├── Qt-Color-Widgets
├── include
│ └── QtColorWidgets
│ │ ├── ColorDialog
│ │ ├── ColorWheel
│ │ ├── HueSlider
│ │ ├── ColorDelegate
│ │ ├── ColorPreview
│ │ ├── ColorSelector
│ │ ├── ColorListWidget
│ │ ├── GradientEditor
│ │ ├── GradientSlider
│ │ ├── AbstractWidgetList
│ │ ├── BoundColorSelector
│ │ ├── GradientListModel
│ │ ├── HarmonyColorWheel
│ │ ├── colorwidgets_global.hpp
│ │ ├── CMakeLists.txt
│ │ ├── bound_color_selector.hpp
│ │ ├── color_names.hpp
│ │ ├── color_delegate.hpp
│ │ ├── color_utils.hpp
│ │ ├── color_list_widget.hpp
│ │ ├── harmony_color_wheel.hpp
│ │ ├── abstract_widget_list.hpp
│ │ ├── gradient_helper.hpp
│ │ ├── color_line_edit.hpp
│ │ ├── hue_slider.hpp
│ │ ├── color_selector.hpp
│ │ ├── gradient_slider.hpp
│ │ ├── gradient_delegate.hpp
│ │ ├── color_2d_slider.hpp
│ │ ├── color_preview.hpp
│ │ ├── gradient_editor.hpp
│ │ ├── color_palette_model.hpp
│ │ ├── color_dialog.hpp
│ │ ├── gradient_list_model.hpp
│ │ ├── color_wheel.hpp
│ │ ├── swatch.hpp
│ │ ├── color_palette_widget.hpp
│ │ └── color_palette.hpp
├── resources
│ └── QtColorWidgets
│ │ ├── color_widgets.qrc
│ │ ├── alphaback.png
│ │ └── CMakeLists.txt
├── src
│ └── QtColorWidgets
│ │ ├── color_dialog.cpp
│ │ ├── CMakeLists.txt
│ │ ├── bound_color_selector.cpp
│ │ ├── color_utils.cpp
│ │ ├── color_names.cpp
│ │ ├── hue_slider.cpp
│ │ ├── color_list_widget.cpp
│ │ ├── color_delegate.cpp
│ │ ├── color_selector.cpp
│ │ ├── abstract_widget_list.cpp
│ │ ├── color_preview.cpp
│ │ ├── color_line_edit.cpp
│ │ ├── color_palette_widget.ui
│ │ ├── harmony_color_wheel.cpp
│ │ ├── color_2d_slider.cpp
│ │ └── gradient_slider.cpp
└── color_widgets.pri
├── GUI.png
├── data
├── img_s.png
└── palette.obj
├── paletteviewwidget.cpp
├── main.cpp
├── rgbwidget.h
├── opengl3dwidget.h
├── imagewidget.h
├── paletteviewwidget.h
├── mainwindow.h
├── openglwidget.h
├── RgbPalette_Recolor_GUI.sln
├── image2mp4.py
├── README.md
├── opengl3dwidget.cpp
├── imagewidget.cpp
├── RgbPalette_Recolor_GUI.pro
├── data.h
├── my_util.h
├── openglwidget.cpp
├── utility.h
├── rgbwidget.cpp
├── vec3.h
└── utility.cpp
/Qt-Color-Widgets/include/QtColorWidgets/ColorDialog:
--------------------------------------------------------------------------------
1 | #include "color_dialog.hpp"
2 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/ColorWheel:
--------------------------------------------------------------------------------
1 | #include "color_wheel.hpp"
2 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/HueSlider:
--------------------------------------------------------------------------------
1 | #include "hue_slider.hpp"
2 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/ColorDelegate:
--------------------------------------------------------------------------------
1 | #include "color_delegate.hpp"
2 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/ColorPreview:
--------------------------------------------------------------------------------
1 | #include "color_preview.hpp"
2 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/ColorSelector:
--------------------------------------------------------------------------------
1 | #include "color_selector.hpp"
2 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/ColorListWidget:
--------------------------------------------------------------------------------
1 | #include "color_list_widget.hpp"
2 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/GradientEditor:
--------------------------------------------------------------------------------
1 | #include "gradient_editor.hpp"
2 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/GradientSlider:
--------------------------------------------------------------------------------
1 | #include "gradient_slider.hpp"
2 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/AbstractWidgetList:
--------------------------------------------------------------------------------
1 | #include "abstract_widget_list.hpp"
2 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/BoundColorSelector:
--------------------------------------------------------------------------------
1 | #include "bound_color_selector.hpp"
2 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/GradientListModel:
--------------------------------------------------------------------------------
1 | #include "gradient_list_model.hpp"
2 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/HarmonyColorWheel:
--------------------------------------------------------------------------------
1 | #include "harmony_color_wheel.hpp"
2 |
--------------------------------------------------------------------------------
/GUI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zhengjun-Du/Convexhull-based-Image-Recoloring-GUI/HEAD/GUI.png
--------------------------------------------------------------------------------
/data/img_s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zhengjun-Du/Convexhull-based-Image-Recoloring-GUI/HEAD/data/img_s.png
--------------------------------------------------------------------------------
/paletteviewwidget.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zhengjun-Du/Convexhull-based-Image-Recoloring-GUI/HEAD/paletteviewwidget.cpp
--------------------------------------------------------------------------------
/Qt-Color-Widgets/resources/QtColorWidgets/color_widgets.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | alphaback.png
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/src/QtColorWidgets/color_dialog.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zhengjun-Du/Convexhull-based-Image-Recoloring-GUI/HEAD/Qt-Color-Widgets/src/QtColorWidgets/color_dialog.cpp
--------------------------------------------------------------------------------
/Qt-Color-Widgets/resources/QtColorWidgets/alphaback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zhengjun-Du/Convexhull-based-Image-Recoloring-GUI/HEAD/Qt-Color-Widgets/resources/QtColorWidgets/alphaback.png
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "mainwindow.h"
3 | #include "openglwidget.h"
4 | #include
5 |
6 | #include
7 |
8 | #include
9 | using namespace std;
10 |
11 | int main(int argc, char *argv[])
12 | {
13 | QApplication a(argc, argv);
14 | MainWindow w;
15 | w.show();
16 |
17 | return a.exec();
18 | }
19 |
--------------------------------------------------------------------------------
/data/palette.obj:
--------------------------------------------------------------------------------
1 | v 0.19265958366850472 0.2449361096093332 0.6248451143203233
2 | v 0.9261599310002775 0.9749654614172395 1.0
3 | v 0.4414301759963405 0.850881832181207 0.9785412017079019
4 | v 0.0 0.0 0.0
5 | v 1.0 0.19304083417015647 7.081126416897743e-17
6 | v 1.0 0.8922744468227546 6.219342577385976e-17
7 | f 6 5 4
8 | f 2 5 6
9 | f 5 1 4
10 | f 1 5 2
11 | f 3 6 4
12 | f 3 2 6
13 | f 1 3 4
14 | f 3 1 2
15 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/resources/QtColorWidgets/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | set (SOURCES
2 | alphaback.png
3 | color_widgets.qrc
4 | )
5 |
6 | file(RELATIVE_PATH
7 | PREFIX
8 | ${PROJECT_SOURCE_DIR}
9 | ${CMAKE_CURRENT_LIST_DIR})
10 |
11 |
12 | foreach (SOURCE IN LISTS SOURCES)
13 | target_sources (${TARGET_NAME}
14 | PRIVATE
15 | $)
16 | endforeach (SOURCE IN SOURCES)
17 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/colorwidgets_global.hpp:
--------------------------------------------------------------------------------
1 | #ifndef QT_COLOR_WIDGETS_GLOBAL_H
2 | #define QT_COLOR_WIDGETS_GLOBAL_H
3 |
4 | #include
5 |
6 | #if defined(QTCOLORWIDGETS_STATICALLY_LINKED)
7 | # define QCP_EXPORT
8 | #elif defined(QTCOLORWIDGETS_LIBRARY)
9 | # define QCP_EXPORT Q_DECL_EXPORT
10 | #else
11 | //# define QCP_EXPORT Q_DECL_IMPORT
12 | # define QCP_EXPORT
13 | #endif
14 |
15 | #endif // QT_COLOR_WIDGETS_GLOBAL_H
16 |
--------------------------------------------------------------------------------
/rgbwidget.h:
--------------------------------------------------------------------------------
1 | #ifndef RGBWIDGET_H
2 | #define RGBWIDGET_H
3 |
4 | #include
5 | #include"data.h"
6 | #include
7 |
8 | class RGBWidget : public OpenGL3DWidget
9 | {
10 | protected:
11 | void paintGL() Q_DECL_OVERRIDE;
12 | void mouseMoveEvent(QMouseEvent *event) override;
13 |
14 | public:
15 | RGBWidget();
16 |
17 | private:
18 | QSharedMemory sharedMemory;
19 | static double _rotate_x;
20 | static double _rotate_y;
21 | static double _rotate_z;
22 | };
23 |
24 | #endif // RGBWIDGET_H
25 |
--------------------------------------------------------------------------------
/opengl3dwidget.h:
--------------------------------------------------------------------------------
1 | #ifndef OPENGL3DWIDGET_H
2 | #define OPENGL3DWIDGET_H
3 |
4 | #include"openglwidget.h"
5 |
6 | class OpenGL3DWidget : public OpenGLWidget
7 | {
8 | public:
9 | OpenGL3DWidget(QWidget *parent = 0);
10 | protected:
11 | void paintGL() Q_DECL_OVERRIDE;
12 | void mousePressEvent(QMouseEvent *event) override;
13 | void mouseMoveEvent(QMouseEvent *event) override;
14 | protected:
15 | double rotate_x;
16 | double rotate_y;
17 | double rotate_z;
18 | private:
19 | QPoint lastPos;
20 | };
21 |
22 | #endif // OPENGL3DWIDGET_H
23 |
--------------------------------------------------------------------------------
/imagewidget.h:
--------------------------------------------------------------------------------
1 | #ifndef ImageWidget_H
2 | #define ImageWidget_H
3 |
4 | #include
5 | #include
6 | #include "data.h"
7 |
8 | class ImageWidget : public QWidget
9 | {
10 | Q_OBJECT
11 | public:
12 | explicit ImageWidget(bool _isAfter, QWidget *parent = nullptr);
13 |
14 | void setData(Data *value);
15 |
16 | protected:
17 | virtual void paintEvent(QPaintEvent *event);
18 | signals:
19 |
20 | public slots:
21 | void setTime(int t);
22 | void update();
23 |
24 | protected:
25 | Data *data = nullptr;
26 | int time = 0;
27 |
28 | private:
29 | bool isAfter;
30 | };
31 |
32 | #endif // ImageWidget_H
33 |
--------------------------------------------------------------------------------
/paletteviewwidget.h:
--------------------------------------------------------------------------------
1 | #ifndef PALETTEVIEWWIDGET_H
2 | #define PALETTEVIEWWIDGET_H
3 |
4 | #include
5 | #include
6 |
7 | class PaletteViewWidget : public OpenGLWidget
8 | {
9 | Q_OBJECT
10 | public:
11 | explicit PaletteViewWidget(QWidget *parent = 0);
12 |
13 | protected:
14 | void paintGL() Q_DECL_OVERRIDE;
15 | void mousePressEvent(QMouseEvent *event) override;
16 |
17 | public Q_SLOTS:
18 | void getColor(QColor c);
19 | void setTime(int t_);
20 |
21 | void resetPaletteColor();
22 | void resetAllPaletteColors();
23 |
24 | Q_SIGNALS:
25 | void setColor(QColor c);
26 |
27 | private:
28 | bool blink = false;
29 | double scale = 1.95;
30 | int selected_vid = -1;
31 | double aspect = 1.0;
32 | int time = 0;
33 |
34 | vector palette_pos;
35 | QMenu *pMenu;
36 | };
37 |
38 | #endif // PALETTEVIEWWIDGET_H
39 |
--------------------------------------------------------------------------------
/mainwindow.h:
--------------------------------------------------------------------------------
1 | #ifndef MAINWINDOW_H
2 | #define MAINWINDOW_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | class MainWindow : public QMainWindow
9 | {
10 | Q_OBJECT
11 |
12 | public:
13 | explicit MainWindow(QWidget *parent = nullptr);
14 | ~MainWindow();
15 |
16 | private:
17 | QDockWidget *imageBeforeDockWidget = nullptr;
18 | QDockWidget *imageAfterDockWidget = nullptr;
19 | void exportImage();
20 | void importPalette();
21 | void exportPalette();
22 |
23 |
24 | void openFile(bool merge);
25 | Data *data = nullptr;
26 | QSlider *slider = nullptr;
27 | QSlider *mergeStepSlider = nullptr;
28 |
29 | // QString title = "Video Recoloring Tool (Build " __DATE__ " " __TIME__ ")";
30 | QString title = "Image Recoloring Tool";
31 |
32 | bool isPlaying = false;
33 | };
34 |
35 | #endif // MAINWINDOW_H
36 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/src/QtColorWidgets/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | set (SOURCES
2 | abstract_widget_list.cpp
3 | bound_color_selector.cpp
4 | color_2d_slider.cpp
5 | color_delegate.cpp
6 | color_dialog.cpp
7 | color_dialog.ui
8 | color_line_edit.cpp
9 | color_list_widget.cpp
10 | color_names.cpp
11 | color_palette.cpp
12 | color_palette_model.cpp
13 | color_palette_widget.cpp
14 | color_palette_widget.ui
15 | color_preview.cpp
16 | color_selector.cpp
17 | color_utils.cpp
18 | color_wheel.cpp
19 | gradient_slider.cpp
20 | hue_slider.cpp
21 | swatch.cpp
22 | gradient_editor.cpp
23 | harmony_color_wheel.cpp
24 | gradient_list_model.cpp
25 | )
26 |
27 | file(RELATIVE_PATH
28 | PREFIX
29 | ${PROJECT_SOURCE_DIR}
30 | ${CMAKE_CURRENT_LIST_DIR})
31 |
32 |
33 | foreach (SOURCE IN LISTS SOURCES)
34 | target_sources (${TARGET_NAME}
35 | PRIVATE
36 | $)
37 | endforeach (SOURCE IN SOURCES)
38 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | set (HEADERS
2 | abstract_widget_list.hpp
3 | bound_color_selector.hpp
4 | color_2d_slider.hpp
5 | color_delegate.hpp
6 | color_dialog.hpp
7 | color_line_edit.hpp
8 | color_list_widget.hpp
9 | color_names.hpp
10 | color_palette.hpp
11 | color_palette_model.hpp
12 | color_palette_widget.hpp
13 | color_preview.hpp
14 | color_selector.hpp
15 | color_wheel.hpp
16 | colorwidgets_global.hpp
17 | gradient_slider.hpp
18 | hue_slider.hpp
19 | swatch.hpp
20 | gradient_editor.hpp
21 | harmony_color_wheel.hpp
22 | gradient_list_model.hpp
23 | gradient_delegate.hpp
24 | )
25 |
26 | file(RELATIVE_PATH
27 | PREFIX
28 | ${PROJECT_SOURCE_DIR}
29 | ${CMAKE_CURRENT_LIST_DIR})
30 |
31 |
32 | foreach (HEADER IN LISTS HEADERS)
33 | target_sources (${TARGET_NAME}
34 | PRIVATE
35 | $
36 | $)
37 | endforeach (HEADER IN HEADERS)
38 |
--------------------------------------------------------------------------------
/openglwidget.h:
--------------------------------------------------------------------------------
1 | #ifndef OPENGLWIDGET_H
2 | #define OPENGLWIDGET_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #include
9 | #include
10 |
11 | #include
12 |
13 | #include"data.h"
14 |
15 | class OpenGLWidget:public QOpenGLWidget, protected QOpenGLFunctions
16 | {
17 | public:
18 | explicit OpenGLWidget(QWidget *parent = 0);
19 |
20 | void setData(Data *value);
21 |
22 | public slots:
23 | void update();
24 | void setTime(int t);
25 | void setShowImageData(bool _showImageData);
26 | void setPreview(int percentage);
27 |
28 | protected:
29 | void initializeGL() Q_DECL_OVERRIDE;
30 | void resizeGL(int w, int h) Q_DECL_OVERRIDE;
31 | void paintGL() Q_DECL_OVERRIDE;
32 |
33 | private:
34 |
35 | protected:
36 | Data *data = nullptr;
37 |
38 | int time = 0;
39 |
40 | bool showImageData = true;
41 | double preview =.25;
42 |
43 | };
44 |
45 | #endif // OPENGLWIDGET_H
46 |
--------------------------------------------------------------------------------
/RgbPalette_Recolor_GUI.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RgbPalette_Recolor_GUI", "RgbPalette_Recolor_GUI.vcxproj", "{8C6E3580-7B5B-3679-990B-F6EAE4EE2555}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Release|x64 = Release|x64
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {8C6E3580-7B5B-3679-990B-F6EAE4EE2555}.Debug|x64.ActiveCfg = Debug|x64
15 | {8C6E3580-7B5B-3679-990B-F6EAE4EE2555}.Debug|x64.Build.0 = Debug|x64
16 | {8C6E3580-7B5B-3679-990B-F6EAE4EE2555}.Release|x64.ActiveCfg = Release|x64
17 | {8C6E3580-7B5B-3679-990B-F6EAE4EE2555}.Release|x64.Build.0 = Release|x64
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/image2mp4.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | from cv2 import VideoWriter, VideoWriter_fourcc, imread, resize
3 | import os
4 | from PIL import Image
5 | import sys
6 |
7 |
8 | def Pic2Video(imgPath,videoPath ):
9 | images = os.listdir(imgPath)
10 | fps = 15 # 每秒15帧数
11 |
12 | # VideoWriter_fourcc为视频编解码器 ('I', '4', '2', '0') —>(.avi) 、('P', 'I', 'M', 'I')—>(.avi)、('X', 'V', 'I', 'D')—>(.avi)、('T', 'H', 'E', 'O')—>.ogv、('F', 'L', 'V', '1')—>.flv、('m', 'p', '4', 'v')—>.mp4
13 | fourcc = VideoWriter_fourcc('m', 'p', '4', 'v')
14 |
15 | image = Image.open(imgPath + "/" + images[0])
16 | videoWriter = cv2.VideoWriter(videoPath + "/recolored.mp4", fourcc, fps, image.size)
17 |
18 |
19 | for i in range(len(images)):
20 |
21 | frame = cv2.imread(imgPath + "/" + str(i) + ".png") # 这里的路径只能是英文路径
22 | print(imgPath + "/" + str(i) + ".png")
23 | videoWriter.write(frame)
24 | print("图片转视频结束!")
25 | videoWriter.release()
26 | cv2.destroyAllWindows()
27 |
28 | if __name__ == '__main__':
29 | imgPath = sys.argv[1]
30 | videoPath = sys.argv[2]
31 | Pic2Video(imgPath,videoPath)
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Convexhull-based-Image-Recoloring-GUI
2 | A GUI written by Qt for convex hull palette based image recoloring
3 |
4 | 
5 |
6 | ### Compile platform
7 | Windows 10 + Qt 5.14.1 + Visual Studio 2015
8 |
9 | ### Feature
10 | **Open Image and Palette**: test the GUI use image and palette in the 'data' directory
11 | **MVC minxing weights:** click the "Calc MVC" button to calculate the mixing weights
12 | **RGB view**: see the point cloud of the image and its convex hull
13 | **Export Image**: export recolored image
14 | **Import/Export Palette**: save the modified palette colors
15 |
16 | ### Reference Paper
17 | 1. Tan J, Lien J M, Gingold Y. Decomposing images into layers via RGB-space geometry[J]. ACM Transactions on Graphics (TOG), 2016, 36(1): 1-14.
18 |
19 | 2. Tan J, Echevarria J, Gingold Y. Efficient palette-based decomposition and recoloring of images via RGBXY-space geometry[J]. ACM Transactions on Graphics (TOG), 2018, 37(6): 1-10.
20 |
21 | 3. Wang Y, Liu Y, Xu K. An Improved Geometric Approach for Palette‐based Image Decomposition and Recoloring[C]//Computer Graphics Forum. 2019, 38(7): 11-22.
22 |
23 | Any question, please feel free to contact me: duzqhu@aliyun.com
24 |
25 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/src/QtColorWidgets/bound_color_selector.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #include "QtColorWidgets/bound_color_selector.hpp"
23 |
24 | namespace color_widgets {
25 |
26 | BoundColorSelector::BoundColorSelector(QColor* reference, QWidget *parent) :
27 | ColorSelector(parent), ref(reference)
28 | {
29 | setColor(*reference);
30 | connect(this,&ColorPreview::colorChanged,this, &BoundColorSelector::update_reference);
31 | }
32 |
33 | void BoundColorSelector::update_reference(QColor c)
34 | {
35 | *ref = c;
36 | }
37 |
38 | } // namespace color_widgets
39 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/bound_color_selector.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef BOUND_COLOR_SELECTOR_HPP
23 | #define BOUND_COLOR_SELECTOR_HPP
24 |
25 | #include "color_selector.hpp"
26 |
27 | namespace color_widgets {
28 | /**
29 | * \brief A color selector bound to a color reference
30 | * \todo Maybe this can be removed
31 | */
32 | class QCP_EXPORT BoundColorSelector : public ColorSelector
33 | {
34 | Q_OBJECT
35 | private:
36 | QColor* ref;
37 | public:
38 | explicit BoundColorSelector(QColor* reference, QWidget *parent = 0);
39 |
40 | private Q_SLOTS:
41 | void update_reference(QColor);
42 | };
43 | } // namespace color_widgets
44 | #endif // BOUND_COLOR_SELECTOR_HPP
45 |
--------------------------------------------------------------------------------
/opengl3dwidget.cpp:
--------------------------------------------------------------------------------
1 | #include "opengl3dwidget.h"
2 | #include
3 | #include
4 |
5 | // basic OpenGL 3D Widget
6 |
7 | OpenGL3DWidget::OpenGL3DWidget(QWidget *parent) : OpenGLWidget(parent), rotate_x(-15), rotate_y(-70), rotate_z(0), lastPos(0, 0)
8 | {
9 | lastPos.setX(0);
10 | lastPos.setY(0);
11 | }
12 |
13 | void OpenGL3DWidget::paintGL()
14 | {
15 | OpenGLWidget::paintGL();
16 |
17 | // Otras transformaciones
18 | // glTranslatef( 0.1, 0.0, 0.0 ); // No incluido
19 | // glRotatef( 180, 0.0, 1.0, 0.0 ); // No incluido
20 |
21 | // Rotar cuando el usuario cambie “rotate_x” y “rotate_y”
22 | glRotatef( rotate_x, 1.0, 0.0, 0.0 );
23 | glRotatef( rotate_y, 0.0, 1.0, 0.0 );
24 | glRotatef( rotate_z, 0.0, 0.0, 1.0 );
25 | glScalef( 1.2, 1.2, -1.2 );
26 |
27 | }
28 |
29 | void OpenGL3DWidget::mousePressEvent(QMouseEvent *event)
30 | {
31 | lastPos = event->pos();
32 | }
33 |
34 | void OpenGL3DWidget::mouseMoveEvent(QMouseEvent *event)
35 | {
36 | QOpenGLWidget::mouseMoveEvent(event);
37 |
38 | if (event->buttons() & Qt::LeftButton)
39 | {
40 | int dx = event->x() - lastPos.x();
41 | int dy = event->y() - lastPos.y();
42 |
43 | // qDebug() << rotate_x << rotate_y << event->x() << event->y() << lastPos.x() << lastPos.y();
44 |
45 | lastPos = event->pos();
46 | rotate_x -= dy;
47 | rotate_y -= dx;
48 | qDebug() << "mouseMoveEvent" << rotate_x << rotate_y;
49 |
50 | update();
51 | }
52 | }
53 |
54 |
55 |
--------------------------------------------------------------------------------
/imagewidget.cpp:
--------------------------------------------------------------------------------
1 | #include "imagewidget.h"
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 |
8 | ImageWidget::ImageWidget(bool _isAfter, QWidget *parent) : QWidget(parent), isAfter(_isAfter)
9 | {
10 | }
11 |
12 | void ImageWidget::paintEvent(QPaintEvent *event)
13 | {
14 | QWidget::paintEvent(event);
15 |
16 | if (data == nullptr) return;
17 |
18 | int width = data->GetFrameWidth();
19 | int height = data->GetFrameHeight();
20 | int depth = data->GetFrameDepth();
21 | double *video = data->GetImage(isAfter);
22 |
23 | QPainter painter(this);
24 |
25 | uchar *data = new uchar[width * height * depth];
26 |
27 | for (int i = 0; i < width * height * depth; i++)
28 | {
29 | int x = static_cast(video[i] * 255);
30 | if (x > 255) x = 255;
31 | if (x < 0) x = 0;
32 |
33 | data[i] = static_cast(x);
34 | }
35 |
36 | cout << endl;
37 | for (int i = 0; i < 3; i++)
38 | cout << (int)data[i * 3] << "," << (int)data[i * 3 + 1] << "," << (int)data[i * 3 + 2] << endl;
39 |
40 | QImage im(data, width, height, width*3, QImage::Format_RGB888);
41 |
42 | cout << im.height() << "," << im.width() << "," << im.depth() << endl;
43 |
44 |
45 | painter.setPen(QPen(Qt::red, 3));
46 |
47 | painter.drawImage(QRectF(0, 0, width, height), im);
48 |
49 | //painter.drawRect(0, 0, width, height);
50 |
51 | painter.end();
52 | delete[] data;
53 | }
54 |
55 | void ImageWidget::setTime(int t)
56 | {
57 | time = t;
58 |
59 | update();
60 | }
61 |
62 | void ImageWidget::update()
63 | {
64 | QWidget::update();
65 |
66 | int w = data->GetFrameWidth();
67 | int h = data->GetFrameHeight();
68 |
69 | setMaximumSize(w, h);
70 | setMinimumSize(w, h);
71 | }
72 |
73 | void ImageWidget::setData(Data *value)
74 | {
75 | data = value;
76 | connect(value, &Data::updated, this, &ImageWidget::update);
77 | }
78 |
--------------------------------------------------------------------------------
/RgbPalette_Recolor_GUI.pro:
--------------------------------------------------------------------------------
1 | #-------------------------------------------------
2 | #
3 | # Project created by QtCreator 2020-04-06T14:49:16
4 | #
5 | #-------------------------------------------------
6 |
7 | QT += core gui widgets datavisualization opengl
8 | LIBS += -lopengl32 -lglu32 -openmp
9 | QMAKE_CXXFLAGS += -openmp
10 |
11 | #note: linux -fopenmp
12 |
13 |
14 | TARGET = Recolor_GUI
15 | TEMPLATE = app
16 |
17 | # The following define makes your compiler emit warnings if you use
18 | # any feature of Qt which has been marked as deprecated (the exact warnings
19 | # depend on your compiler). Please consult the documentation of the
20 | # deprecated API in order to know how to port your code away from it.
21 | DEFINES += QT_DEPRECATED_WARNINGS
22 |
23 | # You can also make your code fail to compile if you use deprecated APIs.
24 | # In order to do so, uncomment the following line.
25 | # You can also select to disable deprecated APIs only up to a certain version of Qt.
26 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
27 |
28 |
29 |
30 | CONFIG += c++11
31 |
32 | SOURCES += \
33 | data.cpp \
34 | main.cpp \
35 | mainwindow.cpp \
36 | opengl3dwidget.cpp \
37 | openglwidget.cpp \
38 | paletteviewwidget.cpp \
39 | rgbwidget.cpp \
40 | utility.cpp \
41 | videowidget.cpp
42 |
43 | HEADERS += \
44 | data.h \
45 | mainwindow.h \
46 | opengl3dwidget.h \
47 | openglwidget.h \
48 | paletteviewwidget.h \
49 | rgbwidget.h \
50 | utility.h \
51 | videowidget.h
52 |
53 |
54 | DEFINES += QUAZIP_BUILD
55 |
56 | #INCLUDEPATH += $$PWDQt-Color-Widgets
57 | include(Qt-Color-Widgets/color_widgets.pri)
58 |
59 | FORMS +=
60 |
61 | # Default rules for deployment.
62 | qnx: target.path = /tmp/$${TARGET}/bin
63 | else: unix:!android: target.path = /opt/$${TARGET}/bin
64 | !isEmpty(target.path): INSTALLS += target
65 |
--------------------------------------------------------------------------------
/data.h:
--------------------------------------------------------------------------------
1 | #ifndef DATA_H
2 | #define DATA_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include"utility.h"
9 | #include "vec3.h"
10 | #include
11 | using namespace std;
12 |
13 | class Data : public QObject
14 | {
15 | Q_OBJECT
16 |
17 | public:
18 | Data();
19 | void OpenImage(QString fileName);
20 | void OpenPalette(string fileName);
21 | void reset();
22 |
23 | double *GetImage(bool isAfter = true) const { return isAfter ? recolored_image : original_image; }
24 | Polyhedron GetChangedPalette() { return changed_palette; }
25 | Polyhedron GetOriginalPalette() { return original_palette; }
26 | Polyhedron GetPalette() { return is_mvc_calculated ? changed_palette : original_palette; }
27 |
28 | vector ComputeSingleVertexMVCWeights(int vid, const vec3 &x);
29 | vector ComputeSingleVertexMVCWeightsForceInside(int vid, const vec3 &x);
30 | const void ComputeMVCWeights();
31 |
32 | vec3 RecolorSinglePixel(int vid, const vec3 &x);
33 | void Recolor();
34 |
35 | int GetFrameWidth() const { return image_width; }
36 | int GetFrameHeight() const{ return image_height; }
37 | int GetFrameDepth() const{ return image_depth; }
38 |
39 | void setPaletteColor(int id, QColor c);
40 | void resetPaletteColor(int id);
41 | void resetAllPaletteColors();
42 |
43 | void ExportOriginalVideo(string path);
44 | void ExportRecoloredImage(string path);
45 | void ExportChangedPalette(string path);
46 | void ImportChangedPalette(string path);
47 |
48 | public slots:
49 | signals:
50 | void updated();
51 |
52 | private:
53 | double* recolored_image = nullptr;
54 | double* original_image = nullptr;
55 |
56 | Polyhedron changed_palette;
57 | Polyhedron original_palette;
58 |
59 | vector > mvc_weights;
60 | bool is_mvc_calculated;
61 |
62 | int image_width = 0;
63 | int image_height = 0;
64 | int image_depth = 0;
65 | };
66 |
67 | #endif // DATA_H
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/color_names.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef COLOR_WIDGETS_COLOR_NAMES_HPP
23 | #define COLOR_WIDGETS_COLOR_NAMES_HPP
24 |
25 | #include
26 | #include
27 |
28 | #include
29 |
30 | namespace color_widgets {
31 |
32 | /**
33 | * \brief Convert a string into a color
34 | *
35 | * Supported string formats:
36 | * * Short hex strings #f00
37 | * * Long hex strings #ff0000
38 | * * Color names red
39 | * * Function-like rgb(255,0,0)
40 | *
41 | * Additional string formats supported only when \p alpha is true:
42 | * * Long hex strings #ff0000ff
43 | * * Function like rgba(255,0,0,255)
44 | */
45 | QCP_EXPORT QColor colorFromString(const QString& string, bool alpha = true);
46 |
47 | /**
48 | * \brief Convert a color into a string
49 | *
50 | * Format:
51 | * * If the color has full alpha: #ff0000
52 | * * If alpha is true and the color has non-full alpha: #ff000088
53 | */
54 | QCP_EXPORT QString stringFromColor(const QColor& color, bool alpha = true);
55 |
56 | } // namespace color_widgets
57 | #endif // COLOR_WIDGETS_COLOR_NAMES_HPP
58 |
--------------------------------------------------------------------------------
/my_util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | template std::ostream& operator<< (std::ostream& os, const std::vector& vec) {
8 | os << "[";
9 | for (int i = 0; i < (int)vec.size(); i++)
10 | {
11 | if (i != 0)
12 | os << ",";
13 | os << vec[i];
14 | }
15 | os << "]";
16 | return os;
17 | }
18 |
19 | template T fromString(const std::string& str) {
20 | T t;
21 | std::stringstream ss(str);
22 | ss >> t;
23 | return t;
24 | }
25 |
26 | namespace my_util {
27 |
28 | template T clamp(const T&val, const T&val_min, const T&val_max)
29 | {
30 | T tmp = std::min(val, val_max);
31 | tmp = std::max(val, val_min);
32 | return tmp;
33 | }
34 |
35 | /*
36 | e.g.:
37 | directory: "." => "./",
38 | directory: "./" => "./"
39 | */
40 | inline std::string addSlashToEnd(const std::string& directory) {
41 | if (directory.length() == 0)
42 | return directory;
43 | int last_pos = directory.length() - 1;
44 | if (directory[last_pos] == '\\' || directory[last_pos] == '/')
45 | return directory;
46 | else if (directory.find('\\') != -1)
47 | return directory + "\\";
48 | else
49 | return directory + "/";
50 | }
51 |
52 |
53 | /*
54 | e.g: fullpath: "D:\\test\\aaa.png" => "aaa.png",
55 | */
56 | inline std::string getFilenameWithExt(const std::string& fullpath) {
57 | int pos2 = fullpath.find_last_of('\\');
58 | int pos3 = fullpath.find_last_of('/');
59 | int pos4 = std::max(pos2, pos3);
60 | if (pos4 == -1) {
61 | return fullpath;
62 | }
63 | else {
64 | return fullpath.substr(pos4 + 1);
65 | }
66 | }
67 |
68 | /*
69 | e.g: fullpath: "D:\\test\\aaa.png" => "aaa",
70 | */
71 | inline std::string getFilename(const std::string& fullpath) {
72 | std::string filename;
73 |
74 | std::string fnWithExt = getFilenameWithExt(fullpath);
75 |
76 | //remove extension
77 | int pos = fnWithExt.find_last_of('.');
78 | if (pos == -1) {
79 | filename = fnWithExt;
80 | }
81 | else {
82 | filename = fnWithExt.substr(0, pos);
83 | }
84 |
85 | return filename;
86 | }
87 | }
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/color_delegate.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef COLOR_DELEGATE_HPP
23 | #define COLOR_DELEGATE_HPP
24 |
25 | #include "colorwidgets_global.hpp"
26 |
27 | #include
28 |
29 | namespace color_widgets {
30 |
31 | /**
32 | Delegate to use a ColorSelector in a color list
33 | */
34 | class QCP_EXPORT ColorDelegate : public QStyledItemDelegate
35 | {
36 | Q_OBJECT
37 | public:
38 | explicit ColorDelegate(QWidget *parent = 0);
39 |
40 | void paint(QPainter *painter, const QStyleOptionViewItem &option,
41 | const QModelIndex &index) const Q_DECL_OVERRIDE;
42 |
43 | QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
44 | const QModelIndex &index) const Q_DECL_OVERRIDE;
45 |
46 | void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE;
47 |
48 | void setModelData(QWidget *editor, QAbstractItemModel *model,
49 | const QModelIndex &index) const Q_DECL_OVERRIDE;
50 |
51 | QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
52 |
53 | void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
54 | const QModelIndex &index) const Q_DECL_OVERRIDE;
55 |
56 |
57 | private slots:
58 | void close_editor();
59 | void color_changed();
60 | };
61 |
62 | } // namespace color_widgets
63 |
64 | #endif // COLOR_DELEGATE_HPP
65 |
--------------------------------------------------------------------------------
/openglwidget.cpp:
--------------------------------------------------------------------------------
1 | #include "openglwidget.h"
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | // basic OpenGL 2D widget
8 |
9 | OpenGLWidget::OpenGLWidget(QWidget *parent) : QOpenGLWidget(parent)
10 | {
11 | }
12 |
13 | void OpenGLWidget::initializeGL()
14 | {
15 | initializeOpenGLFunctions();
16 | // glEnable(GL_DEPTH_TEST);
17 | glEnable(GL_POINT_SMOOTH);
18 | glEnable(GL_LINE_SMOOTH);
19 | glEnable(GL_BLEND);
20 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
21 |
22 | glEnable(GL_BLEND); //Enable blending.
23 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //Set blending function.
24 |
25 | glEnable(GL_DEPTH_TEST);
26 | glDepthFunc(GL_LESS);
27 |
28 | glClearDepth(1.0f);
29 | // Borrar pantalla y Z-buffer
30 | glClearColor(.5f, .5f, .5f, 0.0f);
31 | }
32 |
33 | void OpenGLWidget::resizeGL(int w, int h)
34 | {
35 | qDebug() << "resizeGL" << w << h;
36 | int m = w < h ? w : h;
37 | glViewport(0, 0, m, m);
38 | update();
39 | }
40 |
41 | void OpenGLWidget::paintGL()
42 | {
43 | QOpenGLWidget::paintGL();
44 |
45 |
46 | glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
47 |
48 | glShadeModel(GL_SMOOTH);
49 | // Resetear transformaciones
50 | glLoadIdentity();
51 |
52 | }
53 |
54 | void OpenGLWidget::setData(Data *value)
55 | {
56 | data = value;
57 | connect(value, &Data::updated, this, &OpenGLWidget::update);
58 | }
59 |
60 | void OpenGLWidget::update()
61 | {
62 | QOpenGLWidget::update();
63 | }
64 |
65 | void OpenGLWidget::setTime(int t)
66 | {
67 | // qDebug() << t;
68 |
69 | time = t;
70 | update();
71 | }
72 |
73 | void OpenGLWidget::setShowImageData(bool _showImageData)
74 | {
75 | showImageData = _showImageData;
76 | update();
77 | }
78 |
79 | void OpenGLWidget::setPreview(int percentage)
80 | {
81 | preview = percentage / 1000.;
82 | update();
83 | }
84 |
85 | /*
86 | void OpenGLWidget::graficarLineas()
87 | {
88 | glBegin(GL_LINES);
89 | glColor3f(1,0,0);
90 | glVertex3f(0,0,0);
91 | glVertex3f(20,0,0);
92 |
93 | glColor3f(1,1,0);
94 | glVertex3f(0,0,0);
95 | glVertex3f(0,20,0);
96 |
97 | glColor3f(0,1,1);
98 | glVertex3f(0,0,0);
99 | glVertex3f(0,0,20);
100 | glEnd();
101 | }
102 | */
103 |
104 |
105 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/color_utils.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef COLOR_UTILS_HPP
23 | #define COLOR_UTILS_HPP
24 |
25 | #include
26 | #include
27 |
28 | #include "QtColorWidgets/colorwidgets_global.hpp"
29 |
30 | namespace color_widgets {
31 | namespace detail {
32 |
33 |
34 | inline qreal color_chromaF(const QColor& c)
35 | {
36 | qreal max = qMax(c.redF(), qMax(c.greenF(), c.blueF()));
37 | qreal min = qMin(c.redF(), qMin(c.greenF(), c.blueF()));
38 | return max - min;
39 | }
40 |
41 | inline qreal color_lumaF(const QColor& c)
42 | {
43 | return 0.30 * c.redF() + 0.59 * c.greenF() + 0.11 * c.blueF();
44 | }
45 | QColor color_from_lch(qreal hue, qreal chroma, qreal luma, qreal alpha = 1 );
46 |
47 | inline QColor rainbow_lch(qreal hue)
48 | {
49 | return color_from_lch(hue,1,1);
50 | }
51 |
52 | inline QColor rainbow_hsv(qreal hue)
53 | {
54 | return QColor::fromHsvF(hue,1,1);
55 | }
56 |
57 | inline qreal color_lightnessF(const QColor& c)
58 | {
59 | return ( qMax(c.redF(),qMax(c.greenF(),c.blueF())) +
60 | qMin(c.redF(),qMin(c.greenF(),c.blueF())) ) / 2;
61 | }
62 |
63 | inline qreal color_HSL_saturationF(const QColor& col)
64 | {
65 | qreal c = color_chromaF(col);
66 | qreal l = color_lightnessF(col);
67 | if ( qFuzzyCompare(l+1,1) || qFuzzyCompare(l+1,2) )
68 | return 0;
69 | return c / (1-qAbs(2*l-1));
70 | }
71 |
72 | QCP_EXPORT QColor color_from_hsl(qreal hue, qreal sat, qreal lig, qreal alpha = 1 );
73 |
74 | } // namespace detail
75 | } // namespace color_widgets
76 |
77 | #endif // COLOR_UTILS_HPP
78 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/color_list_widget.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef COLOR_LIST_WIDGET_HPP
23 | #define COLOR_LIST_WIDGET_HPP
24 |
25 | #include "abstract_widget_list.hpp"
26 | #include "color_wheel.hpp"
27 |
28 | namespace color_widgets {
29 |
30 | class QCP_EXPORT ColorListWidget : public AbstractWidgetList
31 | {
32 | Q_OBJECT
33 |
34 | Q_PROPERTY(QList colors READ colors WRITE setColors NOTIFY colorsChanged )
35 | Q_PROPERTY(ColorWheel::ShapeEnum wheelShape READ wheelShape WRITE setWheelShape NOTIFY wheelShapeChanged)
36 | Q_PROPERTY(ColorWheel::ColorSpaceEnum colorSpace READ colorSpace WRITE setColorSpace NOTIFY colorSpaceChanged)
37 | Q_PROPERTY(bool wheelRotating READ wheelRotating WRITE setWheelRotating NOTIFY wheelRotatingChanged)
38 |
39 | public:
40 | explicit ColorListWidget(QWidget *parent = 0);
41 | ~ColorListWidget();
42 |
43 | QList colors() const;
44 | void setColors(const QList& colors);
45 |
46 | void swap(int a, int b);
47 |
48 | void append();
49 |
50 | ColorWheel::ShapeEnum wheelShape() const;
51 | ColorWheel::ColorSpaceEnum colorSpace() const;
52 | bool wheelRotating() const;
53 |
54 | Q_SIGNALS:
55 | void colorsChanged(const QList&);
56 | void wheelShapeChanged(ColorWheel::ShapeEnum shape);
57 | void colorSpaceChanged(ColorWheel::ColorSpaceEnum space);
58 | void wheelRotatingChanged(bool rotating);
59 |
60 | public Q_SLOTS:
61 | void setWheelShape(ColorWheel::ShapeEnum shape);
62 | void setColorSpace(ColorWheel::ColorSpaceEnum space);
63 | void setWheelRotating(bool rotating);
64 |
65 | private Q_SLOTS:
66 | void emit_changed();
67 | void handle_removed(int);
68 | void color_changed(int row);
69 |
70 | private:
71 | class Private;
72 | Private * const p;
73 | void append_widget(int col);
74 | };
75 |
76 | } // namespace color_widgets
77 |
78 | #endif // COLOR_LIST_WIDGET_HPP
79 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/src/QtColorWidgets/color_utils.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #include "QtColorWidgets/color_utils.hpp"
23 |
24 | namespace color_widgets {
25 | namespace detail {
26 |
27 | QColor color_from_lch(qreal hue, qreal chroma, qreal luma, qreal alpha )
28 | {
29 | qreal h1 = hue*6;
30 | qreal x = chroma*(1-qAbs(std::fmod(h1,2)-1));
31 | QColor col;
32 | if ( h1 >= 0 && h1 < 1 )
33 | col = QColor::fromRgbF(chroma,x,0);
34 | else if ( h1 < 2 )
35 | col = QColor::fromRgbF(x,chroma,0);
36 | else if ( h1 < 3 )
37 | col = QColor::fromRgbF(0,chroma,x);
38 | else if ( h1 < 4 )
39 | col = QColor::fromRgbF(0,x,chroma);
40 | else if ( h1 < 5 )
41 | col = QColor::fromRgbF(x,0,chroma);
42 | else if ( h1 < 6 )
43 | col = QColor::fromRgbF(chroma,0,x);
44 |
45 | qreal m = luma - color_lumaF(col);
46 |
47 | return QColor::fromRgbF(
48 | qBound(0.0,col.redF()+m,1.0),
49 | qBound(0.0,col.greenF()+m,1.0),
50 | qBound(0.0,col.blueF()+m,1.0),
51 | alpha);
52 | }
53 |
54 | QColor color_from_hsl(qreal hue, qreal sat, qreal lig, qreal alpha )
55 | {
56 | qreal chroma = (1 - qAbs(2*lig-1))*sat;
57 | qreal h1 = hue*6;
58 | qreal x = chroma*(1-qAbs(std::fmod(h1,2)-1));
59 | QColor col;
60 | if ( h1 >= 0 && h1 < 1 )
61 | col = QColor::fromRgbF(chroma,x,0);
62 | else if ( h1 < 2 )
63 | col = QColor::fromRgbF(x,chroma,0);
64 | else if ( h1 < 3 )
65 | col = QColor::fromRgbF(0,chroma,x);
66 | else if ( h1 < 4 )
67 | col = QColor::fromRgbF(0,x,chroma);
68 | else if ( h1 < 5 )
69 | col = QColor::fromRgbF(x,0,chroma);
70 | else if ( h1 < 6 )
71 | col = QColor::fromRgbF(chroma,0,x);
72 |
73 | qreal m = lig-chroma/2;
74 |
75 | return QColor::fromRgbF(
76 | qBound(0.0,col.redF()+m,1.0),
77 | qBound(0.0,col.greenF()+m,1.0),
78 | qBound(0.0,col.blueF()+m,1.0),
79 | alpha);
80 | }
81 |
82 | } // namespace detail
83 | } // namespace color_widgets
84 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/src/QtColorWidgets/color_names.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #include "QtColorWidgets/color_names.hpp"
23 | #include
24 |
25 | static QRegularExpression regex_qcolor (QStringLiteral("^(?:(?:#[[:xdigit:]]{3})|(?:#[[:xdigit:]]{6})|(?:[[:alpha:]]+))$"));
26 | static QRegularExpression regex_func_rgb (QStringLiteral(R"(^rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)$)"));
27 | static QRegularExpression regex_hex_rgba (QStringLiteral("^#[[:xdigit:]]{8}$"));
28 | static QRegularExpression regex_func_rgba (QStringLiteral(R"(^rgba?\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)$)"));
29 |
30 | namespace color_widgets {
31 |
32 |
33 | QString stringFromColor(const QColor& color, bool alpha)
34 | {
35 | if ( !alpha || color.alpha() == 255 )
36 | return color.name();
37 | return color.name()+QStringLiteral("%1").arg(color.alpha(), 2, 16, QChar('0'));
38 | }
39 |
40 | QColor colorFromString(const QString& string, bool alpha)
41 | {
42 | QString xs = string.trimmed();
43 | QRegularExpressionMatch match;
44 |
45 | match = regex_qcolor.match(xs);
46 | if ( match.hasMatch() )
47 | {
48 | return QColor(xs);
49 | }
50 |
51 | match = regex_func_rgb.match(xs);
52 | if ( match.hasMatch() )
53 | {
54 | return QColor(
55 | match.captured(1).toInt(),
56 | match.captured(2).toInt(),
57 | match.captured(3).toInt()
58 | );
59 | }
60 |
61 | if ( alpha )
62 | {
63 | match = regex_hex_rgba.match(xs);
64 | if ( match.hasMatch() )
65 | {
66 | return QColor(
67 | xs.mid(1,2).toInt(nullptr,16),
68 | xs.mid(3,2).toInt(nullptr,16),
69 | xs.mid(5,2).toInt(nullptr,16),
70 | xs.mid(7,2).toInt(nullptr,16)
71 | );
72 | }
73 |
74 | match = regex_func_rgba.match(xs);
75 | if ( match.hasMatch() )
76 | {
77 | return QColor(
78 | match.captured(1).toInt(),
79 | match.captured(2).toInt(),
80 | match.captured(3).toInt(),
81 | match.captured(4).toInt()
82 | );
83 | }
84 | }
85 |
86 | return QColor();
87 | }
88 |
89 | } // namespace color_widgets
90 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/harmony_color_wheel.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | * \copyright Copyright (C) 2017 caryoscelus
8 | *
9 | * This program is free software: you can redistribute it and/or modify
10 | * it under the terms of the GNU Lesser General Public License as published by
11 | * the Free Software Foundation, either version 3 of the License, or
12 | * (at your option) any later version.
13 | *
14 | * This program is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | * GNU Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public License
20 | * along with this program. If not, see .
21 | *
22 | */
23 | #ifndef HARMONY_COLOR_WHEEL_HPP
24 | #define HARMONY_COLOR_WHEEL_HPP
25 |
26 |
27 | #include "color_wheel.hpp"
28 |
29 | namespace color_widgets {
30 |
31 | /**
32 | * \brief ColorWheel with color harmonies
33 | */
34 | class QCP_EXPORT HarmonyColorWheel : public ColorWheel
35 | {
36 | Q_OBJECT
37 |
38 | public:
39 | explicit HarmonyColorWheel(QWidget *parent = 0);
40 | ~HarmonyColorWheel();
41 |
42 | /// Get all harmony colors (including main)
43 | QList harmonyColors() const;
44 |
45 | /// Get number of harmony colors (including main)
46 | unsigned int harmonyCount() const;
47 |
48 | /// Clear harmony color scheme
49 | void clearHarmonies();
50 |
51 | /**
52 | * @brief Add harmony color
53 | * @param hue_diff Initial hue difference (in [0-1) range)
54 | * @param editable Whether this harmony should be editable
55 | * @returns Index of newly added harmony
56 | */
57 | unsigned addHarmony(double hue_diff, bool editable);
58 |
59 | /**
60 | * @brief Add symmetric harmony color
61 | * @param relative_to Index of other harmony that should be symmetric relative to main hue
62 | * @returns Index of newly added harmony
63 | * Editability is inherited from symmetric editor
64 | */
65 | unsigned addSymmetricHarmony(unsigned relative_to);
66 |
67 | /**
68 | * @brief Add opposite harmony color
69 | * @param relative_to Index of other harmony that should be opposite to this
70 | * @returns Index of newly added harmony
71 | * Editability is inherited from opposite editor
72 | */
73 | unsigned addOppositeHarmony(unsigned relative_to);
74 |
75 | Q_SIGNALS:
76 | /**
77 | * Emitted when harmony settings or harmony colors are changed (including due to main hue change)
78 | */
79 | void harmonyChanged();
80 |
81 | protected:
82 | void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
83 | void mouseMoveEvent(QMouseEvent *) Q_DECL_OVERRIDE;
84 | void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE;
85 | void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE;
86 |
87 | private:
88 | class Private;
89 | Private * p;
90 | };
91 |
92 | } // namespace color_widgets
93 |
94 | #endif // COLOR_WHEEL_HPP
95 |
96 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/abstract_widget_list.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef ABSTRACT_WIDGET_LIST_HPP
23 | #define ABSTRACT_WIDGET_LIST_HPP
24 |
25 | #include "colorwidgets_global.hpp"
26 |
27 | #include
28 | #include
29 |
30 | class QCP_EXPORT AbstractWidgetList : public QWidget
31 | {
32 | Q_OBJECT
33 | public:
34 | explicit AbstractWidgetList(QWidget *parent = 0);
35 | ~AbstractWidgetList();
36 |
37 | /**
38 | * \brief Get the number of items
39 | */
40 | int count() const;
41 |
42 | /**
43 | * \brief Swap row a and row b
44 | */
45 | virtual void swap(int a, int b) = 0;
46 |
47 |
48 | /// Whether the given row index is valid
49 | bool isValidRow(int i) const { return i >= 0 && i < count(); }
50 |
51 | void setRowHeight(int row, int height);
52 |
53 |
54 | public Q_SLOTS:
55 | /**
56 | * \brief Remove row i
57 | */
58 | void remove(int i);
59 |
60 | /**
61 | * \brief append a default row
62 | */
63 | virtual void append() = 0;
64 |
65 | Q_SIGNALS:
66 | void removed(int i);
67 |
68 | protected:
69 |
70 | /**
71 | * \brief Create a new row with the given widget
72 | *
73 | * Must be caled by implementations of append()
74 | */
75 | void appendWidget(QWidget* w);
76 |
77 | /**
78 | * \brief get the widget found at the given row
79 | */
80 | QWidget* widget(int i);
81 |
82 |
83 | /**
84 | * \brief get the widget found at the given row
85 | */
86 | template
87 | T* widget_cast(int i) { return qobject_cast(widget(i)); }
88 |
89 | /**
90 | * \brief clear all rows without emitting signals
91 | *
92 | * May be useful when implementation want to set all values at once
93 | */
94 | void clear();
95 |
96 | private Q_SLOTS:
97 | void remove_clicked(QWidget* w);
98 | void up_clicked(QWidget* w);
99 | void down_clicked(QWidget* w);
100 |
101 | private:
102 | class Private;
103 | Private * const p;
104 |
105 | QWidget* create_button(QWidget* data, QSignalMapper*mapper,
106 | QString icon_name, QString text,
107 | QString tooltip = QString()) const;
108 | };
109 |
110 | #endif // ABSTRACT_WIDGET_LIST_HPP
111 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/gradient_helper.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef GRADIENT_HELPER_HPP
23 | #define GRADIENT_HELPER_HPP
24 |
25 | #include "colorwidgets_global.hpp"
26 |
27 | #include
28 |
29 | namespace color_widgets {
30 |
31 | inline QColor blendColors(const QColor& a, const QColor& b, qreal ratio)
32 | {
33 | return QColor::fromRgbF(
34 | a.redF() * (1-ratio) + b.redF() * ratio,
35 | a.greenF() * (1-ratio) + b.greenF() * ratio,
36 | a.blueF() * (1-ratio) + b.blueF() * ratio,
37 | a.alphaF() * (1-ratio) + b.alphaF() * ratio
38 | );
39 | }
40 |
41 |
42 | /**
43 | * \brief Get an insertion point in the gradient
44 | * \param gradient Gradient stops to look into (must be properly set up)
45 | * \param factor Value in [0, 1] to get the color for
46 | * \return A pair whose first element is the index to insert the new value at, and a GradientStop
47 | */
48 | inline QPair Q_DECL_EXPORT gradientBlendedColorInsert(const QGradientStops& gradient, qreal factor)
49 | {
50 | if ( gradient.empty() )
51 | return {0, {0, QColor()}};
52 |
53 | if ( gradient.size() == 1 || factor <= 0 )
54 | return {0, gradient.front()};
55 |
56 | int i = 0;
57 | QGradientStop s1;
58 | for ( auto s2 : gradient )
59 | {
60 | if ( factor < s2.first )
61 | {
62 | qreal ratio = (factor - s1.first) / (s2.first - s1.first);
63 | return {i, {factor, blendColors(s1.second, s2.second, ratio)}};
64 | }
65 | s1 = s2;
66 | ++i;
67 | }
68 |
69 | return {gradient.size(), gradient.back()};
70 | }
71 |
72 | /**
73 | * \brief Returns a color in the gradient
74 | * \param gradient Gradient stops to look into (must be properly set up)
75 | * \param factor Value in [0, 1] to get the color for
76 | */
77 | inline QColor Q_DECL_EXPORT gradientBlendedColor(const QGradientStops& gradient, qreal factor)
78 | {
79 | return gradientBlendedColorInsert(gradient, factor).second.second;
80 | }
81 |
82 | /**
83 | * \brief Returns a color in the gradient
84 | * \param gradient Gradient to look into
85 | * \param factor Value in [0, 1] to get the color for
86 | */
87 | inline QColor Q_DECL_EXPORT gradientBlendedColor(const QGradient& gradient, qreal factor)
88 | {
89 | return gradientBlendedColor(gradient.stops(), factor);
90 | }
91 |
92 | } // namespace color_widgets
93 |
94 |
95 |
96 |
97 | #endif // GRADIENT_HELPER_HPP
98 |
99 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/color_line_edit.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef COLOR_WIDGETS_COLOR_LINE_EDIT_HPP
23 | #define COLOR_WIDGETS_COLOR_LINE_EDIT_HPP
24 |
25 | #include "colorwidgets_global.hpp"
26 | #include
27 | #include
28 |
29 | namespace color_widgets {
30 |
31 | /**
32 | * \brief A line edit used to define a color name
33 | *
34 | * Supported string formats:
35 | * * Short hex strings #f00
36 | * * Long hex strings #ff0000
37 | * * Color names red
38 | * * Function-like rgb(255,0,0)
39 | *
40 | * Additional string formats supported when showAlpha is true:
41 | * * Long hex strings #ff0000ff
42 | * * Function like rgba(255,0,0,255)
43 | */
44 | class QCP_EXPORT ColorLineEdit : public QLineEdit
45 | {
46 | Q_OBJECT
47 | Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
48 | /**
49 | * \brief Whether the widget displays and edits the alpha channel
50 | */
51 | Q_PROPERTY(bool showAlpha READ showAlpha WRITE setShowAlpha NOTIFY showAlphaChanged)
52 | /**
53 | * \brief If \b true, the background of the widget is changed to show the color
54 | */
55 | Q_PROPERTY(bool previewColor READ previewColor WRITE setPreviewColor NOTIFY previewColorChanged)
56 |
57 | public:
58 | explicit ColorLineEdit(QWidget* parent = nullptr);
59 | ~ColorLineEdit();
60 |
61 | QColor color() const;
62 | bool showAlpha() const;
63 | bool previewColor() const;
64 |
65 | public Q_SLOTS:
66 | void setColor(const QColor& color);
67 | void setShowAlpha(bool showAlpha);
68 | void setPreviewColor(bool previewColor);
69 |
70 | Q_SIGNALS:
71 | /**
72 | * \brief Emitted when the color is changed by any means
73 | */
74 | void colorChanged(const QColor& color);
75 | /**
76 | * \brief Emitted when the user is typing a color but has not finished yet
77 | */
78 | void colorEdited(const QColor& color);
79 | /**
80 | * \brief Emitted when the user finished to edit a string
81 | */
82 | void colorEditingFinished(const QColor& color);
83 |
84 | void showAlphaChanged(bool showAlpha);
85 | void previewColorChanged(bool previewColor);
86 |
87 | protected:
88 | void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE;
89 | void dropEvent(QDropEvent * event) Q_DECL_OVERRIDE;
90 | void paintEvent(QPaintEvent* event) Q_DECL_OVERRIDE;
91 |
92 | private:
93 | class Private;
94 | Private* p;
95 | };
96 |
97 | } // namespace color_widgets
98 | #endif // COLOR_WIDGETS_COLOR_LINE_EDIT_HPP
99 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/hue_slider.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2014 Calle Laakkonen
7 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
8 | *
9 | * This program is free software: you can redistribute it and/or modify
10 | * it under the terms of the GNU Lesser General Public License as published by
11 | * the Free Software Foundation, either version 3 of the License, or
12 | * (at your option) any later version.
13 | *
14 | * This program is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | * GNU Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public License
20 | * along with this program. If not, see .
21 | *
22 | */
23 | #ifndef HUE_SLIDER_HPP
24 | #define HUE_SLIDER_HPP
25 |
26 | #include "gradient_slider.hpp"
27 |
28 | namespace color_widgets {
29 |
30 | /**
31 | * \brief A slider for selecting a hue value
32 | */
33 | class QCP_EXPORT HueSlider : public GradientSlider
34 | {
35 | Q_OBJECT
36 | /**
37 | * \brief Saturation used in the rainbow gradient, as a [0-1] float
38 | */
39 | Q_PROPERTY(qreal colorSaturation READ colorSaturation WRITE setColorSaturation NOTIFY colorSaturationChanged)
40 | /**
41 | * \brief Value used in the rainbow gradient, as a [0-1] float
42 | */
43 | Q_PROPERTY(qreal colorValue READ colorValue WRITE setColorValue NOTIFY colorValueChanged)
44 | /**
45 | * \brief Alpha used in the rainbow gradient, as a [0-1] float
46 | */
47 | Q_PROPERTY(qreal colorAlpha READ colorAlpha WRITE setColorAlpha NOTIFY colorAlphaChanged)
48 |
49 | /**
50 | * \brief Color with corresponding color* components
51 | */
52 | Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
53 |
54 | /**
55 | * \brief Normalized Hue, as indicated from the slider
56 | */
57 | Q_PROPERTY(qreal colorHue READ colorHue WRITE setColorHue NOTIFY colorHueChanged)
58 |
59 |
60 | public:
61 | explicit HueSlider(QWidget *parent = nullptr);
62 | explicit HueSlider(Qt::Orientation orientation, QWidget *parent = nullptr);
63 | ~HueSlider();
64 |
65 | qreal colorSaturation() const;
66 | qreal colorValue() const;
67 | qreal colorAlpha() const;
68 | QColor color() const;
69 | qreal colorHue() const;
70 |
71 | public Q_SLOTS:
72 | void setColorValue(qreal value);
73 | void setColorSaturation(qreal value);
74 | void setColorAlpha(qreal alpha);
75 | void setColorHue(qreal colorHue);
76 | /**
77 | * \brief Set Hue Saturation and ColorValue, ignoring alpha
78 | */
79 | void setColor(const QColor& color);
80 | /**
81 | * \brief Set Hue Saturation, ColorValue and Alpha
82 | */
83 | void setFullColor(const QColor& color);
84 |
85 | Q_SIGNALS:
86 | void colorHueChanged(qreal colorHue);
87 | void colorChanged(QColor);
88 | void colorAlphaChanged(qreal v);
89 | void colorSaturationChanged(qreal v);
90 | void colorValueChanged(qreal v);
91 |
92 | private:
93 | class Private;
94 | Private * const p;
95 | };
96 |
97 | } // namespace color_widgets
98 |
99 | #endif // HUE_SLIDER_HPP
100 |
101 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/color_widgets.pri:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2013-2019 Mattia Basaglia
2 | #
3 | #
4 | # This software is free software: you can redistribute it and/or modify
5 | # it under the terms of the GNU Lesser General Public License as published by
6 | # the Free Software Foundation, either version 3 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This software is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU Lesser General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU Lesser General Public License
15 | # along with Color Widgets. If not, see .
16 |
17 | CONFIG += c++11
18 |
19 | INCLUDEPATH += $$PWD/src $$PWD/include
20 |
21 | SOURCES += \
22 | $$PWD/src/QtColorWidgets/abstract_widget_list.cpp \
23 | $$PWD/src/QtColorWidgets/bound_color_selector.cpp \
24 | $$PWD/src/QtColorWidgets/color_2d_slider.cpp \
25 | $$PWD/src/QtColorWidgets/color_delegate.cpp \
26 | $$PWD/src/QtColorWidgets/color_dialog.cpp \
27 | $$PWD/src/QtColorWidgets/color_line_edit.cpp \
28 | $$PWD/src/QtColorWidgets/color_list_widget.cpp \
29 | $$PWD/src/QtColorWidgets/color_names.cpp \
30 | $$PWD/src/QtColorWidgets/color_palette.cpp \
31 | $$PWD/src/QtColorWidgets/color_palette_model.cpp \
32 | $$PWD/src/QtColorWidgets/color_palette_widget.cpp \
33 | $$PWD/src/QtColorWidgets/color_preview.cpp \
34 | $$PWD/src/QtColorWidgets/color_selector.cpp \
35 | $$PWD/src/QtColorWidgets/color_utils.cpp \
36 | $$PWD/src/QtColorWidgets/color_wheel.cpp \
37 | $$PWD/src/QtColorWidgets/gradient_editor.cpp \
38 | $$PWD/src/QtColorWidgets/gradient_list_model.cpp \
39 | $$PWD/src/QtColorWidgets/gradient_slider.cpp \
40 | $$PWD/src/QtColorWidgets/harmony_color_wheel.cpp \
41 | $$PWD/src/QtColorWidgets/hue_slider.cpp \
42 | $$PWD/src/QtColorWidgets/swatch.cpp
43 |
44 | HEADERS += \
45 | $$PWD/include/QtColorWidgets/abstract_widget_list.hpp \
46 | $$PWD/include/QtColorWidgets/bound_color_selector.hpp \
47 | $$PWD/include/QtColorWidgets/color_2d_slider.hpp \
48 | $$PWD/include/QtColorWidgets/color_delegate.hpp \
49 | $$PWD/include/QtColorWidgets/color_dialog.hpp \
50 | $$PWD/include/QtColorWidgets/color_line_edit.hpp \
51 | $$PWD/include/QtColorWidgets/color_list_widget.hpp \
52 | $$PWD/include/QtColorWidgets/color_names.hpp \
53 | $$PWD/include/QtColorWidgets/color_palette.hpp \
54 | $$PWD/include/QtColorWidgets/color_palette_model.hpp \
55 | $$PWD/include/QtColorWidgets/color_palette_widget.hpp \
56 | $$PWD/include/QtColorWidgets/color_preview.hpp \
57 | $$PWD/include/QtColorWidgets/color_selector.hpp \
58 | $$PWD/include/QtColorWidgets/color_utils.hpp \
59 | $$PWD/include/QtColorWidgets/color_wheel.hpp \
60 | $$PWD/include/QtColorWidgets/color_wheel_private.hpp \
61 | $$PWD/include/QtColorWidgets/colorwidgets_global.hpp \
62 | $$PWD/include/QtColorWidgets/gradient_delegate.hpp \
63 | $$PWD/include/QtColorWidgets/gradient_editor.hpp \
64 | $$PWD/include/QtColorWidgets/gradient_helper.hpp \
65 | $$PWD/include/QtColorWidgets/gradient_list_model.hpp \
66 | $$PWD/include/QtColorWidgets/gradient_slider.hpp \
67 | $$PWD/include/QtColorWidgets/harmony_color_wheel.hpp \
68 | $$PWD/include/QtColorWidgets/hue_slider.hpp \
69 | $$PWD/include/QtColorWidgets/swatch.hpp
70 |
71 | FORMS += \
72 | $$PWD/src/QtColorWidgets/color_dialog.ui \
73 | $$PWD/src/QtColorWidgets/color_palette_widget.ui
74 |
75 | RESOURCES += \
76 | $$PWD/resources/QtColorWidgets/color_widgets.qrc
77 |
78 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/color_selector.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef COLOR_SELECTOR_HPP
23 | #define COLOR_SELECTOR_HPP
24 |
25 | #include "color_preview.hpp"
26 | #include "color_wheel.hpp"
27 |
28 | namespace color_widgets {
29 |
30 | /**
31 | * Color preview that opens a color dialog
32 | */
33 | class QCP_EXPORT ColorSelector : public ColorPreview
34 | {
35 | Q_OBJECT
36 | Q_ENUMS(UpdateMode)
37 | Q_PROPERTY(UpdateMode updateMode READ updateMode WRITE setUpdateMode NOTIFY updateModeChanged)
38 | Q_PROPERTY(Qt::WindowModality dialogModality READ dialogModality WRITE setDialogModality NOTIFY dialogModalityChanged)
39 | Q_PROPERTY(ColorWheel::ShapeEnum wheelShape READ wheelShape WRITE setWheelShape NOTIFY wheelShapeChanged)
40 | Q_PROPERTY(ColorWheel::ColorSpaceEnum colorSpace READ colorSpace WRITE setColorSpace NOTIFY colorSpaceChanged)
41 | Q_PROPERTY(bool wheelRotating READ wheelRotating WRITE setWheelRotating NOTIFY wheelRotatingChanged)
42 |
43 | public:
44 | enum UpdateMode {
45 | Confirm, ///< Update color only after the dialog has been accepted
46 | Continuous ///< Update color as it's being modified in the dialog
47 | };
48 |
49 | explicit ColorSelector(QWidget *parent = 0);
50 | ~ColorSelector();
51 |
52 | void setUpdateMode(UpdateMode m);
53 | UpdateMode updateMode() const;
54 |
55 | Qt::WindowModality dialogModality() const;
56 | void setDialogModality(Qt::WindowModality m);
57 |
58 | ColorWheel::ShapeEnum wheelShape() const;
59 | ColorWheel::ColorSpaceEnum colorSpace() const;
60 | bool wheelRotating() const;
61 |
62 | Q_SIGNALS:
63 | void wheelShapeChanged(ColorWheel::ShapeEnum shape);
64 | void colorSpaceChanged(ColorWheel::ColorSpaceEnum space);
65 | void wheelRotatingChanged(bool rotating);
66 | void updateModeChanged(UpdateMode);
67 | void dialogModalityChanged(Qt::WindowModality);
68 | /// Emitted when a color is selected by the user
69 | void colorSelected(const QColor& c);
70 |
71 | public Q_SLOTS:
72 | void showDialog();
73 | void setWheelShape(ColorWheel::ShapeEnum shape);
74 | void setColorSpace(ColorWheel::ColorSpaceEnum space);
75 | void setWheelRotating(bool rotating);
76 |
77 | private Q_SLOTS:
78 | void accept_dialog();
79 | void reject_dialog();
80 | void update_old_color(const QColor &c);
81 |
82 | protected:
83 | void dragEnterEvent(QDragEnterEvent *event);
84 | void dropEvent(QDropEvent * event);
85 |
86 | private:
87 | /// Connect/Disconnect colorChanged based on UpdateMode
88 | void connect_dialog();
89 |
90 | /// Disconnect from dialog update
91 | void disconnect_dialog();
92 |
93 | class Private;
94 | Private * const p;
95 | };
96 |
97 | } // namespace color_widgets
98 |
99 | #endif // COLOR_SELECTOR_HPP
100 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/gradient_slider.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file gradient_slider.hpp
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | * \copyright Copyright (C) 2014 Calle Laakkonen
8 | * \copyright Copyright (C) 2017 caryoscelus
9 | *
10 | * This program is free software: you can redistribute it and/or modify
11 | * it under the terms of the GNU Lesser General Public License as published by
12 | * the Free Software Foundation, either version 3 of the License, or
13 | * (at your option) any later version.
14 | *
15 | * This program is distributed in the hope that it will be useful,
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | * GNU Lesser General Public License for more details.
19 | *
20 | * You should have received a copy of the GNU Lesser General Public License
21 | * along with this program. If not, see .
22 | *
23 | */
24 | #ifndef GRADIENT_SLIDER_HPP
25 | #define GRADIENT_SLIDER_HPP
26 |
27 | #include "colorwidgets_global.hpp"
28 |
29 | #include
30 | #include
31 |
32 | namespace color_widgets {
33 |
34 | /**
35 | * \brief A slider that moves on top of a gradient
36 | */
37 | class QCP_EXPORT GradientSlider : public QSlider
38 | {
39 | Q_OBJECT
40 | Q_PROPERTY(QBrush background READ background WRITE setBackground NOTIFY backgroundChanged)
41 | Q_PROPERTY(QGradientStops colors READ colors WRITE setColors DESIGNABLE false)
42 | Q_PROPERTY(QColor firstColor READ firstColor WRITE setFirstColor STORED false)
43 | Q_PROPERTY(QColor lastColor READ lastColor WRITE setLastColor STORED false)
44 | Q_PROPERTY(QLinearGradient gradient READ gradient WRITE setGradient)
45 |
46 | public:
47 | explicit GradientSlider(QWidget *parent = 0);
48 | explicit GradientSlider(Qt::Orientation orientation, QWidget *parent = 0);
49 | ~GradientSlider();
50 |
51 | /// Get the background, it's visible for transparent gradient stops
52 | QBrush background() const;
53 | /// Set the background, it's visible for transparent gradient stops
54 | void setBackground(const QBrush &bg);
55 |
56 | /// Get the colors that make up the gradient
57 | QGradientStops colors() const;
58 | /// Set the colors that make up the gradient
59 | void setColors(const QGradientStops &colors);
60 |
61 | /// Get the gradient
62 | QLinearGradient gradient() const;
63 | /// Set the gradient
64 | void setGradient(const QLinearGradient &gradient);
65 |
66 | /**
67 | * Overload: create an evenly distributed gradient of the given colors
68 | */
69 | void setColors(const QVector &colors);
70 |
71 | /**
72 | * \brief Set the first color of the gradient
73 | *
74 | * If the gradient is currently empty it will create a stop with the given color
75 | */
76 | void setFirstColor(const QColor &c);
77 |
78 | /**
79 | * \brief Set the last color of the gradient
80 | *
81 | * If the gradient is has less than two colors,
82 | * it will create a stop with the given color
83 | */
84 | void setLastColor(const QColor &c);
85 |
86 | /**
87 | * \brief Get the first color
88 | *
89 | * \returns QColor() con empty gradient
90 | */
91 | QColor firstColor() const;
92 |
93 | /**
94 | * \brief Get the last color
95 | *
96 | * \returns QColor() con empty gradient
97 | */
98 | QColor lastColor() const;
99 |
100 | Q_SIGNALS:
101 | void backgroundChanged(const QBrush&);
102 |
103 | protected:
104 | void paintEvent(QPaintEvent *ev) override;
105 |
106 | void mousePressEvent(QMouseEvent *ev) override;
107 | void mouseMoveEvent(QMouseEvent *ev) override;
108 | void mouseReleaseEvent(QMouseEvent *ev) override;
109 |
110 | private:
111 | class Private;
112 | Private * const p;
113 | };
114 |
115 | } // namespace color_widgets
116 |
117 | #endif // GRADIENT_SLIDER_HPP
118 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/gradient_delegate.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 |
23 | #ifndef COLOR_WIDGETS_GRADIENT_DELEGATE_HPP
24 | #define COLOR_WIDGETS_GRADIENT_DELEGATE_HPP
25 |
26 |
27 | #include
28 | #include
29 |
30 | #include "QtColorWidgets/gradient_editor.hpp"
31 |
32 | namespace color_widgets {
33 |
34 | /**
35 | * \brief Item delegate to edits gradients
36 | *
37 | * In order to make it work, return as edit data from the model a QBrush with a gradient
38 | */
39 | class QCP_EXPORT GradientDelegate : public QStyledItemDelegate
40 | {
41 | Q_OBJECT
42 |
43 | public:
44 | QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const Q_DECL_OVERRIDE
45 | {
46 | QVariant data = index.data(Qt::EditRole);
47 | if ( data.canConvert() )
48 | {
49 | QBrush brush = data.value();
50 | if ( brush.gradient() )
51 | {
52 | GradientEditor* editor = new GradientEditor(parent);
53 | editor->setStops(brush.gradient()->stops());
54 | return editor;
55 | }
56 | }
57 |
58 | return QStyledItemDelegate::createEditor(parent, option, index);
59 | }
60 |
61 | void setModelData(QWidget * widget, QAbstractItemModel * model, const QModelIndex & index) const Q_DECL_OVERRIDE
62 | {
63 | if ( GradientEditor* editor = qobject_cast(widget) )
64 | model->setData(index, QBrush(editor->gradient()), Qt::EditRole);
65 | else
66 | QStyledItemDelegate::setModelData(widget, model, index);
67 | }
68 |
69 | void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const Q_DECL_OVERRIDE
70 | {
71 | QVariant display_data = index.data(Qt::DisplayRole);
72 | QVariant gradient_data = display_data.isValid() ? display_data : index.data(Qt::EditRole);
73 | if ( gradient_data.canConvert() )
74 | {
75 | QBrush brush = gradient_data.value();
76 | if ( brush.gradient() )
77 | {
78 | QBrush background;
79 | background.setTexture(QPixmap(QStringLiteral(":/color_widgets/alphaback.png")));
80 | painter->fillRect(option.rect, background);
81 |
82 | QLinearGradient g(option.rect.topLeft(), option.rect.topRight());
83 | g.setStops(brush.gradient()->stops());
84 | painter->fillRect(option.rect, g);
85 |
86 | if ( option.state & QStyle::State_Selected )
87 | {
88 | int border = 2;
89 | painter->setBrush(Qt::transparent);
90 | painter->setPen(QPen(option.palette.highlight(), border));
91 | painter->drawRect(option.rect.adjusted(border/2, border/2, -border/2, -border/2));
92 | }
93 | return;
94 | }
95 | }
96 |
97 | QStyledItemDelegate::paint(painter, option, index);
98 | }
99 | };
100 |
101 | } // namespace color_widgets
102 |
103 | #endif // COLOR_WIDGETS_GRADIENT_DELEGATE_HPP
104 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/color_2d_slider.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef COLOR_WIDGETS_COLOR_2D_SLIDER_HPP
23 | #define COLOR_WIDGETS_COLOR_2D_SLIDER_HPP
24 |
25 | #include "colorwidgets_global.hpp"
26 | #include
27 |
28 | namespace color_widgets {
29 |
30 | /**
31 | * \brief A 2D slider that edits 2 color components
32 | */
33 | class QCP_EXPORT Color2DSlider : public QWidget
34 | {
35 | Q_OBJECT
36 |
37 | Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged DESIGNABLE true STORED false )
38 | Q_PROPERTY(qreal hue READ hue WRITE setHue DESIGNABLE false )
39 | Q_PROPERTY(qreal saturation READ saturation WRITE setSaturation DESIGNABLE false )
40 | Q_PROPERTY(qreal value READ value WRITE setValue DESIGNABLE false )
41 | /**
42 | * \brief Which color component is used on the x axis
43 | */
44 | Q_PROPERTY(Component componentX READ componentX WRITE setComponentX NOTIFY componentXChanged)
45 | /**
46 | * \brief Which color component is used on the y axis
47 | */
48 | Q_PROPERTY(Component componentY READ componentY WRITE setComponentY NOTIFY componentYChanged)
49 |
50 |
51 | public:
52 | enum Component {
53 | Hue, Saturation, Value
54 | };
55 | Q_ENUMS(Component)
56 |
57 | explicit Color2DSlider(QWidget *parent = nullptr);
58 | ~Color2DSlider();
59 |
60 | /// Get current color
61 | QColor color() const;
62 |
63 | QSize sizeHint() const Q_DECL_OVERRIDE;
64 |
65 | /// Get current hue in the range [0-1]
66 | qreal hue() const;
67 |
68 | /// Get current saturation in the range [0-1]
69 | qreal saturation() const;
70 |
71 | /// Get current value in the range [0-1]
72 | qreal value() const;
73 |
74 | Component componentX() const;
75 | Component componentY() const;
76 |
77 | public Q_SLOTS:
78 |
79 | /// Set current color
80 | void setColor(const QColor& c);
81 |
82 | /**
83 | * @param h Hue [0-1]
84 | */
85 | void setHue(qreal h);
86 |
87 | /**
88 | * @param s Saturation [0-1]
89 | */
90 | void setSaturation(qreal s);
91 |
92 | /**
93 | * @param v Value [0-1]
94 | */
95 | void setValue(qreal v);
96 |
97 | void setComponentX(Component componentX);
98 | void setComponentY(Component componentY);
99 |
100 | Q_SIGNALS:
101 | /**
102 | * Emitted when the user selects a color or setColor is called
103 | */
104 | void colorChanged(QColor);
105 |
106 | /**
107 | * Emitted when the user selects a color
108 | */
109 | void colorSelected(QColor);
110 |
111 | void componentXChanged(Component componentX);
112 | void componentYChanged(Component componentY);
113 |
114 | protected:
115 | void paintEvent(QPaintEvent* event) Q_DECL_OVERRIDE;
116 | void mousePressEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
117 | void mouseMoveEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
118 | void mouseReleaseEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
119 | void resizeEvent(QResizeEvent* event) Q_DECL_OVERRIDE;
120 |
121 | private:
122 | class Private;
123 | Private * const p;
124 | };
125 |
126 | } // namespace color_widgets
127 |
128 | #endif // COLOR_WIDGETS_COLOR_2D_SLIDER_HPP
129 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/color_preview.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | * \copyright Copyright (C) 2014 Calle Laakkonen
8 | *
9 | * This program is free software: you can redistribute it and/or modify
10 | * it under the terms of the GNU Lesser General Public License as published by
11 | * the Free Software Foundation, either version 3 of the License, or
12 | * (at your option) any later version.
13 | *
14 | * This program is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | * GNU Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public License
20 | * along with this program. If not, see .
21 | *
22 | */
23 | #ifndef COLOR_PREVIEW_HPP
24 | #define COLOR_PREVIEW_HPP
25 |
26 | #include "colorwidgets_global.hpp"
27 |
28 | #include
29 |
30 | namespace color_widgets {
31 |
32 | /**
33 | * Simple widget that shows a preview of a color
34 | */
35 | class QCP_EXPORT ColorPreview : public QWidget
36 | {
37 | Q_OBJECT
38 | Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged DESIGNABLE true)
39 | Q_PROPERTY(QColor comparisonColor READ comparisonColor WRITE setComparisonColor NOTIFY comparisonColorChanged DESIGNABLE true)
40 | Q_PROPERTY(DisplayMode display_mode READ displayMode WRITE setDisplayMode NOTIFY displayModeChanged DESIGNABLE true)
41 | Q_PROPERTY(QBrush background READ background WRITE setBackground NOTIFY backgroundChanged DESIGNABLE true)
42 | Q_PROPERTY(bool drawFrame READ drawFrame WRITE setDrawFrame NOTIFY drawFrameChanged DESIGNABLE true)
43 | Q_ENUMS(DisplayMode)
44 | public:
45 | enum DisplayMode
46 | {
47 | NoAlpha, ///< Show current color with no transparency
48 | AllAlpha, ///< show current color with transparency
49 | SplitAlpha, ///< Show both solid and transparent side by side
50 | SplitColor, ///< Show current and comparison colors side by side
51 | SplitColorReverse, ///< Like Split color but swapped
52 | };
53 | Q_ENUMS(DisplayMode)
54 |
55 | explicit ColorPreview(QWidget *parent = 0);
56 | ~ColorPreview();
57 |
58 | /// Get the background visible under transparent colors
59 | QBrush background() const;
60 |
61 | /// Change the background visible under transparent colors
62 | void setBackground(const QBrush &bk);
63 |
64 | /// Get color display mode
65 | DisplayMode displayMode() const;
66 |
67 | /// Set how transparent colors are handled
68 | void setDisplayMode(DisplayMode dm);
69 |
70 | /// Get current color
71 | QColor color() const;
72 |
73 | /// Get the comparison color
74 | QColor comparisonColor() const;
75 |
76 | QSize sizeHint () const;
77 |
78 | void paint(QPainter &painter, QRect rect) const;
79 |
80 | /// Whether to draw a frame around the color
81 | bool drawFrame() const;
82 | void setDrawFrame(bool);
83 |
84 | public Q_SLOTS:
85 | /// Set current color
86 | void setColor(const QColor &c);
87 |
88 | /// Set the comparison color
89 | void setComparisonColor(const QColor &c);
90 |
91 | Q_SIGNALS:
92 | /// Emitted when the user clicks on the widget
93 | void clicked();
94 |
95 | /// Emitted on setColor
96 | void colorChanged(QColor);
97 |
98 | void comparisonColorChanged(QColor);
99 | void displayModeChanged(DisplayMode);
100 | void backgroundChanged(const QBrush&);
101 | void drawFrameChanged(bool);
102 | protected:
103 | void paintEvent(QPaintEvent *);
104 | void resizeEvent(QResizeEvent *);
105 | void mouseReleaseEvent(QMouseEvent *ev);
106 | void mouseMoveEvent(QMouseEvent *ev);
107 |
108 | private:
109 | class Private;
110 | Private * const p;
111 | };
112 |
113 | } // namespace color_widgets
114 | Q_DECLARE_METATYPE(color_widgets::ColorPreview::DisplayMode)
115 |
116 | #endif // COLOR_PREVIEW_HPP
117 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/gradient_editor.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file gradient_editor.hpp
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef GRADIENT_EDITOR_HPP
23 | #define GRADIENT_EDITOR_HPP
24 |
25 | #include "colorwidgets_global.hpp"
26 |
27 | #include
28 | #include
29 |
30 | namespace color_widgets {
31 |
32 | class ColorDialog;
33 |
34 | /**
35 | * \brief A slider that moves on top of a gradient
36 | */
37 | class QCP_EXPORT GradientEditor : public QWidget
38 | {
39 | Q_OBJECT
40 | Q_PROPERTY(QBrush background READ background WRITE setBackground NOTIFY backgroundChanged)
41 | Q_PROPERTY(QGradientStops stops READ stops WRITE setStops NOTIFY stopsChanged)
42 | Q_PROPERTY(QLinearGradient gradient READ gradient WRITE setGradient)
43 | Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
44 | Q_PROPERTY(int selectedStop READ selectedStop WRITE setSelectedStop NOTIFY selectedStopChanged)
45 | Q_PROPERTY(QColor selectedColor READ selectedColor WRITE setSelectedColor)
46 |
47 | public:
48 | explicit GradientEditor(QWidget *parent = 0);
49 | explicit GradientEditor(Qt::Orientation orientation, QWidget *parent = 0);
50 | ~GradientEditor();
51 |
52 | QSize sizeHint() const override;
53 |
54 | /// Get the background, it's visible for transparent gradient stops
55 | QBrush background() const;
56 | /// Set the background, it's visible for transparent gradient stops
57 | void setBackground(const QBrush &bg);
58 |
59 | /// Get the colors that make up the gradient
60 | QGradientStops stops() const;
61 | /// Set the colors that make up the gradient
62 | void setStops(const QGradientStops &colors);
63 |
64 | /// Get the gradient
65 | QLinearGradient gradient() const;
66 | /// Set the gradient
67 | void setGradient(const QLinearGradient &gradient);
68 |
69 | Qt::Orientation orientation() const;
70 |
71 | /**
72 | * \brief Dialog shown when double clicking a stop
73 | */
74 | ColorDialog* dialog() const;
75 |
76 | /**
77 | * \brief Index of the currently selected gradient stop (or -1 if there is no selection)
78 | */
79 | int selectedStop() const;
80 |
81 | /**
82 | * \brief Color of the selected stop
83 | */
84 | QColor selectedColor() const;
85 |
86 | public Q_SLOTS:
87 | void setOrientation(Qt::Orientation);
88 | void setSelectedStop(int stop);
89 | void setSelectedColor(const QColor& color);
90 | void addStop();
91 | void removeStop();
92 |
93 | Q_SIGNALS:
94 | void backgroundChanged(const QBrush&);
95 | void stopsChanged(const QGradientStops&);
96 | void selectedStopChanged(int);
97 |
98 | protected:
99 | void paintEvent(QPaintEvent *ev) override;
100 |
101 | void mousePressEvent(QMouseEvent *ev) override;
102 | void mouseMoveEvent(QMouseEvent *ev) override;
103 | void mouseReleaseEvent(QMouseEvent *ev) override;
104 | void leaveEvent(QEvent * event) override;
105 | void mouseDoubleClickEvent(QMouseEvent *event) override;
106 |
107 | void dragEnterEvent(QDragEnterEvent *event) override;
108 | void dragMoveEvent(QDragMoveEvent* event) override;
109 | void dragLeaveEvent(QDragLeaveEvent *event) override;
110 | void dropEvent(QDropEvent* event) override;
111 |
112 | private Q_SLOTS:
113 | void dialogUpdate(const QColor& c);
114 |
115 | private:
116 | class Private;
117 | Private * const p;
118 | };
119 |
120 | } // namespace color_widgets
121 |
122 | #endif // GRADIENT_EDITOR_HPP
123 |
124 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/src/QtColorWidgets/hue_slider.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2014 Calle Laakkonen
7 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
8 | * \copyright Copyright (C) 2017 caryoscelus
9 | *
10 | * This program is free software: you can redistribute it and/or modify
11 | * it under the terms of the GNU Lesser General Public License as published by
12 | * the Free Software Foundation, either version 3 of the License, or
13 | * (at your option) any later version.
14 | *
15 | * This program is distributed in the hope that it will be useful,
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | * GNU Lesser General Public License for more details.
19 | *
20 | * You should have received a copy of the GNU Lesser General Public License
21 | * along with this program. If not, see .
22 | *
23 | */
24 | #include "QtColorWidgets/hue_slider.hpp"
25 |
26 | namespace color_widgets {
27 |
28 | class HueSlider::Private
29 | {
30 | private:
31 | HueSlider *w;
32 |
33 | public:
34 | qreal saturation = 1;
35 | qreal value = 1;
36 | qreal alpha = 1;
37 |
38 | Private(HueSlider *widget)
39 | : w(widget)
40 | {
41 | w->setRange(0, 359);
42 | connect(w, &QSlider::valueChanged, [this]{
43 | Q_EMIT w->colorHueChanged(w->colorHue());
44 | Q_EMIT w->colorChanged(w->color());
45 | });
46 | updateGradient();
47 | }
48 |
49 | void updateGradient()
50 | {
51 | static const double n_colors = 6;
52 | QGradientStops colors;
53 | colors.reserve(n_colors+1);
54 | for ( int i = 0; i <= n_colors; ++i )
55 | colors.append(QGradientStop(i/n_colors, QColor::fromHsvF(i/n_colors, saturation, value)));
56 | w->setColors(colors);
57 | }
58 | };
59 |
60 | HueSlider::HueSlider(QWidget *parent) :
61 | GradientSlider(parent), p(new Private(this))
62 | {
63 | }
64 |
65 | HueSlider::HueSlider(Qt::Orientation orientation, QWidget *parent) :
66 | GradientSlider(orientation, parent), p(new Private(this))
67 | {
68 | }
69 |
70 | HueSlider::~HueSlider()
71 | {
72 | delete p;
73 | }
74 |
75 | qreal HueSlider::colorSaturation() const
76 | {
77 | return p->saturation;
78 | }
79 |
80 | void HueSlider::setColorSaturation(qreal s)
81 | {
82 | p->saturation = qBound(0.0, s, 1.0);
83 | p->updateGradient();
84 | Q_EMIT colorSaturationChanged(s);
85 | }
86 |
87 | qreal HueSlider::colorValue() const
88 | {
89 | return p->value;
90 | }
91 |
92 | void HueSlider::setColorValue(qreal v)
93 | {
94 | p->value = qBound(0.0, v, 1.0);
95 | p->updateGradient();
96 | Q_EMIT colorValueChanged(v);
97 | }
98 |
99 | qreal HueSlider::colorAlpha() const
100 | {
101 | return p->alpha;
102 | }
103 |
104 | void HueSlider::setColorAlpha(qreal alpha)
105 | {
106 | p->alpha = alpha;
107 | p->updateGradient();
108 | Q_EMIT colorAlphaChanged(alpha);
109 | }
110 |
111 | QColor HueSlider::color() const
112 | {
113 | return QColor::fromHsvF(colorHue(), p->saturation, p->value, p->alpha);
114 | }
115 |
116 | void HueSlider::setColor(const QColor& color)
117 | {
118 | p->saturation = color.saturationF();
119 | p->value = color.valueF();
120 | p->updateGradient();
121 | setColorHue(color.hueF());
122 | Q_EMIT colorValueChanged(p->alpha);
123 | Q_EMIT colorSaturationChanged(p->alpha);
124 | }
125 |
126 | void HueSlider::setFullColor(const QColor& color)
127 | {
128 | p->alpha = color.alphaF();
129 | setColor(color);
130 | Q_EMIT colorAlphaChanged(p->alpha);
131 | }
132 |
133 | qreal HueSlider::colorHue() const
134 | {
135 | if (maximum() == minimum())
136 | return 0;
137 | auto hue = qreal(value() - minimum()) / (maximum() - minimum());
138 | if (orientation() == Qt::Vertical)
139 | hue = 1 - hue;
140 | return hue;
141 | }
142 |
143 | void HueSlider::setColorHue(qreal colorHue)
144 | {
145 | // TODO: consider supporting invertedAppearance?
146 | if (orientation() == Qt::Vertical)
147 | colorHue = 1 - colorHue;
148 | setValue(minimum()+colorHue*(maximum()-minimum()));
149 | Q_EMIT colorHueChanged(colorHue);
150 | Q_EMIT colorChanged(color());
151 | }
152 |
153 | } // namespace color_widgets
154 |
--------------------------------------------------------------------------------
/utility.h:
--------------------------------------------------------------------------------
1 | #ifndef UTILITY_H
2 | #define UTILITY_H
3 |
4 | float myasin(float x);
5 | float myacos(float x);
6 | float mysqrt(float x);
7 | float mylog(float x);
8 |
9 | #include
10 | #include "vec3.h"
11 | #include "my_util.h"
12 | #include
13 | using namespace std;
14 |
15 |
16 | struct TripleSegment {
17 | int a, b, c, d, e, f;
18 | double w_ab, w_cd, w_ef;
19 | TripleSegment(int a_, int b_, int c_, int d_, int e_, int f_, double w_ab_ = 0, double w_cd_ = 0, double w_ef_ = 0) {
20 | a = a_, b = b_, c = c_, d = d_, e = e_, f = f_;
21 | w_ab = w_ab_, w_cd = w_cd_, w_ef = w_ef_;
22 | }
23 | TripleSegment() {
24 | a = b = c = d = e = f = w_ab = w_cd = w_ef = 0;
25 | }
26 | };
27 |
28 | class myfloat3
29 | {
30 | public:
31 | explicit myfloat3();
32 | explicit myfloat3(float x, float y, float z);
33 | const float norm2() const;
34 | const float norm() const;
35 | float dot(myfloat3 another);
36 | myfloat3 cross(myfloat3 another);
37 |
38 | const myfloat3 operator +(const myfloat3 another) const;
39 | const myfloat3 operator -(const myfloat3 another) const;
40 |
41 | const myfloat3 operator *(float x) const;
42 | const myfloat3 operator /(float x) const;
43 |
44 | float getX() const;
45 | float getY() const;
46 | float getZ() const;
47 |
48 | friend float dot(myfloat3 x, myfloat3 y);
49 | friend myfloat3 cross(myfloat3 x, myfloat3 y);
50 |
51 | private:
52 | float x, y, z;
53 | };
54 |
55 | class Triangle {
56 | public:
57 | vec3 p, q, r;
58 |
59 | Triangle() {}
60 | Triangle(vec3 v1_, vec3 v2_, vec3 v3_) {
61 | p = v1_;
62 | q = v2_;
63 | r = v3_;
64 | }
65 | };
66 |
67 | class int3 {
68 | public:
69 | int x, y, z;
70 | int3(int x_ = 0, int y_ = 0, int z_ = 0) {
71 | x = x_;
72 | y = y_;
73 | z = z_;
74 | }
75 | int operator[] (int idx) {
76 | if (idx == 0)
77 | return x;
78 | else if (idx == 1)
79 | return y;
80 | else if (idx == 2)
81 | return z;
82 | }
83 | };
84 |
85 | class Polyhedron {
86 | public:
87 | vector faces;
88 | vector vertices;
89 | vector current_vertices;
90 | vector correspondences;
91 |
92 | Polyhedron(){}
93 | Polyhedron(vector& verts, vector& fs, vector& corres) {
94 | faces = fs;
95 | vertices = verts;
96 | current_vertices = verts;
97 | correspondences = corres;
98 | }
99 | };
100 |
101 | class int2 {
102 | public:
103 | int u, v;
104 | int2() { u = 0, v = 0; }
105 | int2(int u_, int v_) {
106 | u = u_;
107 | v = v_;
108 | }
109 | int operator[] (int idx) const {
110 | if (idx == 0)
111 | return u;
112 | else if (idx == 1)
113 | return v;
114 | }
115 | };
116 |
117 | class vec4 {
118 | public:
119 | float v[4];
120 | vec4(){}
121 | vec4(float a, float b, float c, float d) {
122 | v[0] = a;
123 | v[1] = b;
124 | v[2] = c;
125 | v[3] = d;
126 | }
127 | float operator[] (int idx) const {
128 | return v[idx];
129 | }
130 |
131 | vec4 operator*(float mul) const {
132 | return vec4(v[0] * mul, v[1] * mul, v[2] * mul, v[3] * mul);
133 | }
134 | vec4 operator+(const vec4 &another) const {
135 | return vec4(
136 | v[0] + another.v[0],
137 | v[1] + another.v[1],
138 | v[2] + another.v[2],
139 | v[3] + another.v[3]
140 | );
141 | }
142 | vec4 operator-(const vec4 &another) const {
143 | return vec4(
144 | v[0] - another.v[0],
145 | v[1] - another.v[1],
146 | v[2] - another.v[2],
147 | v[3] - another.v[3]
148 | );
149 | }
150 | };
151 |
152 | class VideoPalette {
153 | public:
154 | vector edges;
155 | vector vertices;
156 | void clear() {
157 | edges.clear();
158 | vertices.clear();
159 | }
160 | };
161 |
162 | vec3 closesPointOnTriangle(const vec3 *triangle, const vec3 &sourcePosition);
163 |
164 | bool cut(double time, vec4 p, vec4 q, double &r, double &g, double &b);
165 | void RGBtoHSV(double src_r, double src_g, double src_b, double &dst_h, double &dst_s, double &dst_v);
166 |
167 | double norm2(double x, double y, double z);
168 | void cross(double x1, double y1, double z1, double x2, double y2, double z2, double &x, double &y, double &z);
169 | double angle(double x1, double y1, double z1, double x2, double y2, double z2);
170 | double dot(double x1, double y1, double z1, double x2, double y2, double z2);
171 |
172 | #endif // UTILITY_H
173 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/src/QtColorWidgets/color_list_widget.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #include "QtColorWidgets/color_list_widget.hpp"
23 | #include "QtColorWidgets/color_selector.hpp"
24 |
25 | namespace color_widgets {
26 |
27 | class ColorListWidget::Private
28 | {
29 | public:
30 | QList colors;
31 | QSignalMapper mapper;
32 | ColorWheel::ShapeEnum wheel_shape = ColorWheel::ShapeTriangle;
33 | ColorWheel::ColorSpaceEnum color_space = ColorWheel::ColorHSV;
34 | bool wheel_rotating = true;
35 | };
36 |
37 | ColorListWidget::ColorListWidget(QWidget *parent)
38 | : AbstractWidgetList(parent), p(new Private)
39 | {
40 | connect(this, &AbstractWidgetList::removed, this, &ColorListWidget::handle_removed);
41 | connect(&p->mapper, SIGNAL(mapped(int)), SLOT(color_changed(int)));
42 | }
43 |
44 | ColorListWidget::~ColorListWidget()
45 | {
46 | delete p;
47 | }
48 |
49 | QList ColorListWidget::colors() const
50 | {
51 | return p->colors;
52 | }
53 |
54 | void ColorListWidget::setColors(const QList &colors)
55 | {
56 | clear();
57 | p->colors = colors;
58 | for(int i = 0;i < colors.size();i++ )
59 | append_widget(i);
60 | Q_EMIT colorsChanged(colors);
61 | }
62 |
63 | void ColorListWidget::swap(int a, int b)
64 | {
65 | ColorSelector* sa = widget_cast(a);
66 | ColorSelector* sb = widget_cast(b);
67 | if ( sa && sb )
68 | {
69 | QColor ca = sa->color();
70 | sa->setColor(sb->color());
71 | sb->setColor(ca);
72 | Q_EMIT colorsChanged(p->colors);
73 | }
74 | }
75 |
76 | void ColorListWidget::append()
77 | {
78 | p->colors.push_back(Qt::black);
79 | append_widget(p->colors.size()-1);
80 | Q_EMIT colorsChanged(p->colors);
81 | }
82 |
83 | void ColorListWidget::emit_changed()
84 | {
85 | Q_EMIT colorsChanged(p->colors);
86 | }
87 |
88 | void ColorListWidget::handle_removed(int i)
89 | {
90 | p->colors.removeAt(i);
91 | Q_EMIT colorsChanged(p->colors);
92 | }
93 |
94 | void ColorListWidget::color_changed(int row)
95 | {
96 | ColorSelector *cs = widget_cast(row);
97 | if ( cs )
98 | {
99 | p->colors[row] = cs->color();
100 | Q_EMIT colorsChanged(p->colors);
101 | }
102 | }
103 |
104 | void ColorListWidget::append_widget(int col)
105 | {
106 | ColorSelector* cbs = new ColorSelector;
107 | cbs->setDisplayMode(ColorPreview::AllAlpha);
108 | cbs->setColor(p->colors[col]);
109 | //connect(cbs,SIGNAL(colorChanged(QColor)),SLOT(emit_changed()));
110 | p->mapper.setMapping(cbs,col);
111 | connect(cbs,SIGNAL(colorChanged(QColor)),&p->mapper,SLOT(map()));
112 | connect(this, &ColorListWidget::wheelRotatingChanged, cbs, &ColorSelector::setWheelRotating);
113 | connect(this, &ColorListWidget::wheelShapeChanged, cbs, &ColorSelector::setWheelShape);
114 | connect(this, &ColorListWidget::colorSpaceChanged, cbs, &ColorSelector::setColorSpace);
115 | appendWidget(cbs);
116 | setRowHeight(count()-1,22);
117 | }
118 |
119 | void ColorListWidget::setWheelShape(ColorWheel::ShapeEnum shape)
120 | {
121 | Q_EMIT wheelShapeChanged(p->wheel_shape = shape);
122 | }
123 |
124 | ColorWheel::ShapeEnum ColorListWidget::wheelShape() const
125 | {
126 | return p->wheel_shape;
127 | }
128 |
129 | void ColorListWidget::setColorSpace(ColorWheel::ColorSpaceEnum space)
130 | {
131 | Q_EMIT colorSpaceChanged(p->color_space = space);
132 | }
133 |
134 | ColorWheel::ColorSpaceEnum ColorListWidget::colorSpace() const
135 | {
136 | return p->color_space;
137 | }
138 |
139 | void ColorListWidget::setWheelRotating(bool rotating)
140 | {
141 | Q_EMIT wheelRotatingChanged(p->wheel_rotating = rotating);
142 | }
143 |
144 | bool ColorListWidget::wheelRotating() const
145 | {
146 | return p->wheel_rotating;
147 | }
148 |
149 | } // namespace color_widgets
150 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/src/QtColorWidgets/color_delegate.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #include "QtColorWidgets/color_delegate.hpp"
23 | #include "QtColorWidgets/color_selector.hpp"
24 | #include "QtColorWidgets/color_dialog.hpp"
25 | #include
26 | #include
27 | #include
28 |
29 | namespace color_widgets {
30 |
31 | ColorDelegate::ColorDelegate(QWidget *parent) :
32 | QStyledItemDelegate(parent)
33 | {
34 | }
35 |
36 | void ColorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
37 | const QModelIndex &index) const
38 | {
39 | if ( index.data().type() == QVariant::Color )
40 | {
41 | QStyleOptionFrame panel;
42 | panel.initFrom(option.widget);
43 | if (option.widget->isEnabled())
44 | panel.state = QStyle::State_Enabled;
45 | panel.rect = option.rect;
46 | panel.lineWidth = 2;
47 | panel.midLineWidth = 0;
48 | panel.state |= QStyle::State_Sunken;
49 | option.widget->style()->drawPrimitive(QStyle::PE_Frame, &panel, painter, nullptr);
50 | QRect r = option.widget->style()->subElementRect(QStyle::SE_FrameContents, &panel, nullptr);
51 | painter->fillRect(r, index.data().value());
52 | }
53 | else
54 | {
55 | QStyledItemDelegate::paint(painter, option, index);
56 | }
57 | }
58 |
59 | QSize ColorDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
60 | {
61 | if ( index.data().type() == QVariant::Color )
62 | return QSize(24,16);
63 | return QStyledItemDelegate::sizeHint(option, index);
64 | }
65 |
66 | QWidget *ColorDelegate::createEditor(QWidget *parent,
67 | const QStyleOptionViewItem &option,
68 | const QModelIndex &index) const
69 | {
70 | if ( index.data().type() == QVariant::Color )
71 | {
72 | ColorDialog *editor = new ColorDialog(const_cast(parent));
73 | connect(editor, &QDialog::accepted, this, &ColorDelegate::close_editor);
74 | connect(editor, &ColorDialog::colorSelected, this, &ColorDelegate::color_changed);
75 | return editor;
76 | }
77 |
78 | return QStyledItemDelegate::createEditor(parent, option, index);
79 | }
80 |
81 | void ColorDelegate::color_changed()
82 | {
83 | ColorDialog *editor = qobject_cast(sender());
84 | emit commitData(editor);
85 | }
86 |
87 | void ColorDelegate::close_editor()
88 | {
89 | ColorDialog *editor = qobject_cast(sender());
90 | emit closeEditor(editor);
91 | }
92 |
93 | void ColorDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
94 | {
95 |
96 | if ( index.data().type() == QVariant::Color )
97 | {
98 | ColorDialog *selector = qobject_cast(editor);
99 | selector->setColor(qvariant_cast(index.data()));
100 | return;
101 | }
102 |
103 | QStyledItemDelegate::setEditorData(editor, index);
104 | }
105 |
106 | void ColorDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
107 | const QModelIndex &index) const
108 | {
109 | if ( index.data().type() == QVariant::Color )
110 | {
111 | ColorDialog *selector = qobject_cast(editor);
112 | model->setData(index, QVariant::fromValue(selector->color()));
113 | return;
114 | }
115 |
116 | QStyledItemDelegate::setModelData(editor, model, index);
117 | }
118 |
119 | void ColorDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
120 | const QModelIndex &index) const
121 | {
122 | if ( index.data().type() == QVariant::Color )
123 | {
124 | return;
125 | }
126 |
127 |
128 | QStyledItemDelegate::updateEditorGeometry(editor, option, index);
129 |
130 | }
131 |
132 | } // namespace color_widgets
133 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/color_palette_model.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef COLOR_WIDGETS_COLOR_PALETTE_MODEL_HPP
23 | #define COLOR_WIDGETS_COLOR_PALETTE_MODEL_HPP
24 |
25 | #include
26 | #include "color_palette.hpp"
27 |
28 | namespace color_widgets {
29 |
30 | class QCP_EXPORT ColorPaletteModel : public QAbstractListModel
31 | {
32 | Q_OBJECT
33 | /**
34 | * \brief List of directories to be scanned for palette files
35 | */
36 | Q_PROPERTY(QStringList searchPaths READ searchPaths WRITE setSearchPaths NOTIFY searchPathsChanged)
37 |
38 | /**
39 | * \brief Default directory to be used when saving a palette
40 | */
41 | Q_PROPERTY(QString savePath READ savePath WRITE setSavePath NOTIFY savePathChanged)
42 |
43 | /**
44 | * \brief Size of the icon used for the palette previews
45 | */
46 | Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize NOTIFY iconSizeChanged)
47 |
48 |
49 | public:
50 | ColorPaletteModel();
51 | ~ColorPaletteModel();
52 | int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
53 | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
54 | bool removeRows(int row, int count, const QModelIndex & parent = QModelIndex()) Q_DECL_OVERRIDE;
55 |
56 | QString savePath() const;
57 | QStringList searchPaths() const;
58 | QSize iconSize() const;
59 |
60 | /**
61 | * \brief Number of palettes
62 | */
63 | int count() const;
64 |
65 | /**
66 | * \brief Returns a reference to the first palette with the given name
67 | * \pre hasPalette(name)
68 | */
69 | const ColorPalette& palette(const QString& name) const;
70 |
71 | /**
72 | * \brief Whether a palette with the given name exists in the model
73 | */
74 | bool hasPalette(const QString& name) const;
75 |
76 | /**
77 | * \brief Get the palette at the given index (row)
78 | * \pre 0 <= index < count()
79 | */
80 | const ColorPalette& palette(int index) const;
81 |
82 | /**
83 | * \brief Updates an existing palette
84 | * \param index Palette index
85 | * \param palette New palette
86 | * \param save Whether to save the palette to the filesystem
87 | *
88 | * Saving will try: (in this order)
89 | * * To overwrite the file pointed by the old palette
90 | * * To write to the new palette file name
91 | * * To create a file in the save path
92 | * If all of the above fail, the palette will be replaced interally
93 | * but not on the filesystem
94 | *
95 | * \returns \b true if the palette has been successfully updated (and saved)
96 | */
97 | bool updatePalette(int index, const ColorPalette& palette, bool save = true);
98 |
99 | /**
100 | * \brief Remove a palette from the model and optionally from the filesystem
101 | * \returns \b true if the palette has been successfully removed
102 | */
103 | bool removePalette(int index, bool remove_file = true);
104 |
105 | /**
106 | * \brief Remove a palette to the model and optionally to the filesystem
107 | * \returns \b true if the palette has been successfully added
108 | */
109 | bool addPalette(const ColorPalette& palette, bool save = true);
110 |
111 | /**
112 | * \brief The index of the palette with the given file name
113 | * \returns -1 if none is found
114 | */
115 | int indexFromFile(const QString& filename) const;
116 |
117 | public Q_SLOTS:
118 | void setSavePath(const QString& savePath);
119 | void setSearchPaths(const QStringList& searchPaths);
120 | void addSearchPath(const QString& path);
121 | void setIconSize(const QSize& iconSize);
122 |
123 | /**
124 | * \brief Load palettes files found in the search paths
125 | */
126 | void load();
127 |
128 | Q_SIGNALS:
129 | void savePathChanged(const QString& savePath);
130 | void searchPathsChanged(const QStringList& searchPaths);
131 | void iconSizeChanged(const QSize& iconSize);
132 |
133 | private:
134 | class Private;
135 | Private* p;
136 | };
137 |
138 | } // namespace color_widgets
139 |
140 | #endif // COLOR_WIDGETS_COLOR_PALETTE_MODEL_HPP
141 |
--------------------------------------------------------------------------------
/rgbwidget.cpp:
--------------------------------------------------------------------------------
1 | #include "rgbwidget.h"
2 | #include
3 | #include
4 | #include
5 | #include"utility.h"
6 | #include
7 |
8 | // Widget shows a RGB view
9 |
10 | RGBWidget::RGBWidget():sharedMemory("RGBWidget")
11 | {
12 | QTimer *timer = new QTimer(this);
13 | if (!sharedMemory.attach())
14 | {
15 | sharedMemory.create(sizeof(float[3]));
16 | }
17 |
18 | connect(timer, &QTimer::timeout, [=]() {
19 | sharedMemory.lock();
20 | const float *data = (float*)sharedMemory.constData();
21 | rotate_x = data[0];
22 | rotate_y = data[1];
23 | rotate_z = data[2];
24 | sharedMemory.unlock();
25 | update();
26 | });
27 | timer->start(40);
28 |
29 | }
30 |
31 | void RGBWidget::paintGL()
32 | {
33 | OpenGL3DWidget::paintGL();
34 |
35 | Polyhedron poly = data->GetPalette();
36 |
37 |
38 | glLineWidth(1.f);
39 | glBegin(GL_LINES);
40 |
41 | for (int p = 0; p <= 1; p++)
42 | for (int r = 0; r <= 1; r++)
43 | {
44 | double q = p - .5;
45 | double s = r - .5;
46 |
47 | glColor3f(p, r, 0.);
48 | glVertex3f(q, s, -.5);
49 | glColor3f(p, r, 1.);
50 | glVertex3f(q, s, .5);
51 | glColor3f(p, 0., r);
52 | glVertex3f(q, -.5, s);
53 | glColor3f(p, 1., r);
54 | glVertex3f(q, .5, s);
55 | glColor3f(0., p, r);
56 | glVertex3f(-.5, q, s);
57 | glColor3f(1., p, r);
58 | glVertex3f(.5, q, s);
59 | }
60 |
61 | glEnd();
62 |
63 | if (data == nullptr) return;
64 |
65 | int width = data->GetFrameWidth();
66 | int height = data->GetFrameHeight();
67 | int depth = data->GetFrameDepth();
68 | double *video = data->GetImage();
69 |
70 | int n_vertex = 0;
71 | int n_line = 0;
72 | int n_face = 0;
73 |
74 | //auto face = data->getFace();
75 |
76 | const double *vertex = nullptr;
77 | const int *line = nullptr;
78 |
79 | if (showImageData)
80 | {
81 | QRandomGenerator rng;
82 |
83 | glPointSize(2.f);
84 | glBegin(GL_POINTS);
85 |
86 | for (int i = 0; i < width * height; i++)
87 | {
88 | if (rng.bounded(1.) > preview) continue;
89 |
90 | double *p = video + time * width * height * depth + i * depth;
91 | double r = p[0], g = p[1], b = p[2];
92 |
93 | glColor3f(r, g, b);
94 | glVertex3f(r - .5, g - .5, b - .5);
95 | }
96 |
97 | glEnd();
98 | }
99 |
100 | glPointSize(10.f);
101 | glBegin(GL_POINTS);
102 |
103 | vector vertices = poly.vertices;
104 |
105 | for (int i = 0; i < vertices.size(); i++)
106 | {
107 | vec3 p = vertices[i];
108 |
109 | double r = p[0], g = p[1], b = p[2];
110 | glColor3f(r, g, b);
111 | glVertex3f(r - .5, g - .5, b - .5);
112 | }
113 |
114 | glEnd();
115 |
116 | glLineWidth(3.f);
117 | glBegin(GL_LINES);
118 |
119 | int fcnt = poly.faces.size();
120 |
121 | for (int i = 0; i < fcnt; i++)
122 | {
123 | int vid1 = poly.faces[i].x;
124 | int vid2 = poly.faces[i].y;
125 | int vid3 = poly.faces[i].z;
126 |
127 | vec3 p = poly.vertices[vid1];
128 | vec3 q = poly.vertices[vid2];
129 | vec3 r = poly.vertices[vid3];
130 |
131 | double center[3] = {
132 | (p[0] + q[0] + r[0]) / 3.,
133 | (p[1] + q[1] + r[1]) / 3.,
134 | (p[2] + q[2] + r[2]) / 3.,
135 | };
136 |
137 | glColor3f(p[0], p[1], p[2]);
138 | glVertex3f(p[0] - .5, p[1] - .5, p[2] - .5);
139 |
140 | glColor3f(q[0], q[1], q[2]);
141 | glVertex3f(q[0] - .5, q[1] - .5, q[2] - .5);
142 |
143 | glColor3f(p[0], p[1], p[2]);
144 | glVertex3f(p[0] - .5, p[1] - .5, p[2] - .5);
145 |
146 | glColor3f(r[0], r[1], r[2]);
147 | glVertex3f(r[0] - .5, r[1] - .5, r[2] - .5);
148 |
149 | glColor3f(q[0], q[1], q[2]);
150 | glVertex3f(q[0] - .5, q[1] - .5, q[2] - .5);
151 |
152 | glColor3f(r[0], r[1], r[2]);
153 | glVertex3f(r[0] - .5, r[1] - .5, r[2] - .5);
154 |
155 | glColor3f(center[0], center[1], center[2]);
156 |
157 | double d1[3] = {
158 | q[0] - p[0],
159 | q[1] - p[1],
160 | q[2] - p[2],
161 | };
162 | double d2[3] = {
163 | r[0] - p[0],
164 | r[1] - p[1],
165 | r[2] - p[2],
166 | };
167 | double n[3] = {
168 | d1[1] * d2[2] - d1[2] * d2[1],
169 | d1[2] * d2[0] - d1[0] * d2[2],
170 | d1[0] * d2[1] - d1[1] * d2[0],
171 | };
172 |
173 | double norm = n[0] * n[0] + n[1] * n[1] + n[2] * n[2];
174 |
175 | qDebug() << "DEBUG norm" << norm;
176 |
177 | /*
178 | if (norm > 1e-6)
179 | {
180 | double k = 0.1 / sqrt(norm);
181 | n[0] *= k;
182 | n[1] *= k;
183 | n[2] *= k;
184 |
185 | glColor3f(center[0], center[1], center[2]);
186 | glVertex3f(center[0] - .5, center[1] - .5, center[2] - .5);
187 |
188 | glColor3f(center[0], center[1], center[2]);
189 | glVertex3f(center[0] + n[0] - .5, center[1] + n[1] - .5, center[2] + n[2] - .5);
190 | }
191 | */
192 | }
193 | glEnd();
194 | glFlush();
195 | this->makeCurrent();
196 | }
197 |
198 | void RGBWidget::mouseMoveEvent(QMouseEvent *event)
199 | {
200 | OpenGL3DWidget::mouseMoveEvent(event);
201 | sharedMemory.lock();
202 | float *data = (float*)sharedMemory.data();
203 | data[0] = rotate_x;
204 | data[1] = rotate_y;
205 | data[2] = rotate_z;
206 | sharedMemory.unlock();
207 | }
208 |
209 | double RGBWidget::_rotate_x = 15.;
210 | double RGBWidget::_rotate_y = -70.;
211 | double RGBWidget::_rotate_z = 0.;
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/color_dialog.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef COLOR_DIALOG_HPP
23 | #define COLOR_DIALOG_HPP
24 |
25 | #include "colorwidgets_global.hpp"
26 | #include "color_preview.hpp"
27 | #include "color_wheel.hpp"
28 |
29 |
30 | #include
31 |
32 | class QAbstractButton;
33 |
34 | namespace color_widgets {
35 |
36 | class QCP_EXPORT ColorDialog : public QDialog
37 | {
38 | Q_OBJECT
39 | Q_ENUMS(ButtonMode)
40 | Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged DESIGNABLE true)
41 | Q_PROPERTY(ColorWheel::ShapeEnum wheelShape READ wheelShape WRITE setWheelShape NOTIFY wheelShapeChanged)
42 | Q_PROPERTY(ColorWheel::ColorSpaceEnum colorSpace READ colorSpace WRITE setColorSpace NOTIFY colorSpaceChanged)
43 | Q_PROPERTY(bool wheelRotating READ wheelRotating WRITE setWheelRotating NOTIFY wheelRotatingChanged)
44 | /**
45 | * \brief whether the color alpha channel can be edited.
46 | *
47 | * If alpha is disabled, the selected color's alpha will always be 255.
48 | */
49 | Q_PROPERTY(bool alphaEnabled READ alphaEnabled WRITE setAlphaEnabled NOTIFY alphaEnabledChanged)
50 |
51 | public:
52 | enum ButtonMode {
53 | OkCancel,
54 | OkApplyCancel,
55 | Close
56 | };
57 |
58 | explicit ColorDialog(QWidget *parent = 0, Qt::WindowFlags f = 0);
59 |
60 | ~ColorDialog();
61 |
62 | /**
63 | * Get currently selected color
64 | */
65 | QColor color() const;
66 |
67 | /**
68 | * Set the display mode for the color preview
69 | */
70 | void setPreviewDisplayMode(ColorPreview::DisplayMode mode);
71 |
72 | /**
73 | * Get the color preview diplay mode
74 | */
75 | ColorPreview::DisplayMode previewDisplayMode() const;
76 |
77 | bool alphaEnabled() const;
78 |
79 | /**
80 | * Select which dialog buttons to show
81 | *
82 | * There are three predefined modes:
83 | * OkCancel - this is useful when the dialog is modal and we just want to return a color
84 | * OkCancelApply - this is for non-modal dialogs
85 | * Close - for non-modal dialogs with direct color updates via colorChanged signal
86 | */
87 | void setButtonMode(ButtonMode mode);
88 | ButtonMode buttonMode() const;
89 |
90 | QSize sizeHint() const;
91 |
92 | ColorWheel::ShapeEnum wheelShape() const;
93 | ColorWheel::ColorSpaceEnum colorSpace() const;
94 | bool wheelRotating() const;
95 |
96 | public Q_SLOTS:
97 |
98 | /**
99 | * Change color
100 | */
101 | void setColor(const QColor &c);
102 |
103 | /**
104 | * Set the current color and show the dialog
105 | */
106 | void showColor(const QColor &oldcolor);
107 |
108 | void setWheelShape(ColorWheel::ShapeEnum shape);
109 | void setColorSpace(ColorWheel::ColorSpaceEnum space);
110 | void setWheelRotating(bool rotating);
111 | void getCurrentColor();
112 |
113 | /**
114 | * Set whether the color alpha channel can be edited.
115 | * If alpha is disabled, the selected color's alpha will always be 255.
116 | */
117 | void setAlphaEnabled(bool a);
118 |
119 | Q_SIGNALS:
120 | /**
121 | * The current color was changed
122 | */
123 | void colorChanged(QColor);
124 |
125 | /**
126 | * The user selected the new color by pressing Ok/
127 |
128 | */
129 | void colorSelected(QColor);
130 |
131 | void wheelShapeChanged(ColorWheel::ShapeEnum shape);
132 | void colorSpaceChanged(ColorWheel::ColorSpaceEnum space);
133 | void wheelRotatingChanged(bool rotating);
134 |
135 | void alphaEnabledChanged(bool alphaEnabled);
136 |
137 | void sendColor(QColor c);
138 |
139 | private Q_SLOTS:
140 | /// Update all the Ui elements to match the selected color
141 | void setColorInternal(const QColor &color);
142 | /// Update from HSV sliders
143 | void set_hsv();
144 | /// Update from RGB sliders
145 | void set_rgb();
146 | /// Update from Alpha slider
147 | void set_alpha();
148 |
149 | void on_edit_hex_colorChanged(const QColor& color);
150 | void on_edit_hex_colorEditingFinished(const QColor& color);
151 |
152 | void on_buttonBox_clicked(QAbstractButton*);
153 |
154 | protected:
155 | void dragEnterEvent(QDragEnterEvent *event);
156 | void dropEvent(QDropEvent * event);
157 | void mouseReleaseEvent(QMouseEvent *event);
158 | void mouseMoveEvent(QMouseEvent *event);
159 |
160 | private:
161 | class Private;
162 | Private * const p;
163 | };
164 |
165 | } // namespace color_widgets
166 |
167 | #endif // COLOR_DIALOG_HPP
168 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/gradient_list_model.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef COLOR_WIDGETS_GRADIENT_LIST_MODEL_HPP
23 | #define COLOR_WIDGETS_GRADIENT_LIST_MODEL_HPP
24 |
25 | #include "colorwidgets_global.hpp"
26 |
27 | #include
28 | #include
29 | #include
30 |
31 | namespace color_widgets {
32 |
33 | class QCP_EXPORT GradientListModel : public QAbstractListModel
34 | {
35 | Q_OBJECT
36 |
37 | /**
38 | * \brief Size of the icon used for the gradient previews
39 | */
40 | Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize NOTIFY iconSizeChanged)
41 |
42 | Q_PROPERTY(ItemEditMode editMode READ editMode WRITE setEditMode NOTIFY editModeChanged)
43 |
44 | public:
45 | enum ItemEditMode
46 | {
47 | EditNone = 0,
48 | EditName,
49 | EditGradient,
50 | };
51 |
52 | Q_ENUM(ItemEditMode);
53 |
54 | GradientListModel(QObject *parent = nullptr);
55 | ~GradientListModel();
56 | int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
57 | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
58 | Qt::ItemFlags flags(const QModelIndex & index) const Q_DECL_OVERRIDE;
59 | bool setData(const QModelIndex & index, const QVariant & value, int role) Q_DECL_OVERRIDE;
60 |
61 | QSize iconSize() const;
62 |
63 | /**
64 | * \brief Number of gradients
65 | */
66 | int count() const;
67 |
68 | /**
69 | * \brief Remove all gradients
70 | */
71 | void clear();
72 |
73 | /**
74 | * \brief Returns a reference to the first gradient with the given name
75 | * \pre hasGradient(name)
76 | */
77 | const QLinearGradient& gradient(const QString& name) const;
78 |
79 | /**
80 | * \brief Returns a reference to the first gradient with the given name
81 | * \pre hasGradient(name)
82 | */
83 | QGradientStops gradientStops(const QString& name) const;
84 |
85 | /**
86 | * \brief Whether a gradient with the given name exists in the model
87 | */
88 | bool hasGradient(const QString& name) const;
89 |
90 | /**
91 | * \brief Get the gradient at the given index (row)
92 | * \pre 0 <= index < count()
93 | */
94 | const QLinearGradient& gradient(int index) const;
95 |
96 | /**
97 | * \brief Get the gradient stops at the given index (row)
98 | * \pre 0 <= index < count()
99 | */
100 | QGradientStops gradientStops(int index) const;
101 |
102 | /**
103 | * \brief Inserts or updates a gradient
104 | * \returns The index for the new gradient
105 | */
106 | int setGradient(const QString& name, const QGradient& gradient);
107 |
108 | int setGradient(const QString& name, const QGradientStops& gradient);
109 |
110 | /**
111 | * \brief Updates the gradient at \p index
112 | */
113 | bool setGradient(int index, const QGradient& gradient);
114 |
115 | bool setGradient(int index, const QGradientStops& gradient);
116 |
117 | /**
118 | * \brief Renames the gradient at \p index
119 | * \returns \b true on success
120 | */
121 | bool rename(int index, const QString& new_name);
122 |
123 | /**
124 | * \brief Renames a gradient
125 | * \returns \b true on success
126 | */
127 | bool rename(const QString& old_name, const QString& new_name);
128 |
129 | /**
130 | * \brief Remove a gradient from the model
131 | * \returns \b true if the gradient has been successfully removed
132 | */
133 | bool removeGradient(const QString& name);
134 |
135 |
136 | bool removeGradient(int index);
137 |
138 | /**
139 | * \brief The index of the gradient with the given name
140 | * \returns -1 if none is found
141 | */
142 | int indexFromName(const QString& name) const;
143 |
144 | /**
145 | * \brief Name of the gradient at index
146 | */
147 | QString nameFromIndex(int index) const;
148 |
149 | ItemEditMode editMode() const;
150 |
151 | /**
152 | * \brief Brush for a gradient
153 | * \pre 0 <= \p index < count()
154 | */
155 | QBrush gradientBrush(int index) const;
156 |
157 | public Q_SLOTS:
158 | void setIconSize(const QSize& iconSize);
159 | void setEditMode(ItemEditMode mode);
160 |
161 | Q_SIGNALS:
162 | void iconSizeChanged(const QSize& iconSize);
163 | void editModeChanged(ItemEditMode mode);
164 |
165 | private:
166 | class Private;
167 | std::unique_ptr d;
168 | };
169 |
170 | } // namespace color_widgets
171 |
172 | #endif // COLOR_WIDGETS_GRADIENT_LIST_MODEL_HPP
173 |
174 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/src/QtColorWidgets/color_selector.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #include "QtColorWidgets/color_selector.hpp"
23 | #include "QtColorWidgets/color_dialog.hpp"
24 | #include
25 | #include
26 | #include
27 |
28 | namespace color_widgets {
29 |
30 | class ColorSelector::Private
31 | {
32 | public:
33 | UpdateMode update_mode;
34 | ColorDialog *dialog;
35 | QColor old_color;
36 |
37 | Private(QWidget *widget) : dialog(new ColorDialog(widget))
38 | {
39 | dialog->setButtonMode(ColorDialog::OkCancel);
40 | }
41 | };
42 |
43 | ColorSelector::ColorSelector(QWidget *parent) :
44 | ColorPreview(parent), p(new Private(this))
45 | {
46 | setUpdateMode(Continuous);
47 | p->old_color = color();
48 |
49 | connect(this,&ColorPreview::clicked,this,&ColorSelector::showDialog);
50 | connect(this,SIGNAL(colorChanged(QColor)),this,SLOT(update_old_color(QColor)));
51 | connect(p->dialog,&QDialog::rejected,this,&ColorSelector::reject_dialog);
52 | connect(p->dialog,&ColorDialog::colorSelected, this, &ColorSelector::accept_dialog);
53 |
54 | connect(p->dialog, &ColorDialog::wheelRotatingChanged, this, &ColorSelector::wheelRotatingChanged);
55 | connect(p->dialog, &ColorDialog::wheelShapeChanged, this, &ColorSelector::wheelShapeChanged);
56 | connect(p->dialog, &ColorDialog::colorSpaceChanged, this, &ColorSelector::colorSpaceChanged);
57 |
58 | setAcceptDrops(true);
59 | }
60 |
61 | ColorSelector::~ColorSelector()
62 | {
63 | delete p;
64 | }
65 |
66 | ColorSelector::UpdateMode ColorSelector::updateMode() const
67 | {
68 | return p->update_mode;
69 | }
70 |
71 | void ColorSelector::setUpdateMode(UpdateMode m)
72 | {
73 | p->update_mode = m;
74 | Q_EMIT updateModeChanged(m);
75 | }
76 |
77 | Qt::WindowModality ColorSelector::dialogModality() const
78 | {
79 | return p->dialog->windowModality();
80 | }
81 |
82 | void ColorSelector::setDialogModality(Qt::WindowModality m)
83 | {
84 | p->dialog->setWindowModality(m);
85 | Q_EMIT dialogModalityChanged(m);
86 | }
87 |
88 | void ColorSelector::setWheelShape(ColorWheel::ShapeEnum shape)
89 | {
90 | p->dialog->setWheelShape(shape);
91 | }
92 |
93 | ColorWheel::ShapeEnum ColorSelector::wheelShape() const
94 | {
95 | return p->dialog->wheelShape();
96 | }
97 |
98 | void ColorSelector::setColorSpace(ColorWheel::ColorSpaceEnum space)
99 | {
100 | p->dialog->setColorSpace(space);
101 | }
102 |
103 | ColorWheel::ColorSpaceEnum ColorSelector::colorSpace() const
104 | {
105 | return p->dialog->colorSpace();
106 | }
107 |
108 | void ColorSelector::setWheelRotating(bool rotating)
109 | {
110 | p->dialog->setWheelRotating(rotating);
111 | }
112 |
113 | bool ColorSelector::wheelRotating() const
114 | {
115 | return p->dialog->wheelRotating();
116 | }
117 |
118 | void ColorSelector::showDialog()
119 | {
120 | p->old_color = color();
121 | p->dialog->setColor(color());
122 | connect_dialog();
123 | p->dialog->show();
124 | }
125 |
126 |
127 | void ColorSelector::connect_dialog()
128 | {
129 | if (p->update_mode == Continuous)
130 | connect(p->dialog, SIGNAL(colorChanged(QColor)), this, SLOT(setColor(QColor)), Qt::UniqueConnection);
131 | else
132 | disconnect_dialog();
133 | }
134 |
135 | void ColorSelector::disconnect_dialog()
136 | {
137 | disconnect(p->dialog, SIGNAL(colorChanged(QColor)), this, SLOT(setColor(QColor)));
138 | }
139 |
140 | void ColorSelector::accept_dialog()
141 | {
142 | setColor(p->dialog->color());
143 | p->old_color = color();
144 | Q_EMIT colorSelected(color());
145 | }
146 |
147 | void ColorSelector::reject_dialog()
148 | {
149 | setColor(p->old_color);
150 | }
151 |
152 | void ColorSelector::update_old_color(const QColor &c)
153 | {
154 | if (!p->dialog->isVisible())
155 | p->old_color = c;
156 | }
157 |
158 | void ColorSelector::dragEnterEvent(QDragEnterEvent *event)
159 | {
160 | if ( event->mimeData()->hasColor() ||
161 | ( event->mimeData()->hasText() && QColor(event->mimeData()->text()).isValid() ) )
162 | event->acceptProposedAction();
163 | }
164 |
165 |
166 | void ColorSelector::dropEvent(QDropEvent *event)
167 | {
168 | if ( event->mimeData()->hasColor() )
169 | {
170 | setColor(event->mimeData()->colorData().value());
171 | event->accept();
172 | }
173 | else if ( event->mimeData()->hasText() )
174 | {
175 | QColor col(event->mimeData()->text());
176 | if ( col.isValid() )
177 | {
178 | setColor(col);
179 | event->accept();
180 | }
181 | }
182 | }
183 |
184 | } // namespace color_widgets
185 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/src/QtColorWidgets/abstract_widget_list.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #include "QtColorWidgets/abstract_widget_list.hpp"
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | class AbstractWidgetList::Private
29 | {
30 | public:
31 | QList widgets;
32 | QSignalMapper mapper_up;
33 | QSignalMapper mapper_down;
34 | QSignalMapper mapper_remove;
35 | QTableWidget *table;
36 | };
37 |
38 | AbstractWidgetList::AbstractWidgetList(QWidget *parent) :
39 | QWidget(parent), p(new Private)
40 | {
41 | connect(&p->mapper_up,SIGNAL(mapped(QWidget*)),SLOT(up_clicked(QWidget*)));
42 | connect(&p->mapper_down,SIGNAL(mapped(QWidget*)),SLOT(down_clicked(QWidget*)));
43 | connect(&p->mapper_remove,SIGNAL(mapped(QWidget*)),SLOT(remove_clicked(QWidget*)));
44 |
45 |
46 | QVBoxLayout *verticalLayout = new QVBoxLayout(this);
47 | verticalLayout->setContentsMargins(0, 0, 0, 0);
48 | p->table = new QTableWidget(this);
49 | verticalLayout->addWidget(p->table);
50 |
51 |
52 | p->table->insertColumn(0);
53 | p->table->insertColumn(1);
54 | p->table->insertColumn(2);
55 | p->table->insertColumn(3);
56 |
57 | p->table->setColumnWidth(0,128);
58 | p->table->setColumnWidth(1,24);
59 | p->table->setColumnWidth(2,24);
60 | p->table->setColumnWidth(3,24);
61 |
62 | p->table->horizontalHeader()->hide();
63 | p->table->verticalHeader()->hide();
64 | p->table->setShowGrid(false);
65 |
66 | QPushButton* add_button = new QPushButton(QIcon::fromTheme(QStringLiteral("list-add")),
67 | tr("Add New"));
68 |
69 | verticalLayout->addWidget(add_button);
70 | connect(add_button,&QAbstractButton::clicked,this, &AbstractWidgetList::append);
71 |
72 | }
73 |
74 | AbstractWidgetList::~AbstractWidgetList()
75 | {
76 | delete p;
77 | }
78 |
79 | int AbstractWidgetList::count() const
80 | {
81 | return p->widgets.size();
82 | }
83 |
84 | void AbstractWidgetList::setRowHeight(int row, int height)
85 | {
86 | p->table->setRowHeight(row,height);
87 | }
88 |
89 | void AbstractWidgetList::clear()
90 | {
91 | p->widgets.clear();
92 | while(p->table->rowCount() > 0)
93 | p->table->removeRow(0);
94 | }
95 |
96 |
97 | void AbstractWidgetList::remove(int i)
98 | {
99 | if ( isValidRow(i) )
100 | {
101 | p->widgets.removeAt(i);
102 | p->table->removeRow(i);
103 | if ( i == 0 && !p->widgets.isEmpty() )
104 | p->table->cellWidget(0,1)->setEnabled(false);
105 | else if ( i != 0 && i == count() )
106 | p->table->cellWidget(count()-1,2)->setEnabled(false);
107 |
108 | Q_EMIT removed(i);
109 | }
110 | }
111 |
112 |
113 | void AbstractWidgetList::appendWidget(QWidget *w)
114 | {
115 | int row = count();
116 | p->table->insertRow(row);
117 |
118 | QWidget* b_up = create_button(w,&p->mapper_up,QStringLiteral("go-up"),tr("Move Up"));
119 | QWidget* b_down = create_button(w,&p->mapper_down,QStringLiteral("go-down"),tr("Move Down"));
120 | QWidget* b_remove = create_button(w,&p->mapper_remove,QStringLiteral("list-remove"),tr("Remove"));
121 | if ( row == 0 )
122 | b_up->setEnabled(false);
123 | else
124 | p->table->cellWidget(row-1,2)->setEnabled(true);
125 | b_down->setEnabled(false);
126 |
127 | p->table->setCellWidget(row,0,w);
128 | p->table->setCellWidget(row,1,b_up);
129 | p->table->setCellWidget(row,2,b_down);
130 | p->table->setCellWidget(row,3,b_remove);
131 |
132 | p->widgets.push_back(w);
133 | }
134 |
135 | QWidget *AbstractWidgetList::widget(int i)
136 | {
137 | if ( isValidRow(i) )
138 | return p->widgets[i];
139 | return 0;
140 | }
141 |
142 |
143 | QWidget *AbstractWidgetList::create_button(QWidget *data, QSignalMapper *mapper,
144 | QString icon_name,
145 | QString text, QString tooltip) const
146 | {
147 |
148 | QToolButton* btn = new QToolButton;
149 | btn->setIcon(QIcon::fromTheme(icon_name));
150 | btn->setText(text);
151 | btn->setToolTip(tooltip.isNull() ? btn->text() : tooltip );
152 | connect(btn,SIGNAL(clicked()),mapper,SLOT(map()));
153 | mapper->setMapping(btn,data);
154 | return btn;
155 | }
156 |
157 | void AbstractWidgetList::remove_clicked(QWidget *w)
158 | {
159 | int row = p->widgets.indexOf(w);
160 | remove(row);
161 | }
162 |
163 | void AbstractWidgetList::up_clicked(QWidget *w)
164 | {
165 | int row = p->widgets.indexOf(w);
166 | if ( row > 0 )
167 | swap(row,row-1);
168 | }
169 |
170 | void AbstractWidgetList::down_clicked(QWidget *w)
171 | {
172 | int row = p->widgets.indexOf(w);
173 | if ( row+1 < count() )
174 | swap(row,row+1);
175 | }
176 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/src/QtColorWidgets/color_preview.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | * \copyright Copyright (C) 2014 Calle Laakkonen
8 | *
9 | * This program is free software: you can redistribute it and/or modify
10 | * it under the terms of the GNU Lesser General Public License as published by
11 | * the Free Software Foundation, either version 3 of the License, or
12 | * (at your option) any later version.
13 | *
14 | * This program is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | * GNU Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public License
20 | * along with this program. If not, see .
21 | *
22 | */
23 | #include "QtColorWidgets/color_preview.hpp"
24 |
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 |
31 | namespace color_widgets {
32 |
33 | class ColorPreview::Private
34 | {
35 | public:
36 | QColor col; ///< color to be viewed
37 | QColor comparison; ///< comparison color
38 | QBrush back;///< Background brush, visible on a transparent color
39 | DisplayMode display_mode; ///< How the color(s) are to be shown
40 | bool draw_frame = true; ///< Whether to draw a frame around the color
41 |
42 | Private() : col(Qt::red), back(Qt::darkGray, Qt::DiagCrossPattern), display_mode(NoAlpha)
43 | {}
44 | };
45 |
46 | ColorPreview::ColorPreview(QWidget *parent) :
47 | QWidget(parent), p(new Private)
48 | {
49 | p->back.setTexture(QPixmap(QStringLiteral(":/color_widgets/alphaback.png")));
50 | }
51 |
52 | ColorPreview::~ColorPreview()
53 | {
54 | delete p;
55 | }
56 |
57 | void ColorPreview::setBackground(const QBrush &bk)
58 | {
59 | p->back = bk;
60 | update();
61 | Q_EMIT backgroundChanged(bk);
62 | }
63 |
64 | QBrush ColorPreview::background() const
65 | {
66 | return p->back;
67 | }
68 |
69 | ColorPreview::DisplayMode ColorPreview::displayMode() const
70 | {
71 | return p->display_mode;
72 | }
73 |
74 | void ColorPreview::setDisplayMode(DisplayMode m)
75 | {
76 | p->display_mode = m;
77 | update();
78 | Q_EMIT displayModeChanged(m);
79 | }
80 |
81 | QColor ColorPreview::color() const
82 | {
83 | return p->col;
84 | }
85 |
86 | QColor ColorPreview::comparisonColor() const
87 | {
88 | return p->comparison;
89 | }
90 |
91 | QSize ColorPreview::sizeHint() const
92 | {
93 | return QSize(24,24);
94 | }
95 |
96 | void ColorPreview::paint(QPainter &painter, QRect rect) const
97 | {
98 | QColor c1, c2;
99 | switch(p->display_mode) {
100 | case DisplayMode::NoAlpha:
101 | c1 = c2 = p->col.rgb();
102 | break;
103 | case DisplayMode::AllAlpha:
104 | c1 = c2 = p->col;
105 | break;
106 | case DisplayMode::SplitAlpha:
107 | c1 = p->col.rgb();
108 | c2 = p->col;
109 | break;
110 | case DisplayMode::SplitColor:
111 | c1 = p->comparison;
112 | c2 = p->col;
113 | break;
114 | case DisplayMode::SplitColorReverse:
115 | c1 = p->col;
116 | c2 = p->comparison;
117 | break;
118 | }
119 |
120 | if ( p->draw_frame )
121 | {
122 | QStyleOptionFrame panel;
123 | panel.initFrom(this);
124 | panel.lineWidth = 2;
125 | panel.midLineWidth = 0;
126 | panel.state |= QStyle::State_Sunken;
127 | style()->drawPrimitive(QStyle::PE_Frame, &panel, &painter, this);
128 | QRect r = style()->subElementRect(QStyle::SE_FrameContents, &panel, this);
129 | painter.setClipRect(r);
130 | }
131 |
132 | if ( c1.alpha() < 255 || c2.alpha() < 255 )
133 | painter.fillRect(0, 0, rect.width(), rect.height(), p->back);
134 |
135 | int w = rect.width() / 2;
136 | int h = rect.height();
137 | painter.fillRect(0, 0, w, h, c1);
138 | painter.fillRect(w, 0, w, h, c2);
139 | }
140 |
141 | void ColorPreview::setColor(const QColor &c)
142 | {
143 | p->col = c;
144 | update();
145 | Q_EMIT colorChanged(c);
146 | }
147 |
148 | void ColorPreview::setComparisonColor(const QColor &c)
149 | {
150 | p->comparison = c;
151 | update();
152 | Q_EMIT comparisonColorChanged(c);
153 | }
154 |
155 | void ColorPreview::paintEvent(QPaintEvent *)
156 | {
157 | QStylePainter painter(this);
158 |
159 | paint(painter, geometry());
160 | }
161 |
162 | void ColorPreview::resizeEvent(QResizeEvent *)
163 | {
164 | update();
165 | }
166 |
167 | void ColorPreview::mouseReleaseEvent(QMouseEvent * ev)
168 | {
169 | if ( QRect(QPoint(0,0),size()).contains(ev->pos()) )
170 | Q_EMIT clicked();
171 | }
172 |
173 | void ColorPreview::mouseMoveEvent(QMouseEvent *ev)
174 | {
175 |
176 | if ( ev->buttons() &Qt::LeftButton && !QRect(QPoint(0,0),size()).contains(ev->pos()) )
177 | {
178 | QMimeData *data = new QMimeData;
179 |
180 | data->setColorData(p->col);
181 |
182 | QDrag* drag = new QDrag(this);
183 | drag->setMimeData(data);
184 |
185 | QPixmap preview(24,24);
186 | preview.fill(p->col);
187 | drag->setPixmap(preview);
188 |
189 | drag->exec();
190 | }
191 | }
192 |
193 | bool ColorPreview::drawFrame() const
194 | {
195 | return p->draw_frame;
196 | }
197 |
198 | void ColorPreview::setDrawFrame(bool draw)
199 | {
200 | Q_EMIT drawFrameChanged(p->draw_frame = draw);
201 | update();
202 | }
203 |
204 | } // namespace color_widgets
205 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/color_wheel.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef COLOR_WHEEL_HPP
23 | #define COLOR_WHEEL_HPP
24 |
25 | #include
26 |
27 | #include "colorwidgets_global.hpp"
28 |
29 |
30 | namespace color_widgets {
31 |
32 | /**
33 | * \brief Display an analog widget that allows the selection of a HSV color
34 | *
35 | * It has an outer wheel to select the Hue and an intenal square to select
36 | * Saturation and Lightness.
37 | */
38 | class QCP_EXPORT ColorWheel : public QWidget
39 | {
40 | Q_OBJECT
41 |
42 | Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged DESIGNABLE true STORED false )
43 | Q_PROPERTY(qreal hue READ hue WRITE setHue DESIGNABLE false )
44 | Q_PROPERTY(qreal saturation READ saturation WRITE setSaturation DESIGNABLE false )
45 | Q_PROPERTY(qreal value READ value WRITE setValue DESIGNABLE false )
46 | Q_PROPERTY(unsigned wheelWidth READ wheelWidth WRITE setWheelWidth NOTIFY wheelWidthChanged DESIGNABLE true )
47 | Q_PROPERTY(ShapeEnum selectorShape READ selectorShape WRITE setSelectorShape NOTIFY selectorShapeChanged DESIGNABLE true )
48 | Q_PROPERTY(bool rotatingSelector READ rotatingSelector WRITE setRotatingSelector NOTIFY rotatingSelectorChanged DESIGNABLE true )
49 | Q_PROPERTY(ColorSpaceEnum colorSpace READ colorSpace WRITE setColorSpace NOTIFY colorSpaceChanged DESIGNABLE true )
50 |
51 | public:
52 | enum ShapeEnum
53 | {
54 | ShapeTriangle, ///< A triangle
55 | ShapeSquare, ///< A square
56 | };
57 |
58 | enum AngleEnum
59 | {
60 | AngleFixed, ///< The inner part doesn't rotate
61 | AngleRotating, ///< The inner part follows the hue selector
62 | };
63 |
64 | enum ColorSpaceEnum
65 | {
66 | ColorHSV, ///< Use the HSV color space
67 | ColorHSL, ///< Use the HSL color space
68 | ColorLCH, ///< Use Luma Chroma Hue (Y_601')
69 | };
70 |
71 | Q_ENUM(ShapeEnum);
72 | Q_ENUM(AngleEnum);
73 | Q_ENUM(ColorSpaceEnum);
74 |
75 | explicit ColorWheel(QWidget *parent = 0);
76 | ~ColorWheel();
77 |
78 | /// Get current color
79 | QColor color() const;
80 |
81 | virtual QSize sizeHint() const Q_DECL_OVERRIDE;
82 |
83 | /// Get current hue in the range [0-1]
84 | qreal hue() const;
85 |
86 | /// Get current saturation in the range [0-1]
87 | qreal saturation() const;
88 |
89 | /// Get current value in the range [0-1]
90 | qreal value() const;
91 |
92 | /// Get the width in pixels of the outer wheel
93 | unsigned int wheelWidth() const;
94 |
95 | /// Set the width in pixels of the outer wheel
96 | void setWheelWidth(unsigned int w);
97 |
98 | /// Shape of the internal selector
99 | ShapeEnum selectorShape() const;
100 |
101 | /// Whether the internal selector should rotare in accordance with the hue
102 | bool rotatingSelector() const;
103 |
104 | /// Color space used to preview/edit the color
105 | ColorSpaceEnum colorSpace() const;
106 |
107 | public Q_SLOTS:
108 |
109 | /// Set current color
110 | void setColor(QColor c);
111 |
112 | /**
113 | * @param h Hue [0-1]
114 | */
115 | void setHue(qreal h);
116 |
117 | /**
118 | * @param s Saturation [0-1]
119 | */
120 | void setSaturation(qreal s);
121 |
122 | /**
123 | * @param v Value [0-1]
124 | */
125 | void setValue(qreal v);
126 |
127 | /// Sets the shape of the internal selector
128 | void setSelectorShape(ShapeEnum shape);
129 |
130 | /// Sets whether the internal selector should rotare in accordance with the hue
131 | void setRotatingSelector(bool rotating);
132 |
133 | /// Sets the color space used to preview/edit the color
134 | void setColorSpace(ColorSpaceEnum space);
135 |
136 | Q_SIGNALS:
137 | /**
138 | * Emitted when the user selects a color or setColor is called
139 | */
140 | void colorChanged(QColor);
141 |
142 | /**
143 | * Emitted when the user selects a color
144 | */
145 | void colorSelected(QColor);
146 |
147 | void wheelWidthChanged(unsigned);
148 |
149 | void selectorShapeChanged(ShapeEnum shape);
150 |
151 | void rotatingSelectorChanged(bool rotating);
152 |
153 | void colorSpaceChanged(ColorSpaceEnum space);
154 |
155 | protected:
156 | void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
157 | void mouseMoveEvent(QMouseEvent *) Q_DECL_OVERRIDE;
158 | void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE;
159 | void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE;
160 | void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE;
161 | void dragEnterEvent(QDragEnterEvent* event) Q_DECL_OVERRIDE;
162 | void dropEvent(QDropEvent* event) Q_DECL_OVERRIDE;
163 |
164 | protected:
165 | class Private;
166 | ColorWheel(QWidget *parent, Private* data);
167 | Private* data() const { return p; }
168 |
169 | private:
170 | Private * const p;
171 |
172 | };
173 |
174 | } // namespace color_widgets
175 |
176 | #endif // COLOR_WHEEL_HPP
177 |
--------------------------------------------------------------------------------
/vec3.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by YILI WANG on 3/11/19.
3 | //
4 |
5 | #ifndef PALEfloatfloatE_EDIfloat_VEC3_H
6 | #define PALEfloatfloatE_EDIfloat_VEC3_H
7 |
8 | #include "utility.h"
9 |
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | class vec3
18 | {
19 | public:
20 |
21 | vec3(float x_, float y_, float z_) { v[0] = x_; v[1] = y_; v[2] = z_; }
22 |
23 | vec3(const vec3 & p)
24 | {
25 | v[0] = (float)(p[0]);
26 | v[1] = (float)(p[1]);
27 | v[2] = (float)(p[2]);
28 | }
29 |
30 | vec3() { v[0] = 0; v[1] = 0; v[2] = 0; }
31 |
32 | inline float x() const { return v[0]; }
33 | inline float y() const { return v[1]; }
34 | inline float z() const { return v[2]; }
35 |
36 | inline float operator [] (unsigned int c) const
37 | {
38 | return v[c];
39 | }
40 | inline float & operator [] (unsigned int c)
41 | {
42 | return v[c];
43 | }
44 |
45 | static vec3 Zero() { return vec3(0, 0, 0); }
46 |
47 | void setZero()
48 | {
49 | v[0] = 0;
50 | v[1] = 0;
51 | v[2] = 0;
52 | }
53 |
54 | void operator = (const vec3 & other)
55 | {
56 | v[0] = other.x();
57 | v[1] = other.y();
58 | v[2] = other.z();
59 | }
60 |
61 | void operator += (const vec3 & other)
62 | {
63 | v[0] += other.x();
64 | v[1] += other.y();
65 | v[2] += other.z();
66 | }
67 |
68 | void operator -= (const vec3 & other)
69 | {
70 | v[0] -= other.x();
71 | v[1] -= other.y();
72 | v[2] -= other.z();
73 | }
74 |
75 | // floathis is going to create problems if the compiler needs to resolve umbiguous casts, but it's the cleaner way to do it
76 | void operator *= (int s)
77 | {
78 | v[0] *= s;
79 | v[1] *= s;
80 | v[2] *= s;
81 | }
82 | void operator *= (unsigned int s)
83 | {
84 | v[0] *= s;
85 | v[1] *= s;
86 | v[2] *= s;
87 | }
88 | void operator *= (float s)
89 | {
90 | v[0] *= s;
91 | v[1] *= s;
92 | v[2] *= s;
93 | }
94 | void operator *= (double s)
95 | {
96 | v[0] *= s;
97 | v[1] *= s;
98 | v[2] *= s;
99 | }
100 | void operator /= (int s)
101 | {
102 | v[0] /= s;
103 | v[1] /= s;
104 | v[2] /= s;
105 | }
106 | void operator /= (unsigned int s)
107 | {
108 | v[0] /= s;
109 | v[1] /= s;
110 | v[2] /= s;
111 | }
112 | void operator /= (float s)
113 | {
114 | v[0] /= s;
115 | v[1] /= s;
116 | v[2] /= s;
117 | }
118 | void operator /= (double s)
119 | {
120 | v[0] /= s;
121 | v[1] /= s;
122 | v[2] /= s;
123 | }
124 |
125 | vec3 getOrthogonal() const
126 | {
127 | if (v[0] == 0)
128 | {
129 | return vec3(0, v[2], -v[1]);
130 | }
131 | else if (v[1] == 0)
132 | {
133 | return vec3(v[2], 0, -v[0]);
134 | }
135 |
136 | return vec3(v[1], -v[0], 0);
137 | }
138 |
139 |
140 | float sqrnorm() const
141 | {
142 | return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
143 | }
144 |
145 | float norm() const
146 | {
147 | return mysqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
148 | }
149 |
150 | void normalize()
151 | {
152 | float _n = norm();
153 | v[0] /= _n;
154 | v[1] /= _n;
155 | v[2] /= _n;
156 | }
157 |
158 | //float dot(const vec3& anotherVec) const {
159 | // return ::dot(*this,anotherVec);
160 | //}
161 | operator QString() const {
162 | QString result;
163 | QTextStream(&result) << "vec3(" << v[0] << ", " << v[1] << ", " << v[2] << ")";
164 | return result;
165 | }
166 |
167 | private:
168 | float v[3];
169 | };
170 |
171 |
172 |
173 |
174 | inline
175 | float dot(const vec3 & p1, const vec3 & p2)
176 | {
177 | return p1.x() * p2.x() + p1.y() * p2.y() + p1.z() * p2.z();
178 | }
179 | inline
180 | vec3 cross(const vec3 & p1, const vec3 & p2) {
181 | return vec3(
182 | p1.y() * p2.z() - p1.z() * p2.y(),
183 | p1.z() * p2.x() - p1.x() * p2.z(),
184 | p1.x() * p2.y() - p1.y() * p2.x()
185 | );
186 | }
187 |
188 | inline
189 | vec3 operator + (const vec3 & p1, const vec3 & p2)
190 | {
191 | return vec3(p1.x() + p2.x(), p1.y() + p2.y(), p1.z() + p2.z());
192 | }
193 | inline
194 | vec3 operator - (const vec3 & p1, const vec3 & p2)
195 | {
196 | return vec3(p1.x() - p2.x(), p1.y() - p2.y(), p1.z() - p2.z());
197 | }
198 |
199 |
200 | inline
201 | vec3 operator - (const vec3 & p2)
202 | {
203 | return vec3(-p2.x(), -p2.y(), -p2.z());
204 | }
205 |
206 | inline
207 | vec3 operator * (const vec3 & p, int s)
208 | {
209 | return vec3(s*p.x(), s*p.y(), s*p.z());
210 | }
211 | inline
212 | vec3 operator * (const vec3 & p, float s)
213 | {
214 | return vec3(s*p.x(), s*p.y(), s*p.z());
215 | }
216 | inline
217 | vec3 operator * (const vec3 & p, double s)
218 | {
219 | return vec3(s*p.x(), s*p.y(), s*p.z());
220 | }
221 | inline
222 | vec3 operator * (int s, const vec3 & p)
223 | {
224 | return vec3(s*p.x(), s*p.y(), s*p.z());
225 | }
226 | inline
227 | vec3 operator * (float s, const vec3 & p)
228 | {
229 | return vec3(s*p.x(), s*p.y(), s*p.z());
230 | }
231 | inline
232 | vec3 operator * (double s, const vec3 & p)
233 | {
234 | return vec3(s*p.x(), s*p.y(), s*p.z());
235 | }
236 |
237 |
238 | inline
239 | vec3 operator / (const vec3 & p, int s)
240 | {
241 | return vec3(p.x() / s, p.y() / s, p.z() / s);
242 | }
243 | inline
244 | vec3 operator / (const vec3 & p, float s)
245 | {
246 | return vec3(p.x() / s, p.y() / s, p.z() / s);
247 | }
248 | inline
249 | vec3 operator / (const vec3 & p, double s)
250 | {
251 | return vec3(p.x() / s, p.y() / s, p.z() / s);
252 | }
253 |
254 |
255 | inline
256 | float operator * (const vec3 & p1, const vec3 & p2)
257 | {
258 | return p1.x() * p2.x() + p1.y() * p2.y() + p1.z() * p2.z();
259 | }
260 |
261 |
262 | inline
263 | vec3 operator % (const vec3 & p1, const vec3 & p2)
264 | {
265 | return cross(p1, p2);
266 | }
267 |
268 |
269 | inline std::ostream & operator << (std::ostream & s, vec3 const & p)
270 | {
271 | s << p[0] << " \t" << p[1] << " \t" << p[2];
272 | return s;
273 | }
274 |
275 |
276 | #endif //PALEfloatfloatE_EDIfloat_VEC3_H
277 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/src/QtColorWidgets/color_line_edit.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | * \copyright Copyright (C) 2017 caryoscelus
8 | *
9 | * This program is free software: you can redistribute it and/or modify
10 | * it under the terms of the GNU Lesser General Public License as published by
11 | * the Free Software Foundation, either version 3 of the License, or
12 | * (at your option) any later version.
13 | *
14 | * This program is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | * GNU Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public License
20 | * along with this program. If not, see .
21 | *
22 | */
23 | #include "QtColorWidgets/color_line_edit.hpp"
24 |
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | #include "QtColorWidgets/color_utils.hpp"
33 | #include "QtColorWidgets/color_names.hpp"
34 |
35 | namespace color_widgets {
36 |
37 |
38 | class ColorLineEdit::Private
39 | {
40 | public:
41 | QColor color;
42 | bool show_alpha = false;
43 | bool preview_color = false;
44 | QBrush background;
45 |
46 | bool customAlpha()
47 | {
48 | return preview_color && show_alpha && color.alpha() < 255;
49 | }
50 |
51 | void setPalette(const QColor& color, ColorLineEdit* parent)
52 | {
53 | if ( preview_color )
54 | {
55 | QColor bg = customAlpha() ? Qt::transparent : color;
56 | QColor text = detail::color_lumaF(color) > 0.5 || color.alphaF() < 0.2 ? Qt::black : Qt::white;
57 | parent->setStyleSheet(
58 | QString("background-color: %1; color: %2;")
59 | .arg(bg.name()).arg(text.name())
60 | );
61 | }
62 | }
63 | };
64 |
65 | ColorLineEdit::ColorLineEdit(QWidget* parent)
66 | : QLineEdit(parent), p(new Private)
67 | {
68 | p->background.setTexture(QPixmap(QStringLiteral(":/color_widgets/alphaback.png")));
69 | setColor(Qt::white);
70 | /// \todo determine if having this connection might be useful
71 | /*connect(this, &QLineEdit::textChanged, [this](const QString& text){
72 | QColor color = p->colorFromString(text);
73 | if ( color.isValid() )
74 | Q_EMIT colorChanged(color);
75 | });*/
76 | connect(this, &QLineEdit::textEdited, [this](const QString& text){
77 | QColor color = color_widgets::colorFromString(text, p->show_alpha);
78 | if ( color.isValid() )
79 | {
80 | p->color = color;
81 | p->setPalette(color, this);
82 | Q_EMIT colorEdited(color);
83 | Q_EMIT colorChanged(color);
84 | }
85 | });
86 | connect(this, &QLineEdit::editingFinished, [this](){
87 | QColor color = color_widgets::colorFromString(text(), p->show_alpha);
88 | if ( color.isValid() )
89 | {
90 | p->color = color;
91 | Q_EMIT colorEditingFinished(color);
92 | Q_EMIT colorChanged(color);
93 | }
94 | else
95 | {
96 | setText(color_widgets::stringFromColor(p->color, p->show_alpha));
97 | Q_EMIT colorEditingFinished(p->color);
98 | Q_EMIT colorChanged(color);
99 | }
100 | p->setPalette(p->color, this);
101 | });
102 | }
103 |
104 | ColorLineEdit::~ColorLineEdit()
105 | {
106 | delete p;
107 | }
108 |
109 | QColor ColorLineEdit::color() const
110 | {
111 | return p->color;
112 | }
113 |
114 | void ColorLineEdit::setColor(const QColor& color)
115 | {
116 | if ( color != p->color )
117 | {
118 | p->color = color;
119 | p->setPalette(p->color, this);
120 | setText(color_widgets::stringFromColor(p->color, p->show_alpha));
121 | Q_EMIT colorChanged(p->color);
122 | }
123 | }
124 |
125 | void ColorLineEdit::setShowAlpha(bool showAlpha)
126 | {
127 | if ( p->show_alpha != showAlpha )
128 | {
129 | p->show_alpha = showAlpha;
130 | p->setPalette(p->color, this);
131 | setText(color_widgets::stringFromColor(p->color, p->show_alpha));
132 | Q_EMIT showAlphaChanged(p->show_alpha);
133 | }
134 | }
135 |
136 | bool ColorLineEdit::showAlpha() const
137 | {
138 | return p->show_alpha;
139 | }
140 |
141 | void ColorLineEdit::dragEnterEvent(QDragEnterEvent *event)
142 | {
143 | if ( isReadOnly() )
144 | return;
145 |
146 | if ( event->mimeData()->hasColor() ||
147 | ( event->mimeData()->hasText() &&
148 | color_widgets::colorFromString(event->mimeData()->text(), p->show_alpha).isValid() ) )
149 | {
150 | event->acceptProposedAction();
151 | }
152 | }
153 |
154 |
155 | void ColorLineEdit::dropEvent(QDropEvent *event)
156 | {
157 | if ( isReadOnly() )
158 | return;
159 |
160 | if ( event->mimeData()->hasColor() )
161 | {
162 | setColor(event->mimeData()->colorData().value());
163 | event->accept();
164 | }
165 | else if ( event->mimeData()->hasText() )
166 | {
167 | QColor col = color_widgets::colorFromString(event->mimeData()->text(), p->show_alpha);
168 | if ( col.isValid() )
169 | {
170 | setColor(col);
171 | event->accept();
172 | }
173 | }
174 | }
175 |
176 | bool ColorLineEdit::previewColor() const
177 | {
178 | return p->preview_color;
179 | }
180 |
181 | void ColorLineEdit::setPreviewColor(bool previewColor)
182 | {
183 | if ( previewColor != p->preview_color )
184 | {
185 | p->preview_color = previewColor;
186 |
187 | if ( p->preview_color )
188 | p->setPalette(p->color, this);
189 | else
190 | setPalette(QApplication::palette());
191 |
192 | Q_EMIT previewColorChanged(p->preview_color);
193 | }
194 | }
195 |
196 | void ColorLineEdit::paintEvent(QPaintEvent* event)
197 | {
198 | if ( p->customAlpha() )
199 | {
200 | QPainter painter(this);
201 | QStyleOptionFrame panel;
202 | initStyleOption(&panel);
203 | QRect r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, nullptr);
204 | painter.fillRect(r, p->background);
205 | painter.fillRect(r, p->color);
206 | }
207 |
208 | QLineEdit::paintEvent(event);
209 | }
210 |
211 | } // namespace color_widgets
212 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/src/QtColorWidgets/color_palette_widget.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | color_widgets::ColorPaletteWidget
4 |
5 |
6 |
7 | 0
8 | 0
9 | 227
10 | 186
11 |
12 |
13 |
14 |
15 | 0
16 |
17 |
18 | 0
19 |
20 |
21 | 0
22 |
23 |
24 | 0
25 |
26 | -
27 |
28 |
-
29 |
30 |
31 |
32 | 0
33 | 0
34 |
35 |
36 |
37 |
38 | -
39 |
40 |
41 |
42 | 0
43 |
44 |
45 | 0
46 |
47 |
48 | 0
49 |
50 |
51 | 0
52 |
53 |
54 | 0
55 |
56 |
-
57 |
58 |
59 | Open a new palette from file
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | -
69 |
70 |
71 | Create a new palette
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | -
81 |
82 |
83 | Duplicate the current palette
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 | -
98 |
99 |
100 | -
101 |
102 |
103 |
104 | 0
105 |
106 |
107 | 0
108 |
109 |
110 | 0
111 |
112 |
113 | 0
114 |
115 |
116 | 0
117 |
118 |
-
119 |
120 |
121 | Delete the current palette
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 | -
131 |
132 |
133 | Revert changes to the current palette
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 | -
143 |
144 |
145 | Save changes to the current palette
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 | -
155 |
156 |
157 | Qt::Horizontal
158 |
159 |
160 |
161 | 40
162 | 20
163 |
164 |
165 |
166 |
167 | -
168 |
169 |
170 | Add a color to the palette
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 | -
180 |
181 |
182 | Remove the selected color from the palette
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 | color_widgets::Swatch
199 | QWidget
200 | QtColorWidgets/swatch.hpp
201 |
202 |
203 |
204 |
205 |
206 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/swatch.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef COLOR_WIDGETS_SWATCH_HPP
23 | #define COLOR_WIDGETS_SWATCH_HPP
24 |
25 | #include
26 | #include
27 | #include "color_palette.hpp"
28 |
29 | namespace color_widgets {
30 |
31 | /**
32 | * \brief A widget drawing a palette
33 | */
34 | class QCP_EXPORT Swatch : public QWidget
35 | {
36 | Q_OBJECT
37 |
38 | /**
39 | * \brief Palette shown by the widget
40 | */
41 | Q_PROPERTY(const ColorPalette& palette READ palette WRITE setPalette NOTIFY paletteChanged)
42 | /**
43 | * \brief Currently selected color (-1 if no color is selected)
44 | */
45 | Q_PROPERTY(int selected READ selected WRITE setSelected NOTIFY selectedChanged)
46 |
47 | /**
48 | * \brief Preferred size for a color square
49 | */
50 | Q_PROPERTY(QSize colorSize READ colorSize WRITE setColorSize NOTIFY colorSizeChanged)
51 |
52 | Q_PROPERTY(ColorSizePolicy colorSizePolicy READ colorSizePolicy WRITE setColorSizePolicy NOTIFY colorSizePolicyChanged)
53 |
54 | /**
55 | * \brief Border around the colors
56 | */
57 | Q_PROPERTY(QPen border READ border WRITE setBorder NOTIFY borderChanged)
58 |
59 | /**
60 | * \brief Forces the Swatch to display that many rows of colors
61 | *
62 | * If there are too few elements, the widget will display less than this
63 | * many rows.
64 | *
65 | * A value of0 means that the number of rows is automatic.
66 | *
67 | * \note Conflicts with forcedColumns
68 | */
69 | Q_PROPERTY(int forcedRows READ forcedRows WRITE setForcedRows NOTIFY forcedRowsChanged)
70 |
71 | /**
72 | * \brief Forces the Swatch to display that many columns of colors
73 | *
74 | * If there are too few elements, the widget will display less than this
75 | * many columns.
76 | *
77 | * A value of 0 means that the number of columns is automatic.
78 | *
79 | * \note Conflicts with forcedRows
80 | */
81 | Q_PROPERTY(int forcedColumns READ forcedColumns WRITE setForcedColumns NOTIFY forcedColumnsChanged)
82 |
83 | /**
84 | * \brief Whether the palette can be modified via user interaction
85 | * \note Even when this is \b false, it can still be altered programmatically
86 | */
87 | Q_PROPERTY(bool readOnly READ readOnly WRITE setReadOnly NOTIFY readOnlyChanged)
88 |
89 |
90 | public:
91 | enum ColorSizePolicy
92 | {
93 | Hint, ///< The size is just a hint
94 | Minimum, ///< Can expand but not contract
95 | Fixed ///< Must be exactly as specified
96 | };
97 | Q_ENUMS(ColorSizePolicy)
98 |
99 | Swatch(QWidget* parent = 0);
100 | ~Swatch();
101 |
102 | QSize sizeHint() const Q_DECL_OVERRIDE;
103 | QSize minimumSizeHint() const Q_DECL_OVERRIDE;
104 |
105 | const ColorPalette& palette() const;
106 | ColorPalette& palette();
107 | int selected() const;
108 | /**
109 | * \brief Color at the currently selected index
110 | */
111 | QColor selectedColor() const;
112 |
113 | /**
114 | * \brief Color index at the given position within the widget
115 | * \param p Point in local coordinates
116 | * \returns -1 if the position doesn't represent any color
117 | */
118 | int indexAt(const QPoint& p);
119 |
120 | /**
121 | * \brief Color at the given position within the widget
122 | * \param p Point in local coordinates
123 | */
124 | QColor colorAt(const QPoint& p);
125 |
126 | QSize colorSize() const;
127 | ColorSizePolicy colorSizePolicy() const;
128 | QPen border() const;
129 |
130 | int forcedRows() const;
131 | int forcedColumns() const;
132 |
133 | bool readOnly() const;
134 |
135 | public Q_SLOTS:
136 | void setPalette(const ColorPalette& palette);
137 | void setSelected(int selected);
138 | void clearSelection();
139 | void setColorSize(const QSize& colorSize);
140 | void setColorSizePolicy(ColorSizePolicy colorSizePolicy);
141 | void setBorder(const QPen& border);
142 | void setForcedRows(int forcedRows);
143 | void setForcedColumns(int forcedColumns);
144 | void setReadOnly(bool readOnly);
145 | /**
146 | * \brief Remove the currently seleceted color
147 | **/
148 | void removeSelected();
149 |
150 | Q_SIGNALS:
151 | void paletteChanged(const ColorPalette& palette);
152 | void selectedChanged(int selected);
153 | void colorSelected(const QColor& color);
154 | void colorSizeChanged(const QSize& colorSize);
155 | void colorSizePolicyChanged(ColorSizePolicy colorSizePolicy);
156 | void doubleClicked(int index);
157 | void rightClicked(int index);
158 | void forcedRowsChanged(int forcedRows);
159 | void forcedColumnsChanged(int forcedColumns);
160 | void readOnlyChanged(bool readOnly);
161 | void borderChanged(const QPen& border);
162 |
163 | protected:
164 | bool event(QEvent* event) Q_DECL_OVERRIDE;
165 |
166 | void paintEvent(QPaintEvent* event) Q_DECL_OVERRIDE;
167 |
168 | void keyPressEvent(QKeyEvent* event) Q_DECL_OVERRIDE;
169 |
170 | void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
171 | void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
172 | void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
173 | void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
174 | void wheelEvent(QWheelEvent* event) Q_DECL_OVERRIDE;
175 |
176 | void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE;
177 | void dragMoveEvent(QDragMoveEvent* event) Q_DECL_OVERRIDE;
178 | void dragLeaveEvent(QDragLeaveEvent *event) Q_DECL_OVERRIDE;
179 | void dropEvent(QDropEvent* event) Q_DECL_OVERRIDE;
180 |
181 | protected Q_SLOTS:
182 | /**
183 | * \brief Connected to the internal palette object to keep eveything consistent
184 | */
185 | void paletteModified();
186 |
187 | private:
188 | class Private;
189 | Private* p;
190 | };
191 |
192 |
193 | } // namespace color_widgets
194 | #endif // COLOR_WIDGETS_SWATCH_HPP
195 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/src/QtColorWidgets/harmony_color_wheel.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | * \copyright Copyright (C) 2017 caryoscelus
8 | *
9 | * This program is free software: you can redistribute it and/or modify
10 | * it under the terms of the GNU Lesser General Public License as published by
11 | * the Free Software Foundation, either version 3 of the License, or
12 | * (at your option) any later version.
13 | *
14 | * This program is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | * GNU Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public License
20 | * along with this program. If not, see .
21 | *
22 | */
23 | #include "QtColorWidgets/color_wheel_private.hpp"
24 | #include "QtColorWidgets/harmony_color_wheel.hpp"
25 |
26 | namespace color_widgets {
27 |
28 | struct RingEditor
29 | {
30 | double hue_diff;
31 | bool editable;
32 | int symmetric_to;
33 | int opposite_to;
34 | RingEditor(double hue_diff, bool editable, int symmetric_to=-1, int opposite_to=-1) :
35 | hue_diff(hue_diff),
36 | editable(editable),
37 | symmetric_to(symmetric_to),
38 | opposite_to(opposite_to)
39 | {
40 | }
41 | };
42 |
43 | class HarmonyColorWheel::Private : public ColorWheel::Private
44 | {
45 | public:
46 | using ColorWheel::Private::Private;
47 |
48 | std::vector ring_editors;
49 | int current_ring_editor = -1;
50 |
51 | /**
52 | * Puts a double into [0; 1) range
53 | */
54 | static inline double normalize(double angle)
55 | {
56 | return angle - std::floor(angle);
57 | }
58 | };
59 |
60 |
61 | HarmonyColorWheel::HarmonyColorWheel(QWidget *parent) :
62 | ColorWheel(parent, new Private(this))
63 | {
64 | connect(this, SIGNAL(colorChanged(QColor)), this, SIGNAL(harmonyChanged()));
65 | p = static_cast(data());
66 | }
67 |
68 | HarmonyColorWheel::~HarmonyColorWheel() = default;
69 |
70 | QList HarmonyColorWheel::harmonyColors() const
71 | {
72 | QList result;
73 | result.push_back(color());
74 | for (auto const& harmony : p->ring_editors)
75 | {
76 | auto hue = Private::normalize(p->hue+harmony.hue_diff);
77 | result.push_back(p->color_from(hue, p->sat, p->val, 1));
78 | }
79 | return result;
80 | }
81 |
82 | unsigned int HarmonyColorWheel::harmonyCount() const
83 | {
84 | return 1 + p->ring_editors.size();
85 | }
86 |
87 | void HarmonyColorWheel::clearHarmonies()
88 | {
89 | p->ring_editors.clear();
90 | p->current_ring_editor = -1;
91 | Q_EMIT harmonyChanged();
92 | update();
93 | }
94 |
95 | unsigned HarmonyColorWheel::addHarmony(double hue_diff, bool editable)
96 | {
97 | auto count = p->ring_editors.size();
98 | p->ring_editors.emplace_back(Private::normalize(hue_diff), editable, -1, -1);
99 | Q_EMIT harmonyChanged();
100 | update();
101 | return count;
102 | }
103 |
104 | unsigned HarmonyColorWheel::addSymmetricHarmony(unsigned relative_to)
105 | {
106 | auto count = p->ring_editors.size();
107 | if (relative_to >= count)
108 | throw std::out_of_range("incorrect call to addSymmetricHarmony: harmony number out of range");
109 | auto& relative = p->ring_editors[relative_to];
110 | relative.symmetric_to = count;
111 | p->ring_editors.emplace_back(Private::normalize(-relative.hue_diff), relative.editable, relative_to, -1);
112 | Q_EMIT harmonyChanged();
113 | update();
114 | return count;
115 | }
116 |
117 | unsigned HarmonyColorWheel::addOppositeHarmony(unsigned relative_to)
118 | {
119 | auto count = p->ring_editors.size();
120 | if (relative_to >= count)
121 | throw std::out_of_range("incorrect call to addOppositeHarmony: harmony number out of range");
122 | auto& relative = p->ring_editors[relative_to];
123 | relative.opposite_to = count;
124 | p->ring_editors.emplace_back(Private::normalize(0.5+relative.hue_diff), relative.editable, -1, relative_to);
125 | Q_EMIT harmonyChanged();
126 | update();
127 | return count;
128 | }
129 |
130 | void HarmonyColorWheel::paintEvent(QPaintEvent * ev)
131 | {
132 | ColorWheel::paintEvent(ev);
133 |
134 | QPainter painter(this);
135 | painter.setRenderHint(QPainter::Antialiasing);
136 | painter.translate(geometry().width()/2,geometry().height()/2);
137 |
138 | for (auto const& editor : p->ring_editors)
139 | {
140 | auto hue = p->hue+editor.hue_diff;
141 | // TODO: better color for uneditable indicator
142 | auto color = editor.editable ? Qt::white : Qt::gray;
143 | p->draw_ring_editor(hue, painter, color);
144 | }
145 | }
146 |
147 |
148 | void HarmonyColorWheel::mousePressEvent(QMouseEvent *ev)
149 | {
150 | if ( ev->buttons() & Qt::LeftButton )
151 | {
152 | QLineF ray = p->line_to_point(ev->pos());
153 | if ( ray.length() <= p->outer_radius() && ray.length() > p->inner_radius() )
154 | {
155 | p->mouse_status = DragCircle;
156 | auto hue_diff = Private::normalize(ray.angle()/360 - p->hue);
157 | auto i = 0;
158 | for (auto const& editor : p->ring_editors)
159 | {
160 | const double eps = 1.0/64;
161 | if (editor.editable &&
162 | editor.hue_diff <= hue_diff + eps &&
163 | editor.hue_diff >= hue_diff - eps)
164 | {
165 | p->current_ring_editor = i;
166 | // no need to update color..
167 | return;
168 | }
169 | ++i;
170 | }
171 | }
172 | }
173 | ColorWheel::mousePressEvent(ev);
174 | }
175 |
176 |
177 | void HarmonyColorWheel::mouseMoveEvent(QMouseEvent *ev)
178 | {
179 | if ( p->mouse_status == DragCircle && p->current_ring_editor != -1 )
180 | {
181 | auto hue = p->line_to_point(ev->pos()).angle()/360.0;
182 | auto& editor = p->ring_editors[p->current_ring_editor];
183 | editor.hue_diff = Private::normalize(hue - p->hue);
184 | if (editor.symmetric_to != -1)
185 | {
186 | auto& symmetric = p->ring_editors[editor.symmetric_to];
187 | symmetric.hue_diff = Private::normalize(p->hue - hue);
188 | }
189 | else if (editor.opposite_to != -1)
190 | {
191 | auto& opposite = p->ring_editors[editor.opposite_to];
192 | opposite.hue_diff = Private::normalize(editor.hue_diff-0.5);
193 | }
194 | Q_EMIT harmonyChanged();
195 | update();
196 | return;
197 | }
198 | ColorWheel::mouseMoveEvent(ev);
199 | }
200 |
201 | void HarmonyColorWheel::mouseReleaseEvent(QMouseEvent *ev)
202 | {
203 | ColorWheel::mouseReleaseEvent(ev);
204 | p->current_ring_editor = -1;
205 | }
206 |
207 | } // namespace color_widgets
208 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/color_palette_widget.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef COLOR_WIDGETS_COLOR_PALETTE_WIDGET_HPP
23 | #define COLOR_WIDGETS_COLOR_PALETTE_WIDGET_HPP
24 |
25 | #include
26 | #include
27 | #include "color_palette_model.hpp"
28 | #include "swatch.hpp"
29 |
30 | namespace color_widgets {
31 |
32 | /**
33 | * \brief A widget to use and modify palettes
34 | */
35 | class QCP_EXPORT ColorPaletteWidget : public QWidget
36 | {
37 | Q_OBJECT
38 |
39 | /**
40 | * \brief Model used to store the palettes
41 | */
42 | Q_PROPERTY(ColorPaletteModel* model READ model WRITE setModel NOTIFY modelChanged)
43 |
44 | /**
45 | * \brief Size of a single color in the swatch widget
46 | */
47 | Q_PROPERTY(QSize colorSize READ colorSize WRITE setColorSize NOTIFY colorSizeChanged)
48 | /**
49 | * \brief Policy for colorSize
50 | **/
51 | Q_PROPERTY(color_widgets::Swatch::ColorSizePolicy colorSizePolicy READ colorSizePolicy WRITE setColorSizePolicy NOTIFY colorSizePolicyChanged)
52 |
53 | /**
54 | * \brief Border around the colors
55 | */
56 | Q_PROPERTY(QPen border READ border WRITE setBorder NOTIFY borderChanged)
57 |
58 | /**
59 | * \brief Forces the Swatch to display that many rows of colors
60 | *
61 | * If there are too few elements, the widget will display less than this
62 | * many rows.
63 | *
64 | * A value of0 means that the number of rows is automatic.
65 | *
66 | * \note Conflicts with forcedColumns
67 | */
68 | Q_PROPERTY(int forcedRows READ forcedRows WRITE setForcedRows NOTIFY forcedRowsChanged)
69 |
70 | /**
71 | * \brief Forces the Swatch to display that many columns of colors
72 | *
73 | * If there are too few elements, the widget will display less than this
74 | * many columns.
75 | *
76 | * A value of 0 means that the number of columns is automatic.
77 | *
78 | * \note Conflicts with forcedRows
79 | */
80 | Q_PROPERTY(int forcedColumns READ forcedColumns WRITE setForcedColumns NOTIFY forcedColumnsChanged)
81 |
82 | /**
83 | * \brief Whether the palettes can be modified via user interaction
84 | */
85 | Q_PROPERTY(bool readOnly READ readOnly WRITE setReadOnly NOTIFY readOnlyChanged)
86 |
87 | /**
88 | * \brief Currently selected color
89 | */
90 | Q_PROPERTY(QColor currentColor READ currentColor WRITE setCurrentColor NOTIFY currentColorChanged)
91 |
92 | /**
93 | * \brief Currently selected model row
94 | */
95 | Q_PROPERTY(int currentRow READ currentRow WRITE setCurrentRow NOTIFY currentRowChanged)
96 |
97 | /**
98 | * \brief Palette shown by the widget
99 | */
100 | Q_PROPERTY(const ColorPalette& currentPalette READ currentPalette NOTIFY currentPaletteChanged)
101 |
102 | /**
103 | * \brief If a valid color, it's used when adding new colors to palettes
104 | */
105 | Q_PROPERTY(QColor defaultColor READ defaultColor WRITE setDefaultColor NOTIFY defaultColorChanged)
106 |
107 | public:
108 | ColorPaletteWidget(QWidget* parent = nullptr);
109 | ~ColorPaletteWidget();
110 |
111 | ColorPaletteModel* model() const;
112 |
113 | /**
114 | * \brief Currently selected palette
115 | * \pre model() != nullptr and there is a selected palette
116 | */
117 | const ColorPalette& currentPalette() const;
118 |
119 | QSize colorSize() const;
120 | Swatch::ColorSizePolicy colorSizePolicy() const;
121 | QPen border() const;
122 |
123 | int forcedRows() const;
124 | int forcedColumns() const;
125 |
126 | bool readOnly() const;
127 | QColor currentColor() const;
128 |
129 | int currentRow() const;
130 |
131 | /**
132 | * \brief Default color when adding a color to the current palette
133 | */
134 | QColor defaultColor() const;
135 |
136 | public Q_SLOTS:
137 | void setModel(ColorPaletteModel* model);
138 | void setColorSize(const QSize& colorSize);
139 | void setColorSizePolicy(Swatch::ColorSizePolicy colorSizePolicy);
140 | void setBorder(const QPen& border);
141 | void setForcedRows(int forcedRows);
142 | void setForcedColumns(int forcedColumns);
143 | void setReadOnly(bool readOnly);
144 | /**
145 | * \brief Clear the selected color
146 | */
147 | void clearCurrentColor();
148 | /**
149 | * \brief Attempt to select a color
150 | *
151 | * If the given color is available in the current palete, it will be selected
152 | * \return \b true on success
153 | */
154 | bool setCurrentColor(const QColor& color);
155 | /**
156 | * \brief Attempt to select a color by name
157 | *
158 | * If the given color is available in the current palete, it will be selected
159 | * \return \b true on success
160 | */
161 | bool setCurrentColor(const QString& name);
162 | /**
163 | * \brief Attempt to select a color by index
164 | *
165 | * If the given color is available in the current palete, it will be selected
166 | * \return \b true on success
167 | */
168 | bool setCurrentColor(int index);
169 | /**
170 | * \brief Set the selected row in the model
171 | */
172 | void setCurrentRow(int currentRow);
173 |
174 | /**
175 | * \brief Sets the default for new colors
176 | * If invalid, it will show a dialog
177 | */
178 | void setDefaultColor(const QColor& color);
179 |
180 | Q_SIGNALS:
181 | void modelChanged(ColorPaletteModel* model);
182 | void colorSizeChanged(const QSize& colorSize);
183 | void colorSizePolicyChanged(Swatch::ColorSizePolicy colorSizePolicy);
184 | void forcedRowsChanged(int forcedRows);
185 | void forcedColumnsChanged(int forcedColumns);
186 | void readOnlyChanged(bool readOnly);
187 | void currentColorChanged(const QColor& currentColor);
188 | void currentColorChanged(int index);
189 | void borderChanged(const QPen& border);
190 | void currentRowChanged(int currentRow);
191 | void currentPaletteChanged(const ColorPalette& palette);
192 | void defaultColorChanged(const QColor& color);
193 |
194 | private Q_SLOTS:
195 | void on_palette_list_currentIndexChanged(int index);
196 | void on_swatch_doubleClicked(int index);
197 |
198 | private:
199 | class Private;
200 | std::unique_ptr p;
201 | };
202 |
203 | } // namespace color_widgets
204 | #endif // COLOR_WIDGETS_COLOR_PALETTE_WIDGET_HPP
205 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/src/QtColorWidgets/color_2d_slider.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #include "QtColorWidgets/color_2d_slider.hpp"
23 | #include "QtColorWidgets/color_utils.hpp"
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | namespace color_widgets {
30 |
31 | static const double selector_radius = 6;
32 |
33 | class Color2DSlider::Private
34 | {
35 | public:
36 | qreal hue = 1, sat = 1, val = 1;
37 | Component comp_x = Saturation;
38 | Component comp_y = Value;
39 | QImage square;
40 |
41 | qreal PixHue(float x, float y)
42 | {
43 | if ( comp_x == Hue )
44 | return x;
45 | if ( comp_y == Hue )
46 | return y;
47 | return hue;
48 | }
49 |
50 | qreal PixSat(float x, float y)
51 | {
52 | if ( comp_x == Saturation )
53 | return x;
54 | if ( comp_y == Saturation )
55 | return y;
56 | return sat;
57 | }
58 |
59 | qreal PixVal(float x, float y)
60 | {
61 | if ( comp_x == Value )
62 | return x;
63 | if ( comp_y == Value )
64 | return y;
65 | return val;
66 | }
67 |
68 | void renderSquare(const QSize& size)
69 | {
70 | square = QImage(size, QImage::Format_RGB32);
71 |
72 | for ( int y = 0; y < size.height(); ++y )
73 | {
74 | qreal yfloat = 1 - qreal(y) / size.height();
75 | for ( int x = 0; x < size.width(); ++x )
76 | {
77 | qreal xfloat = qreal(x) / size.width();
78 | square.setPixel( x, y, QColor::fromHsvF(
79 | PixHue(xfloat, yfloat),
80 | PixSat(xfloat, yfloat),
81 | PixVal(xfloat, yfloat)
82 | ).rgb());
83 | }
84 | }
85 | }
86 |
87 | QPointF selectorPos(const QSize& size)
88 | {
89 | QPointF pt;
90 | switch ( comp_x )
91 | {
92 | case Hue: pt.setX(size.width()*hue); break;
93 | case Saturation:pt.setX(size.width()*sat); break;
94 | case Value: pt.setX(size.width()*val); break;
95 | }
96 | switch ( comp_y )
97 | {
98 | case Hue: pt.setY(size.height()*(1-hue)); break;
99 | case Saturation:pt.setY(size.height()*(1-sat)); break;
100 | case Value: pt.setY(size.height()*(1-val)); break;
101 | }
102 | return pt;
103 | }
104 |
105 | void setColorFromPos(const QPoint& pt, const QSize& size)
106 | {
107 | QPointF ptfloat(
108 | qBound(0.0, qreal(pt.x()) / size.width(), 1.0),
109 | qBound(0.0, 1 - qreal(pt.y()) / size.height(), 1.0)
110 | );
111 | switch ( comp_x )
112 | {
113 | case Hue: hue = ptfloat.x(); break;
114 | case Saturation:sat = ptfloat.x(); break;
115 | case Value: val = ptfloat.x(); break;
116 | }
117 | switch ( comp_y )
118 | {
119 | case Hue: hue = ptfloat.y(); break;
120 | case Saturation:sat = ptfloat.y(); break;
121 | case Value: val = ptfloat.y(); break;
122 | }
123 | }
124 | };
125 |
126 | Color2DSlider::Color2DSlider(QWidget* parent)
127 | : QWidget(parent), p(new Private)
128 | {
129 | setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
130 | }
131 |
132 | Color2DSlider::~Color2DSlider()
133 | {
134 | delete p;
135 | }
136 |
137 | QColor Color2DSlider::color() const
138 | {
139 | return QColor::fromHsvF(p->hue, p->sat, p->val);
140 | }
141 |
142 | QSize Color2DSlider::sizeHint() const
143 | {
144 | return {128, 128};
145 | }
146 |
147 | qreal Color2DSlider::hue() const
148 | {
149 | return p->hue;
150 | }
151 |
152 | qreal Color2DSlider::saturation() const
153 | {
154 | return p->sat;
155 | }
156 |
157 | qreal Color2DSlider::value() const
158 | {
159 | return p->val;
160 | }
161 |
162 | Color2DSlider::Component Color2DSlider::componentX() const
163 | {
164 | return p->comp_x;
165 | }
166 |
167 | Color2DSlider::Component Color2DSlider::componentY() const
168 | {
169 | return p->comp_y;
170 | }
171 |
172 | void Color2DSlider::setColor(const QColor& c)
173 | {
174 | p->hue = c.hsvHueF();
175 | p->sat = c.saturationF();
176 | p->val = c.valueF();
177 | p->renderSquare(size());
178 | update();
179 | Q_EMIT colorChanged(color());
180 | }
181 |
182 | void Color2DSlider::setHue(qreal h)
183 | {
184 | p->hue = h;
185 | p->renderSquare(size());
186 | update();
187 | Q_EMIT colorChanged(color());
188 | }
189 |
190 | void Color2DSlider::setSaturation(qreal s)
191 | {
192 | p->sat = s;
193 | p->renderSquare(size());
194 | update();
195 | Q_EMIT colorChanged(color());
196 | }
197 |
198 | void Color2DSlider::setValue(qreal v)
199 | {
200 | p->val = v;
201 | p->renderSquare(size());
202 | update();
203 | Q_EMIT colorChanged(color());
204 | }
205 |
206 | void Color2DSlider::setComponentX(Color2DSlider::Component componentX)
207 | {
208 | if ( componentX != p->comp_x )
209 | {
210 | p->comp_x = componentX;
211 | p->renderSquare(size());
212 | update();
213 | Q_EMIT componentXChanged(p->comp_x);
214 | }
215 | }
216 |
217 | void Color2DSlider::setComponentY(Color2DSlider::Component componentY)
218 | {
219 | if ( componentY != p->comp_y )
220 | {
221 | p->comp_y = componentY;
222 | p->renderSquare(size());
223 | update();
224 | Q_EMIT componentXChanged(p->comp_y);
225 | }
226 | }
227 |
228 | void Color2DSlider::paintEvent(QPaintEvent*)
229 | {
230 | QPainter painter(this);
231 | painter.setRenderHint(QPainter::Antialiasing);
232 | painter.drawImage(0,0,p->square);
233 |
234 | painter.setPen(QPen(p->val > 0.5 ? Qt::black : Qt::white, 3));
235 | painter.setBrush(Qt::NoBrush);
236 | painter.drawEllipse(p->selectorPos(size()), selector_radius, selector_radius);
237 | }
238 |
239 | void Color2DSlider::mousePressEvent(QMouseEvent* event)
240 | {
241 | p->setColorFromPos(event->pos(), size());
242 | Q_EMIT colorChanged(color());
243 | update();
244 | }
245 |
246 | void Color2DSlider::mouseMoveEvent(QMouseEvent* event)
247 | {
248 | p->setColorFromPos(event->pos(), size());
249 | Q_EMIT colorChanged(color());
250 | update();
251 | }
252 |
253 | void Color2DSlider::mouseReleaseEvent(QMouseEvent* event)
254 | {
255 | p->setColorFromPos(event->pos(), size());
256 | Q_EMIT colorChanged(color());
257 | update();
258 | }
259 |
260 | void Color2DSlider::resizeEvent(QResizeEvent* event)
261 | {
262 | p->renderSquare(event->size());
263 | update();
264 | }
265 |
266 |
267 | } // namespace color_widgets
268 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/include/QtColorWidgets/color_palette.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | *
8 | * This program is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU Lesser General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU Lesser General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU Lesser General Public License
19 | * along with this program. If not, see .
20 | *
21 | */
22 | #ifndef COLOR_WIDGETS_COLOR_PALETTE_HPP
23 | #define COLOR_WIDGETS_COLOR_PALETTE_HPP
24 |
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include "colorwidgets_global.hpp"
32 |
33 | namespace color_widgets {
34 |
35 | class QCP_EXPORT ColorPalette : public QObject
36 | {
37 | Q_OBJECT
38 |
39 | /**
40 | * \brief The list of colors
41 | */
42 | Q_PROPERTY(QVector colors READ colors WRITE setColors NOTIFY colorsChanged)
43 | /**
44 | * \brief Name of the palette
45 | */
46 | Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
47 | /**
48 | * \brief Number of colors to display in a row, if 0 unspecified
49 | */
50 | Q_PROPERTY(int columns READ columns WRITE setColumns NOTIFY columnsChanged)
51 | /**
52 | * \brief Number of colors
53 | */
54 | Q_PROPERTY(int count READ count)
55 | /**
56 | * \brief Name of the file the palette has been read from
57 | */
58 | Q_PROPERTY(QString fileName READ fileName WRITE setFileName NOTIFY fileNameChanged)
59 | /**
60 | * \brief Whether it has been modified and it might be advisable to save it
61 | */
62 | Q_PROPERTY(bool dirty READ dirty WRITE setDirty NOTIFY dirtyChanged)
63 |
64 | public:
65 | typedef QPair value_type;
66 |
67 | ColorPalette(const QVector& colors, const QString& name = QString(), int columns = 0);
68 | ColorPalette(const QVector >& colors, const QString& name = QString(), int columns = 0);
69 | explicit ColorPalette(const QString& name = QString());
70 | ColorPalette(const ColorPalette& other);
71 | ColorPalette& operator=(const ColorPalette& other);
72 | ~ColorPalette();
73 | ColorPalette(ColorPalette&& other);
74 | ColorPalette& operator=(ColorPalette&& other);
75 |
76 | /**
77 | * \brief Color at the given index
78 | */
79 | Q_INVOKABLE QColor colorAt(int index) const;
80 |
81 | /**
82 | * \brief Color name at the given index
83 | */
84 | Q_INVOKABLE QString nameAt(int index) const;
85 |
86 | QVector > colors() const;
87 | QVector onlyColors() const;
88 |
89 | int count() const;
90 | int columns();
91 |
92 | QString name() const;
93 |
94 | /**
95 | * \brief Use a color table to set the colors
96 | */
97 | Q_INVOKABLE void loadColorTable(const QVector& color_table);
98 |
99 | /**
100 | * \brief Convert to a color table
101 | */
102 | Q_INVOKABLE QVector colorTable() const;
103 |
104 | /**
105 | * \brief Creates a ColorPalette from a color table
106 | */
107 | static ColorPalette fromColorTable(const QVector& table);
108 |
109 | /**
110 | * \brief Use the pixels on an image to set the palette colors
111 | */
112 | Q_INVOKABLE bool loadImage(const QImage& image);
113 |
114 | /**
115 | * \brief Creates a ColorPalette from a Gimp palette (gpl) file
116 | */
117 | static ColorPalette fromImage(const QImage& image);
118 |
119 | /**
120 | * \brief Load contents from a Gimp palette (gpl) file
121 | * \returns \b true On Success
122 | * \note If this function returns \b false, the palette will become empty
123 | */
124 | Q_INVOKABLE bool load(const QString& name);
125 |
126 | /**
127 | * \brief Creates a ColorPalette from a Gimp palette (gpl) file
128 | */
129 | static ColorPalette fromFile(const QString& name);
130 |
131 | QString fileName() const;
132 |
133 | bool dirty() const;
134 |
135 | /**
136 | * \brief Returns a preview image of the colors in the palette
137 | */
138 | QPixmap preview(const QSize& size, const QColor& background=Qt::transparent) const;
139 |
140 | public Q_SLOTS:
141 | void setColumns(int columns);
142 |
143 | void setColors(const QVector& colors);
144 | void setColors(const QVector >& colors);
145 |
146 | /**
147 | * \brief Change the color at the given index
148 | */
149 | void setColorAt(int index, const QColor& color);
150 | /**
151 | * \brief Change the color at the given index
152 | */
153 | void setColorAt(int index, const QColor& color, const QString& name);
154 | /**
155 | * \brief Change the name of a color
156 | */
157 | void setNameAt(int index, const QString& name = QString());
158 | /**
159 | * \brief Append a color at the end
160 | */
161 | void appendColor(const QColor& color, const QString& name = QString());
162 | /**
163 | * \brief Insert a color in an arbitrary location
164 | */
165 | void insertColor(int index, const QColor& color, const QString& name = QString());
166 | /**
167 | * \brief Remove the color at the given index
168 | */
169 | void eraseColor(int index);
170 |
171 | /**
172 | * \brief Change file name and save
173 | * \returns \b true on success
174 | */
175 | bool save(const QString& filename);
176 | /**
177 | * \brief save to file, the filename is \c fileName or determined automatically
178 | * \returns \b true on success
179 | */
180 | bool save();
181 |
182 | void setName(const QString& name);
183 | void setFileName(const QString& name);
184 | void setDirty(bool dirty);
185 |
186 | Q_SIGNALS:
187 | /**
188 | * \brief Emitted when all the colors have changed
189 | */
190 | void colorsChanged(const QVector >&);
191 | void columnsChanged(int);
192 | void nameChanged(const QString&);
193 | void fileNameChanged(const QString&);
194 | void dirtyChanged(bool);
195 | /**
196 | * \brief Emitted when the color or the name at the given index has been modified
197 | */
198 | void colorChanged(int index);
199 | /**
200 | * \brief Emitted when the color at the given index has been removed
201 | */
202 | void colorRemoved(int index);
203 | /**
204 | * \brief Emitted when a single color has been added
205 | */
206 | void colorAdded(int index);
207 | /**
208 | * \brief Emitted when the colors have been modified with a simple operation (set, append etc.)
209 | */
210 | void colorsUpdated(const QVector>&);
211 |
212 | private:
213 | /**
214 | * \brief Returns \c name if it isn't null, otherwise a default value
215 | */
216 | QString unnamed(const QString& name = QString()) const;
217 |
218 | /**
219 | * \brief Emit all the necessary signals when the palette has been completely overwritten
220 | */
221 | void emitUpdate();
222 |
223 | class Private;
224 | Private *p;
225 | };
226 |
227 | } // namespace color_widgets
228 |
229 | #endif // COLOR_WIDGETS_COLOR_PALETTE_HPP
230 |
--------------------------------------------------------------------------------
/utility.cpp:
--------------------------------------------------------------------------------
1 | #include "utility.h"
2 | #include
3 | #include
4 |
5 | // utility usually used
6 | // 4d poly cutting
7 | // hsv rgb converting
8 | // vector operations
9 |
10 | bool cut(double time, vec4 p, vec4 q, double &r, double &g, double &b)
11 | {
12 | if(p[3] > q[3]) { vec4 tmp = p; p = q; q = tmp; }
13 |
14 | if(p[3] < time + 1e-6 && time < q[3] + 1e-6)
15 | {
16 | double wp = q[3] - time;
17 | double wq = time - p[3];
18 |
19 | r = (p[0] * wp + q[0] * wq) / (wp + wq);
20 | g = (p[1] * wp + q[1] * wq) / (wp + wq);
21 | b = (p[2] * wp + q[2] * wq) / (wp + wq);
22 | return true;
23 | }
24 | else
25 | {
26 | return false;
27 | }
28 | }
29 |
30 |
31 | void RGBtoHSV(double src_r, double src_g, double src_b,
32 | double &dst_h, double &dst_s, double &dst_v)
33 | {
34 | float r = src_r;
35 | float g = src_g;
36 | float b = src_b;
37 |
38 | float h, s, v; // h:0-360.0, s:0.0-1.0, v:0.0-1.0
39 |
40 | float max = 0; // std::max(std::max(r, g), b);
41 | float min = 0; // std::max(std::max(r, g), b);
42 |
43 | if(r > max) max = r;
44 | if(g > max) max = g;
45 | if(b > max) max = b;
46 | if(r < min) min = r;
47 | if(g < min) min = g;
48 | if(b < min) min = b;
49 |
50 | v = max;
51 |
52 | if (max == 0.0f) {
53 | s = 0;
54 | h = 0;
55 | }
56 | else if (max - min == 0.0f) {
57 | s = 0;
58 | h = 0;
59 | }
60 | else {
61 | s = (max - min) / max;
62 |
63 | if (max == r) {
64 | h = 60 * ((g - b) / (max - min)) + 0;
65 | }
66 | else if (max == g) {
67 | h = 60 * ((b - r) / (max - min)) + 120;
68 | }
69 | else {
70 | h = 60 * ((r - g) / (max - min)) + 240;
71 | }
72 | }
73 |
74 | if (h < 0) h += 360.0f;
75 |
76 | dst_h = (h); // dst_h : 0-360
77 | dst_s = (s); // dst_s : 0-255
78 | dst_v = (v); // dst_v : 0-255
79 | }
80 |
81 | void cross(double x1, double y1, double z1, double x2, double y2, double z2, double &x, double &y, double &z)
82 | {
83 | x = y1 * z2 - z1 * y2;
84 | y = z1 * x2 - x1 * z2;
85 | z = x1 * y2 - y1 * x2;
86 | }
87 |
88 | double norm2(double x, double y, double z)
89 | {
90 | return x * x + y * y + z * z;
91 | }
92 |
93 | double angle(double x1, double y1, double z1, double x2, double y2, double z2)
94 | {
95 | double norm2_1 = norm2(x1, y1, z1);
96 | double norm2_2 = norm2(x2, y2, z2);
97 |
98 | if(norm2_1 < 1e-6 || norm2_2 < 1e-6) return 0;
99 |
100 | double c = (x1 * x2 + y1 * y2 + z1 * z2) / mysqrt(norm2_1 * norm2_2);
101 | if(c > 1) c = 1;
102 | if(c < -1) c = -1;
103 | return myacos(c);
104 |
105 | }
106 |
107 | double dot(double x1, double y1, double z1, double x2, double y2, double z2)
108 | {
109 | return x1 * x2 + y1 * y2 + z1 * z2;
110 | }
111 |
112 | myfloat3::myfloat3(float _x, float _y, float _z) : x(_x), y(_y), z(_z)
113 | {
114 | }
115 |
116 | myfloat3::myfloat3() : x(0.f), y(0.f), z(0.f)
117 | {
118 | }
119 |
120 | const float myfloat3::norm2() const
121 | {
122 | return x * x + y * y + z * z;
123 | }
124 |
125 | const float myfloat3::norm() const
126 | {
127 | float ans = x * x + y * y + z * z;
128 | if(ans < 0) ans = 0;
129 | return sqrtf(ans);
130 | }
131 |
132 | float myfloat3::dot(myfloat3 another)
133 | {
134 | return x * another.x + y * another.y + z * another.z;
135 | }
136 |
137 | myfloat3 myfloat3::cross(myfloat3 another)
138 | {
139 | const float &x_ = another.x;
140 | const float &y_ = another.y;
141 | const float &z_ = another.z;
142 |
143 | return myfloat3(
144 | y * z_ - z * y_,
145 | z * x_ - x * z_,
146 | x * y_ - y * x_
147 | );
148 | }
149 |
150 | const myfloat3 myfloat3::operator +(const myfloat3 another) const
151 | {
152 | const float &x_ = another.x;
153 | const float &y_ = another.y;
154 | const float &z_ = another.z;
155 |
156 | return myfloat3(x + x_, y + y_, z + z_);
157 | }
158 |
159 | const myfloat3 myfloat3::operator -(const myfloat3 another) const
160 | {
161 | const float &x_ = another.x;
162 | const float &y_ = another.y;
163 | const float &z_ = another.z;
164 |
165 | return myfloat3(x - x_, y - y_, z - z_);
166 | }
167 |
168 | const myfloat3 myfloat3::operator *(float k) const
169 | {
170 | return myfloat3(x * k, y * k, z * k);
171 | }
172 |
173 | const myfloat3 myfloat3::operator /(float k) const
174 | {
175 | k = 1.f / k;
176 | return myfloat3(x * k, y * k, z * k);
177 | }
178 |
179 | float myfloat3::getX() const
180 | {
181 | return x;
182 | }
183 |
184 | float myfloat3::getY() const
185 | {
186 | return y;
187 | }
188 |
189 | float myfloat3::getZ() const
190 | {
191 | return z;
192 | }
193 |
194 | float dot(myfloat3 x, myfloat3 y)
195 | {
196 | return x.dot(y);
197 | }
198 |
199 | myfloat3 cross(myfloat3 x, myfloat3 y)
200 | {
201 | return x.cross(y);
202 | }
203 |
204 | QDebug operator<<(QDebug debug, const myfloat3 &c)
205 | {
206 | QDebugStateSaver saver(debug);
207 | debug.nospace() << '(' << c.getX() << ", " << c.getY() << ", " << c.getZ() << ')';
208 |
209 | return debug;
210 | }
211 |
212 |
213 | //Yili Wang's code
214 | vec3 closesPointOnTriangle(const vec3 *triangle, const vec3 &sourcePosition)
215 | {
216 | vec3 edge0 = triangle[1] - triangle[0];
217 | vec3 edge1 = triangle[2] - triangle[0];
218 | vec3 v0 = triangle[0] - sourcePosition;
219 |
220 | float a = dot(edge0, edge0);
221 | float b = dot(edge0, edge1);
222 | float c = dot(edge1, edge1);
223 | float d = dot(edge0, v0);
224 | float e = dot(edge1, v0);
225 |
226 | float det = a*c - b*b;
227 | float s = b*e - c*d;
228 | float t = b*d - a*e;
229 |
230 | if (s + t < det)
231 | {
232 | if (s < 0.f)
233 | {
234 | if (t < 0.f)
235 | {
236 | if (d < 0.f)
237 | {
238 | s = my_util::clamp(-d / a, 0.f, 1.f);
239 | t = 0.f;
240 | }
241 | else
242 | {
243 | s = 0.f;
244 | t = my_util::clamp(-e / c, 0.f, 1.f);
245 | }
246 | }
247 | else
248 | {
249 | s = 0.f;
250 | t = my_util::clamp(-e / c, 0.f, 1.f);
251 | }
252 | }
253 | else if (t < 0.f)
254 | {
255 | s = my_util::clamp(-d / a, 0.f, 1.f);
256 | t = 0.f;
257 | }
258 | else
259 | {
260 | float invDet = 1.f / det;
261 | s *= invDet;
262 | t *= invDet;
263 | }
264 | }
265 | else
266 | {
267 | if (s < 0.f)
268 | {
269 | float tmp0 = b + d;
270 | float tmp1 = c + e;
271 | if (tmp1 > tmp0)
272 | {
273 | float numer = tmp1 - tmp0;
274 | float denom = a - 2 * b + c;
275 | s = my_util::clamp(numer / denom, 0.f, 1.f);
276 | t = 1 - s;
277 | }
278 | else
279 | {
280 | t = my_util::clamp(-e / c, 0.f, 1.f);
281 | s = 0.f;
282 | }
283 | }
284 | else if (t < 0.f)
285 | {
286 | if (a + d > b + e)
287 | {
288 | float numer = c + e - b - d;
289 | float denom = a - 2 * b + c;
290 | s = my_util::clamp(numer / denom, 0.f, 1.f);
291 | t = 1 - s;
292 | }
293 | else
294 | {
295 | s = my_util::clamp(-e / c, 0.f, 1.f);
296 | t = 0.f;
297 | }
298 | }
299 | else
300 | {
301 | float numer = c + e - b - d;
302 | float denom = a - 2 * b + c;
303 | s = my_util::clamp(numer / denom, 0.f, 1.f);
304 | t = 1.f - s;
305 | }
306 | }
307 |
308 | return triangle[0] + s * edge0 + t * edge1;
309 | }
310 |
311 | float myasin(float x)
312 | {
313 | if(x > 1) x = 1;
314 | if(x < -1) x = -1;
315 | return asin(x);
316 | }
317 |
318 | float myacos(float x)
319 | {
320 | if(x > 1) x = 1;
321 | if(x < -1) x = -1;
322 | return acos(x);
323 | }
324 |
325 | float mysqrt(float x)
326 | {
327 | if(x < 0) x = 0;
328 | return sqrt(x);
329 | }
330 |
331 | float mylog(float x)
332 | {
333 | if(x < 0) x = 0;
334 | return log(x);
335 | }
336 |
--------------------------------------------------------------------------------
/Qt-Color-Widgets/src/QtColorWidgets/gradient_slider.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * \file gradient_slider.cpp
3 | *
4 | * \author Mattia Basaglia
5 | *
6 | * \copyright Copyright (C) 2013-2020 Mattia Basaglia
7 | * \copyright Copyright (C) 2014 Calle Laakkonen
8 | * \copyright Copyright (C) 2017 caryoscelus
9 | *
10 | * This program is free software: you can redistribute it and/or modify
11 | * it under the terms of the GNU Lesser General Public License as published by
12 | * the Free Software Foundation, either version 3 of the License, or
13 | * (at your option) any later version.
14 | *
15 | * This program is distributed in the hope that it will be useful,
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | * GNU Lesser General Public License for more details.
19 | *
20 | * You should have received a copy of the GNU Lesser General Public License
21 | * along with this program. If not, see .
22 | *
23 | */
24 | #include "QtColorWidgets/gradient_slider.hpp"
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | static void loadResource()
33 | {
34 | static bool loaded = false;
35 | if ( !loaded )
36 | {
37 | Q_INIT_RESOURCE(color_widgets);
38 | loaded = true;
39 | }
40 | }
41 |
42 | namespace color_widgets {
43 |
44 | class GradientSlider::Private
45 | {
46 | public:
47 | QLinearGradient gradient;
48 | QBrush back;
49 |
50 | Private() :
51 | back(Qt::darkGray, Qt::DiagCrossPattern)
52 | {
53 | loadResource();
54 | back.setTexture(QPixmap(QStringLiteral(":/color_widgets/alphaback.png")));
55 | gradient.setCoordinateMode(QGradient::StretchToDeviceMode);
56 | gradient.setSpread(QGradient::RepeatSpread);
57 | }
58 |
59 | void mouse_event(QMouseEvent *ev, GradientSlider* owner)
60 | {
61 | qreal pos = (owner->geometry().width() > 5) ?
62 | static_cast(ev->pos().x() - 2.5) / (owner->geometry().width() - 5) : 0;
63 | pos = qMax(qMin(pos, 1.0), 0.0);
64 | owner->setSliderPosition(qRound(owner->minimum() +
65 | pos * (owner->maximum() - owner->minimum())));
66 | }
67 |
68 | };
69 |
70 | GradientSlider::GradientSlider(QWidget *parent) :
71 | GradientSlider(Qt::Horizontal, parent)
72 | {}
73 |
74 | GradientSlider::GradientSlider(Qt::Orientation orientation, QWidget *parent) :
75 | QSlider(orientation, parent), p(new Private)
76 | {
77 | setTickPosition(NoTicks);
78 | }
79 |
80 | GradientSlider::~GradientSlider()
81 | {
82 | delete p;
83 | }
84 |
85 | void GradientSlider::mousePressEvent(QMouseEvent *ev)
86 | {
87 | if ( ev->button() == Qt::LeftButton )
88 | {
89 | ev->accept();
90 | setSliderDown(true);
91 | p->mouse_event(ev, this);
92 | update();
93 | }
94 | else
95 | {
96 | QSlider::mousePressEvent(ev);
97 | }
98 | }
99 |
100 | void GradientSlider::mouseMoveEvent(QMouseEvent *ev)
101 | {
102 | if ( ev->buttons() & Qt::LeftButton )
103 | {
104 | ev->accept();
105 | p->mouse_event(ev, this);
106 | update();
107 | }
108 | else
109 | {
110 | QSlider::mouseMoveEvent(ev);
111 | }
112 | }
113 |
114 | void GradientSlider::mouseReleaseEvent(QMouseEvent *ev)
115 | {
116 | if ( ev->button() == Qt::LeftButton )
117 | {
118 | ev->accept();
119 | setSliderDown(false);
120 | update();
121 | }
122 | else
123 | {
124 | QSlider::mousePressEvent(ev);
125 | }
126 | }
127 |
128 | QBrush GradientSlider::background() const
129 | {
130 | return p->back;
131 | }
132 |
133 | void GradientSlider::setBackground(const QBrush &bg)
134 | {
135 | p->back = bg;
136 | update();
137 | Q_EMIT backgroundChanged(bg);
138 | }
139 |
140 | QGradientStops GradientSlider::colors() const
141 | {
142 | return p->gradient.stops();
143 | }
144 |
145 | void GradientSlider::setColors(const QGradientStops &colors)
146 | {
147 | p->gradient.setStops(colors);
148 | update();
149 | }
150 |
151 | QLinearGradient GradientSlider::gradient() const
152 | {
153 | return p->gradient;
154 | }
155 |
156 | void GradientSlider::setGradient(const QLinearGradient &gradient)
157 | {
158 | p->gradient = gradient;
159 | update();
160 | }
161 |
162 | void GradientSlider::setColors(const QVector &colors)
163 | {
164 | QGradientStops stops;
165 | stops.reserve(colors.size());
166 |
167 | double c = colors.size() - 1;
168 | if(c==0) {
169 | stops.append(QGradientStop(0, colors.at(0)));
170 |
171 | } else {
172 | for(int i=0;igradient.stops();
182 | if(stops.isEmpty())
183 | stops.push_back(QGradientStop(0.0, c));
184 | else
185 | stops.front().second = c;
186 | p->gradient.setStops(stops);
187 |
188 | update();
189 | }
190 |
191 | void GradientSlider::setLastColor(const QColor &c)
192 | {
193 | QGradientStops stops = p->gradient.stops();
194 | if(stops.size()<2)
195 | stops.push_back(QGradientStop(1.0, c));
196 | else
197 | stops.back().second = c;
198 | p->gradient.setStops(stops);
199 | update();
200 | }
201 |
202 | QColor GradientSlider::firstColor() const
203 | {
204 | QGradientStops s = colors();
205 | return s.empty() ? QColor() : s.front().second;
206 | }
207 |
208 | QColor GradientSlider::lastColor() const
209 | {
210 | QGradientStops s = colors();
211 | return s.empty() ? QColor() : s.back().second;
212 | }
213 |
214 | void GradientSlider::paintEvent(QPaintEvent *)
215 | {
216 | QPainter painter(this);
217 |
218 | QStyleOptionFrame panel;
219 | panel.initFrom(this);
220 | panel.lineWidth = 1;
221 | panel.midLineWidth = 0;
222 | panel.state |= QStyle::State_Sunken;
223 | style()->drawPrimitive(QStyle::PE_Frame, &panel, &painter, this);
224 | QRect r = style()->subElementRect(QStyle::SE_FrameContents, &panel, this);
225 | painter.setClipRect(r);
226 |
227 | qreal gradient_direction = invertedAppearance() ? -1 : 1;
228 |
229 | if(orientation() == Qt::Horizontal)
230 | p->gradient.setFinalStop(gradient_direction, 0);
231 | else
232 | p->gradient.setFinalStop(0, -gradient_direction);
233 |
234 | painter.setPen(Qt::NoPen);
235 | painter.setBrush(p->back);
236 | painter.drawRect(1,1,geometry().width()-2,geometry().height()-2);
237 | painter.setBrush(p->gradient);
238 | painter.drawRect(1,1,geometry().width()-2,geometry().height()-2);
239 |
240 | qreal pos = (maximum() != 0) ?
241 | static_cast(value() - minimum()) / maximum() : 0;
242 | QColor color;
243 | auto stops = p->gradient.stops();
244 | int i;
245 | for (i = 0; i < stops.size(); i++) {
246 | if (stops[i].first > pos)
247 | break;
248 | }
249 | if (i == 0) {
250 | color = firstColor();
251 | } if (i == stops.size()) {
252 | color = lastColor();
253 | } else {
254 | auto &a = stops[i - 1];
255 | auto &b = stops[i];
256 | auto c = (b.first - a.first);
257 | qreal q = (c != 0) ?
258 | (pos - a.first) / c : 0;
259 | color = QColor::fromRgbF(b.second.redF() * q + a.second.redF() * (1.0 - q),
260 | b.second.greenF() * q + a.second.greenF() * (1.0 - q),
261 | b.second.blueF() * q + a.second.blueF() * (1.0 - q),
262 | b.second.alphaF() * q + a.second.alphaF() * (1.0 - q));
263 | }
264 |
265 | pos = pos * (geometry().width() - 5);
266 | if (color.valueF() > 0.5 || color.alphaF() < 0.5) {
267 | painter.setPen(QPen(Qt::black, 3));
268 | } else {
269 | painter.setPen(QPen(Qt::white, 3));
270 | }
271 | QPointF p1 = QPointF(2.5, 2.5) + QPointF(pos, 0);
272 | QPointF p2 = p1 + QPointF(0, geometry().height() - 5);
273 | painter.drawLine(p1, p2);
274 | }
275 |
276 | } // namespace color_widgets
277 |
--------------------------------------------------------------------------------