├── .github
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── .gitignore
├── CMakeLists.txt
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Fixture.pro
├── LICENSE
├── PULL_REQUEST_TEMPLATE.md
├── README.MD
├── ROADMAP.md
├── resources
├── basic.qss
├── checkers.png
├── icons
│ ├── angle-bottom.svg
│ ├── angle-left.svg
│ ├── angle-right.svg
│ ├── angle-top.svg
│ ├── check-tick.svg
│ ├── close-white-dark.svg
│ ├── close-white-lighter.svg
│ └── close-white.svg
├── layermanager.qss
├── paintwidget.qss
├── resources.qrc
├── tool-menu.qss
└── tools
│ ├── paint.svg
│ ├── pan.svg
│ └── select.svg
├── src
├── dialogs
│ ├── newdialog.cpp
│ ├── newdialog.h
│ └── newdialog.ui
├── layers
│ ├── layer.cpp
│ ├── layer.h
│ ├── rasterlayer.cpp
│ └── rasterlayer.h
├── main.cpp
├── mainwindow.cpp
├── mainwindow.h
├── mainwindow.ui
├── model
│ ├── canvas.cpp
│ ├── canvas.h
│ ├── document.cpp
│ ├── document.h
│ ├── drawing.cpp
│ └── drawing.h
├── tools
│ ├── abstractperception.cpp
│ ├── abstractperception.h
│ ├── abstractselection.cpp
│ ├── abstractselection.h
│ ├── components
│ │ ├── boundingrectitem.cpp
│ │ └── boundingrectitem.h
│ ├── pan.cpp
│ ├── pan.h
│ ├── tool.cpp
│ ├── tool.h
│ ├── tooloptions
│ │ ├── pan_menu.cpp
│ │ ├── pan_menu.h
│ │ ├── pan_menu.ui
│ │ ├── toolmenu.cpp
│ │ ├── toolmenu.h
│ │ ├── transform_menu.cpp
│ │ └── transform_menu.h
│ ├── transform.cpp
│ └── transform.h
└── widgets
│ ├── layermanager.cpp
│ ├── layermanager.h
│ ├── paintwidget.cpp
│ └── paintwidget.h
└── uncrustify.cfg
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 |
5 | ---
6 |
7 | **Describe the bug**
8 | A clear and concise description of what the bug is.
9 |
10 | **To Reproduce**
11 | Steps to reproduce the behavior:
12 | 1. Go to '...'
13 | 2. Click on '....'
14 | 3. Scroll down to '....'
15 | 4. See error
16 |
17 | **Expected behavior**
18 | A clear and concise description of what you expected to happen.
19 |
20 | **Screenshots**
21 | If applicable, add screenshots to help explain your problem.
22 |
23 | **Desktop (please complete the following information):**
24 | - OS: [e.g. Ubuntu]
25 | - Version [e.g. 22]
26 |
27 | **Additional context**
28 | Add any other context about the problem here.
29 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 |
5 | ---
6 |
7 | **Is your feature request related to a problem? Please describe.**
8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
9 |
10 | **Describe the solution you'd like**
11 | A clear and concise description of what you want to happen.
12 |
13 | **Describe alternatives you've considered**
14 | A clear and concise description of any alternative solutions or features you've considered.
15 |
16 | **Additional context**
17 | Add any other context or screenshots about the feature request here.
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | Fixture.pro.user
2 | *~
3 | *#
4 | *.autosave
5 | *.orig
6 | .idea
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0)
2 |
3 | set(VERSION_MAJOR "0")
4 | set(VERSION_MINOR "0")
5 | set(VERSION_PATCH "0")
6 |
7 | project(fixture)
8 |
9 | set( CMAKE_BUILD_TYPE Debug)
10 | set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
11 | set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin )
12 | set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
13 |
14 | if( "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
15 | if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
16 | # using clang
17 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Weverything")
18 | elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
19 | # using gcc
20 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
21 | elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel")
22 | # using intel c compiler
23 | elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
24 | # using visual studio c compiler
25 | endif()
26 | endif()
27 |
28 | find_package(Qt5Widgets REQUIRED)
29 | find_package(Qt5Core REQUIRED)
30 | find_package(Qt5Gui REQUIRED)
31 |
32 | set(CMAKE_INCLUDE_CURRENT_DIR ON)
33 | set(CMAKE_AUTOMOC ON)
34 | set(CMAKE_AUTOUIC ON)
35 | set(CMAKE_AUTORCC ON)
36 |
37 | set(SOURCES
38 | resources/resources.qrc
39 | src/dialogs/newdialog.cpp
40 | src/widgets/paintwidget.cpp
41 | src/main.cpp
42 | src/mainwindow.cpp
43 | src/widgets/layermanager.cpp
44 | src/model/canvas.cpp
45 | src/tools/tool.cpp
46 | src/tools/transform.cpp
47 | src/tools/pan.cpp
48 | src/layers/rasterlayer.cpp
49 | src/layers/layer.cpp
50 | src/model/drawing.cpp
51 | src/tools/abstractselection.cpp
52 | src/tools/abstractperception.cpp
53 | src/tools/components/boundingrectitem.cpp
54 | src/tools/tooloptions/transform_menu.cpp
55 | src/tools/tooloptions/toolmenu.cpp
56 | src/tools/tooloptions/pan_menu.cpp
57 | src/model/document.cpp
58 | src/mainwindow.ui
59 | src/dialogs/newdialog.ui
60 | src/tools/tooloptions/pan_menu.ui
61 | )
62 |
63 | add_executable(fixture ${SOURCES})
64 | target_link_libraries(fixture
65 | Qt5::Widgets
66 | Qt5::Gui
67 | Qt5::Core
68 | )
69 |
70 | install(TARGETS fixture DESTINATION bin)
71 |
72 | set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
73 | set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
74 | set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH})
75 | set(CPACK_PACKAGE_CONTACT "eyeon@disroot.org")
76 | include(CPack)
77 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at eyeon@disroot.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | When contributing to this repository, please first discuss the change you wish to make via issue,
4 | email, Telegram or any other method with the owners of this repository before making a change.
5 |
6 | Please check the [ROADMAP file](https://github.com/eyeon/Fixture/blob/master/README.MD) before raising an issue. There's a chance that the missing feature you
7 | are expecting is already in our TODO list. We will get there soon.
8 |
9 | Please note we have a [code of conduct](https://github.com/eyeon/Fixture/blob/master/CODE_OF_CONDUCT.md), please follow it in all your interactions with the project.
10 |
11 | Join the telegram channel at: https://t.me/eyeon_social if you have any queries, suggestions etc.
12 |
13 | ## General rules
14 |
15 | - Commits must be atomic. They should reflect a set of distinct changes as a single operation that solve one problem at a time.
16 | - Commit messages must be meaningful, clear and concise. Stress on your grammar, it's fine to google the correct way to say something, English isn't everyone's first language.
17 | - Commits should do exactly what their message says. If a commit affects quite a few files, and does a few related things, mention them in the commit description. Refrain from using `git commit -m` in such cases.
18 | - IDE configuration files/temp files are not meant to be a part of the repository and they should remain so.
19 | - Variable names like `a`, `x`, `foo` are unacceptable, use variable names that describes its purpose.
20 | - Format the file with `uncrustify` using the `uncrustify.cfg` provided with the project before submitting any patch.
21 |
22 | ## Pull Request Process
23 |
24 | - Check if there's already a PR assigned to someone that solves a similar problem to yours.
25 | - Ensure that the pull request is being sent from a hotfix/feature branch and not from `master`.
26 | - Check the issue page if the feature you are trying to add/bug you are trying to fix is already in the list. If it does, mention the issue number in parentheses with the pull request.
27 | - Provide a clear, concise description of why this pull request is necessary and what value it adds. Make sure that your PR doesn't contain any more or less than what the PR description says.
28 | - One PR should do only one thing only. No more, no less. If you want to implement two new features, open two PRs.
29 |
--------------------------------------------------------------------------------
/Fixture.pro:
--------------------------------------------------------------------------------
1 | #-------------------------------------------------
2 | #
3 | # Project created by QtCreator 2018-05-07T20:37:49
4 | #
5 | #-------------------------------------------------
6 |
7 | QT += core gui
8 |
9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
10 |
11 | TARGET = Fixture
12 | TEMPLATE = app
13 |
14 | # The following define makes your compiler emit warnings if you use
15 | # any feature of Qt which has been marked as deprecated (the exact warnings
16 | # depend on your compiler). Please consult the documentation of the
17 | # deprecated API in order to know how to port your code away from it.
18 | DEFINES += QT_DEPRECATED_WARNINGS
19 | #CONFIG += sanitizer sanitize_address | We don't need that yet
20 |
21 | # You can also make your code fail to compile if you use deprecated APIs.
22 | # In order to do so, uncomment the following line.
23 | # You can also select to disable deprecated APIs only up to a certain version of Qt.
24 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
25 |
26 |
27 | SOURCES += \
28 | src/dialogs/newdialog.cpp \
29 | src/widgets/paintwidget.cpp \
30 | src/main.cpp \
31 | src/mainwindow.cpp \
32 | src/widgets/layermanager.cpp \
33 | src/model/canvas.cpp \
34 | src/tools/tool.cpp \
35 | src/tools/transform.cpp \
36 | src/tools/pan.cpp \
37 | src/layers/rasterlayer.cpp \
38 | src/layers/layer.cpp \
39 | src/model/drawing.cpp \
40 | src/tools/abstractselection.cpp \
41 | src/tools/abstractperception.cpp \
42 | src/tools/components/boundingrectitem.cpp \
43 | src/tools/tooloptions/transform_menu.cpp \
44 | src/tools/tooloptions/pan_menu.cpp \
45 | src/tools/tooloptions/toolmenu.cpp \
46 | src/model/document.cpp
47 |
48 | HEADERS += \
49 | src/dialogs/newdialog.h \
50 | src/widgets/paintwidget.h \
51 | src/mainwindow.h \
52 | src/widgets/layermanager.h \
53 | src/model/canvas.h \
54 | src/tools/tool.h \
55 | src/tools/transform.h \
56 | src/tools/pan.h \
57 | src/layers/rasterlayer.h \
58 | src/layers/layer.h \
59 | src/model/drawing.h \
60 | src/tools/abstractselection.h \
61 | src/tools/abstractperception.h \
62 | src/tools/tooloptions/transform_menu.h \
63 | src/tools/tooloptions/pan_menu.h \
64 | src/tools/components/boundingrectitem.h \
65 | src/tools/tooloptions/toolmenu.h \
66 | src/model/document.h
67 |
68 | FORMS += \
69 | src/mainwindow.ui \
70 | src/dialogs/newdialog.ui \
71 | src/tools/tooloptions/pan_menu.ui
72 |
73 | RESOURCES += \
74 | resources/resources.qrc
75 |
76 | DISTFILES += \
77 | resources/checkers.png \
78 | resources/icons/angle-bottom.svg \
79 | resources/icons/angle-left.svg \
80 | resources/icons/angle-right.svg \
81 | resources/icons/angle-top.svg \
82 | resources/icons/close-white-dark.svg \
83 | resources/icons/close-white-lighter.svg \
84 | resources/icons/close-white.svg \
85 | resources/tools/select.svg \
86 | resources/tools/pan.svg \
87 | resources/basic.qss \
88 | resources/layermanager.qss \
89 | resources/paintwidget.qss \
90 | uncrustify.cfg
91 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Fixture -- A no bullshit image editor
2 |
3 | Copyright (C) 2018 Dedipyaman Das and Kuntal Majumder
4 |
5 | This software is provided 'as-is', without any express or implied
6 | warranty. In no event will the authors be held liable for any damages
7 | arising from the use of this software.
8 |
9 | Permission is granted to anyone to use this software for any purpose,
10 | including commercial applications, and to alter it and redistribute it
11 | freely, subject to the following restrictions:
12 |
13 | 1. The origin of this software must not be misrepresented; you must not
14 | claim that you wrote the original software. If you use this software
15 | in a product, an acknowledgment in the product documentation is required.
16 | 2. Altered source versions must be plainly marked as such, and must not be
17 | misrepresented as being the original software.
18 | 3. This notice must not be removed or altered from any source distribution.
19 |
--------------------------------------------------------------------------------
/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Description
4 |
5 |
6 | ## Related Issue
7 |
8 |
9 |
10 |
11 |
12 | ## Motivation and Context
13 |
14 |
15 | ## How Has This Been Tested?
16 |
17 |
18 |
19 |
20 | ## Screenshots (if appropriate):
21 |
22 | ## Types of changes
23 |
24 | - [ ] Bug fix (non-breaking change which fixes an issue)
25 | - [ ] New feature (non-breaking change which adds functionality)
26 | - [ ] Breaking change (fix or feature that would cause existing functionality to change)
27 |
28 | ## Checklist:
29 |
30 |
31 | - [ ] My code follows the code style of this project.
32 | - [ ] My change requires a change to the documentation.
33 | - [ ] I have updated the documentation accordingly.
34 | - [ ] I have read the **CONTRIBUTING** document.
35 |
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 | # Fixture
2 | 
3 |
4 | **Fixture** is a no-bullshit, free and open source raster graphics editor.
5 |
6 | ## Motivation
7 |
8 | **Fixture** is an attempt to be a multiplatform, free and open source replacement for Adobe Photoshop. This aims to solve the need for having a proper raster graphics editor with a clean and focused UI, to help graphic artists and regular users morph or create images quickly, even on a Linux distribution.
9 |
10 | **Example window [WIP]**
11 | 
12 |
13 | ## Installation
14 |
15 | Fixture, as of now is a work in progress. The master branch has the latest compilable but not necessary the most stable version. To grab a copy of Fixture, simply clone the repository.
16 |
17 | `git clone https://github.com/eyeon/Fixture.git `
18 |
19 | Install the latest version of Qt Creator from [here](https://www.qt.io/download).
20 | You can then open the `Fixture.pro` file with Qt Creator and compile the program to an executable. You can find more info [here](https://doc.qt.io/qtcreator/creator-building-running.html).
21 |
22 | If you'd like to use `qmake`, make sure you are running it on or above Qt 5.10.
23 |
24 | We also plan to provide `appimages` and builds for Windows & Mac in the future.
25 |
26 | ## Support
27 | If you are having troubles figuring out how to make Fixture work, or have any queries/suggestions, join our telegram group:
28 | https://t.me/eyeon_social. You can mailto:eyeon@disroot.org.
29 |
30 | ## Roadmap
31 |
32 | The [Roadmap file](https://github.com/eyeon/Fixture/blob/master/ROADMAP.md) contains a high level description of our TODO list in terms of feature addition. You can help us extend it by adding features we might have missed.
33 |
34 | ## Contributors
35 |
36 | To contribute to Fixture, fork the repo, create a new branch and send us a pull request. Make sure you read the [CONTRIBUTING.md](https://github.com/eyeon/Fixture/blob/master/CONTRIBUTING.md) before sending us PRs. We welcome all sorts of contribution ranging from documentation to bug fixes. If you can find any bugs or want us to implement a feature, raise an issue. Keep in mind that it is a Work in Progress and what you could be asking for is already in our TODO list.
37 |
38 | ## License
39 |
40 | Fixture is licensed under Eyeon General License which is adapted from [zLib license](https://www.zlib.net/zlib_license.html). Refer to the LICENSE file for more information.
41 |
--------------------------------------------------------------------------------
/ROADMAP.md:
--------------------------------------------------------------------------------
1 | # Fixture Roadmap
2 |
3 | This is the series of phases that we are on track to go about. Work in progress.
4 |
5 | ### TODOs:
6 |
7 | - [X] **Phase 1**
8 |
9 |
10 | - Have a minimal image viewer to open various formats.
11 | - Different Images can be stacked up onto each other and rearranged using Layers window.
12 | - Ability to create custom canvas with predefined sizes like A4, A3, Letter.
13 |
14 |
15 |
16 | - [ ] **Phase 2**
17 |
18 |
19 | - Community contribution support and basic documentation.
20 | - Document saving/loading to files.
21 | - Basic tool option menu to modify tool behavior.
22 |
23 |
24 |
25 |
26 | - [ ] **Phase 3**
27 |
28 |
29 |
30 | - Resizing and cropping options operating globally.
31 | - Adjustments like Brightness, Saturation, Contrast, Color implemented globally.
32 | - Start implementing previously mentioned features layerwise.
33 |
34 |
35 |
36 |
37 | - [ ] **Phase 4**
38 |
39 |
40 |
41 | - Add shape selection tools.
42 | - Add a Lasso tool.
43 | - Implement Phase 2 features with masks created with selection tools.
44 | - Control Alpha with the masks generated by the selection tools.
45 |
46 |
47 |
48 |
49 | - [ ] **Phase 5**
50 |
51 |
52 |
53 | - Add a Text Tool.
54 | - Text Generated with the text tool must be a vector image.
55 | - Implement various typographical features onto the text tool.
56 |
57 |
58 |
59 |
60 | - [ ] **Phase 6**
61 |
62 |
63 |
64 | - Add a Shapes tool for generating common shapes.
65 | - The shapes generated would be vector image.
66 | - Implement color masks.
67 |
--------------------------------------------------------------------------------
/resources/basic.qss:
--------------------------------------------------------------------------------
1 | QMenu::item:selected {
2 | background-color: #0066ff;
3 | }
4 |
5 | QMainWindow {
6 | background-color: #1a1a1a;
7 | }
8 |
9 | #mainToolBar {
10 | background-color: #262626;
11 | }
12 |
13 | #toolMenuBar {
14 | background-color: rgb(75, 75, 75);
15 | border-top : 1px solid #252525;
16 | border-bottom : 1px solid #252525;
17 | }
18 |
19 | QToolButton{
20 | padding: 10;
21 | border: none;
22 | }
23 |
24 | QToolButton:hover{
25 | background-color: #333;
26 | }
27 |
28 | QToolButton:checked{
29 | background-color: #111;
30 | }
31 |
32 | QTabBar {
33 | background-color: #1a1a1a;
34 | border-bottom: 1px solid #262626;
35 | margin: 0px;
36 | }
37 |
38 | QTabBar::tab {
39 | padding: 2px;
40 | min-width: 200px;
41 | max-width: 250px;
42 | height: 15px;
43 | font-size: 12px;
44 | background: #262626;
45 | color: #cccccc;
46 | border: 1px solid #1a1a1a;
47 | }
48 | QTabBar::close-button {
49 | subcontrol-position: right;
50 | }
51 |
52 | QTabBar::tab:hover {
53 | background: #333333
54 | }
55 |
56 | QTabBar::tab:selected {
57 | color: #d9d9d9;
58 | background: #004d99;
59 | }
60 |
61 | QTabBar::close-button {
62 | image: url(:/icons/close-white.svg);
63 | }
64 |
65 | QTabBar::close-button:hover {
66 | image: url(:/icons/close-white-lighter.svg);
67 | }
68 |
69 | QMdiSubWindow QScrollBar:horizontal {
70 | border-top: 1px solid #1a1a1a;
71 | background: #262626;
72 | height: 15px;
73 | margin: 0px 20px 0 20px;
74 | }
75 |
76 | QMdiSubWindow QScrollBar::handle:horizontal {
77 | background: #404040;
78 | min-width: 20px;
79 | border: 1px solid #333333;
80 | }
81 |
82 | QMdiSubWindow QScrollBar::add-line:horizontal {
83 | border: 1px solid #1a1a1a;
84 | background: #1a1a1a;
85 | width: 20px;
86 | subcontrol-position: right;
87 | subcontrol-origin: margin;
88 | }
89 |
90 | QMdiSubWindow QScrollBar::sub-line:horizontal {
91 | border: 1px solid #1a1a1a;
92 | background: #1a1a1a;
93 | width: 20px;
94 | subcontrol-position: left;
95 | subcontrol-origin: margin;
96 | }
97 |
98 | QMdiSubWindow QScrollBar:left-arrow:horizontal {
99 | height: 20px;
100 | width: 20px;
101 | margin-left: 5px;
102 | margin-top: 5px;
103 | image: url(:/icons/angle-left.svg);
104 | }
105 |
106 | QMdiSubWindow QScrollBar:right-arrow:horizontal {
107 | height: 20px;
108 | width: 20px;
109 | margin-left: 5px;
110 | margin-top: 5px;
111 | image: url(:/icons/angle-right.svg);
112 | }
113 | QMdiSubWindow QScrollBar:vertical {
114 | border-left: 1px solid #1a1a1a;
115 | background: #262626;
116 | width: 15px;
117 | margin: 22px 0 22px 0;
118 | }
119 |
120 | QMdiSubWindow QScrollBar::handle:vertical {
121 | background: #404040;
122 | min-height: 20px;
123 | border: 1px solid #333333;
124 | }
125 |
126 | QMdiSubWindow QScrollBar::add-line:vertical {
127 | border: 1px solid #1a1a1a;
128 | background: #1a1a1a;
129 | height: 20px;
130 | subcontrol-position: bottom;
131 | subcontrol-origin: margin;
132 | }
133 |
134 | QMdiSubWindow QScrollBar::sub-line:vertical {
135 | border: 1px solid #1a1a1a;
136 | background: #1a1a1a;
137 | height: 20px;
138 | subcontrol-position: top;
139 | subcontrol-origin: margin;
140 | }
141 |
142 | QMdiSubWindow QScrollBar:up-arrow:vertical {
143 | height: 20px;
144 | width: 20px;
145 | margin-left: 5px;
146 | margin-top: 5px;
147 | image: url(:/icons/angle-top.svg);
148 | }
149 |
150 | QMdiSubWindow QScrollBar:down-arrow:vertical {
151 | height: 20px;
152 | width: 20px;
153 | margin-left: 5px;
154 | margin-top: 5px;
155 | image: url(:/icons/angle-bottom.svg);
156 | }
157 |
158 |
159 |
--------------------------------------------------------------------------------
/resources/checkers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eyeon/Fixture/5b8b7aefa500ff548b2054a714d363016adac46f/resources/checkers.png
--------------------------------------------------------------------------------
/resources/icons/angle-bottom.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/resources/icons/angle-left.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/resources/icons/angle-right.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/resources/icons/angle-top.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/resources/icons/check-tick.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/resources/icons/close-white-dark.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/resources/icons/close-white-lighter.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/resources/icons/close-white.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/resources/layermanager.qss:
--------------------------------------------------------------------------------
1 | QListWidget{
2 | background-color: #262626;
3 | max-width: 300px;
4 | border: 1px solid #1a1a1a;
5 | }
6 |
7 | QListWidget::item{
8 | background-color: #333;
9 | color : #aaa;
10 | border: 1px solid #262626;
11 | }
12 |
13 | QListWidget::item:selected{
14 | background-color: #aaa;
15 | color : #333;
16 | }
17 |
--------------------------------------------------------------------------------
/resources/paintwidget.qss:
--------------------------------------------------------------------------------
1 | PaintWidget {
2 | background-color: #1a1a1a;
3 | }
4 |
--------------------------------------------------------------------------------
/resources/resources.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | checkers.png
4 |
5 |
6 | basic.qss
7 | paintwidget.qss
8 | layermanager.qss
9 | tool-menu.qss
10 |
11 |
12 | icons/close-white-lighter.svg
13 | icons/close-white.svg
14 | icons/close-white-dark.svg
15 | icons/angle-top.svg
16 | icons/angle-right.svg
17 | icons/angle-left.svg
18 | icons/angle-bottom.svg
19 | tools/select.svg
20 | tools/pan.svg
21 | icons/check-tick.svg
22 | tools/paint.svg
23 |
24 |
25 |
--------------------------------------------------------------------------------
/resources/tool-menu.qss:
--------------------------------------------------------------------------------
1 | QFrame {
2 | padding: 7px;
3 | padding-left: 10px;
4 | font-size: 10px;
5 | }
6 |
7 | QCheckBox {
8 | color: #d9d9d9;
9 | font-size: 11px;
10 | }
11 |
12 | QCheckBox:disabled {
13 | color: #aaaaaa;
14 | }
15 |
16 | QCheckBox::indicator {
17 | width: 11px;
18 | height: 11px;
19 | background-color: #262626;
20 | border: 1px solid #1a1a1a;
21 | border-radius: 3px;
22 | }
23 |
24 | QCheckBox::indicator:checked {
25 | image: url(:/icons/check-tick.svg);
26 | }
27 |
28 | QPushButton {
29 | background-color: #262626;
30 | border : none;
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/resources/tools/paint.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
--------------------------------------------------------------------------------
/resources/tools/pan.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
64 |
--------------------------------------------------------------------------------
/resources/tools/select.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
79 |
--------------------------------------------------------------------------------
/src/dialogs/newdialog.cpp:
--------------------------------------------------------------------------------
1 | #include "newdialog.h"
2 | #include "ui_newdialog.h"
3 |
4 | NewDialog::NewDialog(QWidget *parent) :
5 | QDialog(parent), ui(new Ui::NewDialog)
6 | {
7 | ui->setupUi(this);
8 | ui->actionBtnsContainer->setAlignment(Qt::AlignTop);
9 |
10 | initPresetCombo();
11 | initDimensionCombos();
12 | initSignalSlots();
13 | }
14 |
15 | NewDialog::~NewDialog()
16 | {
17 | delete ui;
18 | }
19 |
20 | void NewDialog::initSignalSlots()
21 | {
22 | connect(ui->presetCombo, SIGNAL(currentIndexChanged(int)),
23 | this, SLOT(switchPreset(int)));
24 |
25 | connect(ui->widthUnitCombo, SIGNAL(currentIndexChanged(int)),
26 | ui->heightUnitCombo, SLOT(setCurrentIndex(int)));
27 |
28 | connect(ui->heightUnitCombo, SIGNAL(currentIndexChanged(int)),
29 | ui->widthUnitCombo, SLOT(setCurrentIndex(int)));
30 |
31 | connect(ui->sizeCombo, SIGNAL(currentIndexChanged(QString)),
32 | this, SLOT(displaySize(QString)));
33 |
34 | connect(ui->widthTxt, SIGNAL(textEdited(const QString&)),
35 | this, SLOT(switchToCustomPreset(const QString&)));
36 |
37 | connect(ui->heightTxt, SIGNAL(textEdited(const QString&)),
38 | this, SLOT(switchToCustomPreset(const QString&)));
39 | }
40 |
41 | void NewDialog::switchToCustomPreset(const QString &string)
42 | {
43 | ui->presetCombo->setCurrentIndex(Preset::CUSTOM);
44 | }
45 |
46 | void NewDialog::initPresetCombo()
47 | {
48 | QMap presets = getPresetList();
49 | ui->presetCombo->addItems(QStringList(presets.values()));
50 | ui->presetCombo->setCurrentIndex(Preset::DEFAULT);
51 | }
52 |
53 | void NewDialog::initDimensionCombos()
54 | {
55 | QMap unitMap = getDimensionUnitList();
56 |
57 | ui->widthUnitCombo->addItems(QStringList(unitMap.values()));
58 | ui->widthUnitCombo->setCurrentIndex(Canvas::DimensionUnit::PIXELS);
59 |
60 | ui->heightUnitCombo->addItems(QStringList(unitMap.values()));
61 | ui->heightUnitCombo->setCurrentIndex(Canvas::DimensionUnit::PIXELS);
62 | }
63 |
64 | QMap NewDialog::getDimensionUnitList()
65 | {
66 | QMap units;
67 |
68 | units.insert(Canvas::DimensionUnit::PIXELS, "Pixels");
69 | units.insert(Canvas::DimensionUnit::INCHES, "Inches");
70 | units.insert(Canvas::DimensionUnit::CENTIMETERS, "Centimeters");
71 | units.insert(Canvas::DimensionUnit::MILLIMETERS, "Millimeters");
72 | units.insert(Canvas::DimensionUnit::POINTS, "Points");
73 | units.insert(Canvas::DimensionUnit::PICAS, "Picas");
74 |
75 | return units;
76 | }
77 |
78 | QMap NewDialog::getPresetList()
79 | {
80 | QMap presets;
81 |
82 | presets.insert(Preset::DEFAULT, "Fixture Default");
83 | presets.insert(Preset::INTERNATIONAL, "International");
84 | presets.insert(Preset::US_PAPER, "US Paper");
85 | presets.insert(Preset::CUSTOM, "Custom");
86 |
87 | return presets;
88 | }
89 |
90 | QMap NewDialog::getInternationalList()
91 | {
92 | QMap stdSizes;
93 |
94 | stdSizes.insert("A1", { 23.39, 33.11, Canvas::INCHES });
95 | stdSizes.insert("A2", { 16.54, 23.39, Canvas::INCHES });
96 | stdSizes.insert("A3", { 11.69, 16.54, Canvas::INCHES });
97 | stdSizes.insert("A4", { 8.27, 11.69, Canvas::INCHES });
98 | stdSizes.insert("A5", { 5.83, 8.27, Canvas::INCHES });
99 |
100 | return stdSizes;
101 | }
102 |
103 | QMap NewDialog::getUSPaperList()
104 | {
105 | QMap stdSizes;
106 |
107 | stdSizes.insert("Letter", { 8.5, 11, Canvas::INCHES });
108 | stdSizes.insert("Legal", { 8.5, 14, Canvas::INCHES });
109 | stdSizes.insert("Ledger", { 11, 17, Canvas::INCHES });
110 | stdSizes.insert("Tabloid", { 17, 11, Canvas::INCHES });
111 | stdSizes.insert("Executive", { 7.25, 10.55, Canvas::INCHES });
112 |
113 | return stdSizes;
114 | }
115 |
116 | void NewDialog::switchPreset(int index)
117 | {
118 | ui->sizeCombo->setDisabled(false);
119 |
120 | switch (index) {
121 | case Preset::INTERNATIONAL:
122 | ui->sizeCombo->clear();
123 | _currSize = getInternationalList();
124 | ui->sizeCombo->addItems(QStringList(_currSize.keys()));
125 | break;
126 |
127 | case Preset::US_PAPER:
128 | ui->sizeCombo->clear();
129 | _currSize = getUSPaperList();
130 | ui->sizeCombo->addItems(QStringList(_currSize.keys()));
131 | break;
132 |
133 | case Preset::DEFAULT:
134 | ui->sizeCombo->clear();
135 | ui->sizeCombo->setDisabled(true);
136 | displaySizeContents(NewDialog::Default);
137 | break;
138 |
139 | default:
140 | ui->sizeCombo->setDisabled(true);
141 | }
142 | }
143 |
144 | void NewDialog::displaySize(QString presetKey)
145 | {
146 | PageSize size = _currSize.value(presetKey);
147 | displaySizeContents(size);
148 | }
149 |
150 | void NewDialog::displaySizeContents(NewDialog::PageSize size)
151 | {
152 | ui->widthTxt->setText(QString::number(size.width));
153 | ui->heightTxt->setText(QString::number(size.height));
154 | ui->widthUnitCombo->setCurrentIndex(size.unit);
155 | ui->heightUnitCombo->setCurrentIndex(size.unit);
156 | }
157 |
158 | void NewDialog::on_actionOk_clicked()
159 | {
160 | // Needs a validation layer
161 | try {
162 | _dimensionUnit =
163 | (Canvas::DimensionUnit) ui->widthUnitCombo->currentIndex();
164 | _resolution = (int) getDoubleValue(ui->resTxt);
165 |
166 | ui->heightTxt->setFocus();
167 | int height = getPixelValue(ui->heightTxt);
168 |
169 | ui->widthTxt->setFocus();
170 | int width = getPixelValue(ui->widthTxt);
171 |
172 | QString docName = ui->docNameVal->text();
173 |
174 | QSharedDataPointer