├── .github ├── FUNDING.yml └── workflows │ └── build.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── cmake ├── cmake_uninstall.cmake.in └── kColorPickerConfig.cmake.in ├── example ├── CMakeLists.txt └── main.cpp ├── icons ├── ellipsis.64.png └── kColorPicker_icons.qrc ├── include └── kColorPicker │ ├── KColorPicker.h │ └── KColorPickerExport.h ├── src ├── CMakeLists.txt ├── IconCreator.cpp ├── IconCreator.h ├── KColorPicker.cpp ├── PopupMenu.cpp ├── PopupMenu.h ├── buttons │ ├── AbstractPopupMenuButton.cpp │ ├── AbstractPopupMenuButton.h │ ├── ColorButton.cpp │ ├── ColorButton.h │ ├── ColorDialogButton.cpp │ └── ColorDialogButton.h └── common │ ├── ScaledSizeProvider.cpp │ └── ScaledSizeProvider.h └── tests ├── CMakeLists.txt └── buttons ├── ColorButtonTest.cpp └── ColorButtonTest.h /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: DamirPorobic 4 | liberapay: dporobic 5 | patreon: dporobic 6 | open_collective: ksnip 7 | custom: paypal.me/damirporobic 8 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | 16 | - name: Install Qt 17 | uses: jurplel/install-qt-action@v2 18 | with: 19 | version: '5.15.2' 20 | host: 'linux' 21 | install-deps: 'true' 22 | 23 | - name: Install dependencies 24 | run: sudo apt-get install xvfb 25 | 26 | - name: Build 27 | run: | 28 | mkdir build && cd build 29 | cmake .. -DBUILD_TESTS=ON && make VERBOSE=1 30 | 31 | - name: Test 32 | working-directory: ${{github.workspace}}/build 33 | run: xvfb-run make test CTEST_OUTPUT_ON_FAILURE=1 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | *.slo 3 | *.lo 4 | *.o 5 | *.a 6 | *.la 7 | *.lai 8 | *.so 9 | *.dll 10 | *.dylib 11 | 12 | # Qt-es 13 | /.qmake.cache 14 | /.qmake.stash 15 | *.pro.user 16 | *.pro.user.* 17 | *.qbs.user 18 | *.qbs.user.* 19 | *.moc 20 | moc_*.cpp 21 | qrc_*.cpp 22 | ui_*.h 23 | Makefile* 24 | *build-* 25 | 26 | # QtCreator 27 | *.autosave 28 | 29 | # QtCtreator Qml 30 | *.qmlproject.user 31 | *.qmlproject.user.* 32 | 33 | # QtCtreator CMake 34 | CMakeLists.txt.user 35 | 36 | 37 | # kdevelop 38 | apidocs 39 | .kdev4 40 | build 41 | *~ 42 | *.kdev4 43 | *.bak 44 | *.orig 45 | *.rej 46 | doxygen.log 47 | Doxyfile 48 | *.kdevelop 49 | *.kdevelop.filelist 50 | *.kdevelop.pcs 51 | *.kdevses 52 | .*kate-swp 53 | build/ 54 | mem.log.* 55 | massif.* 56 | callgrind.* 57 | perf.data* 58 | 59 | # from kdiff3 60 | *.BACKUP.* 61 | *.BASE.* 62 | *.LOCAL.* 63 | *.REMOTE.* 64 | 65 | # visual studio code 66 | *.vscode/ 67 | *.vs 68 | 69 | # clion 70 | *.idea 71 | *.idea/ -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(kColorPicker LANGUAGES CXX VERSION 0.3.1) 3 | 4 | set(QT_MIN_VERSION 5.15.2) 5 | 6 | set(CMAKE_CXX_STANDARD 17) 7 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 8 | set(CMAKE_CXX_EXTENSIONS OFF) 9 | 10 | set(CMAKE_AUTOMOC ON) 11 | set(CMAKE_AUTORCC ON) 12 | 13 | option(BUILD_TESTS "Build Unit Tests" OFF) 14 | option(BUILD_EXAMPLE "Build Example Application" ON) 15 | 16 | option(BUILD_WITH_QT6 "Build with Qt6" OFF) 17 | if(BUILD_WITH_QT6) 18 | set(QT_MAJOR_VERSION 6) 19 | else() 20 | set(QT_MAJOR_VERSION 5) 21 | endif() 22 | 23 | find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} REQUIRED Widgets) 24 | 25 | include(GNUInstallDirs) 26 | include(FeatureSummary) 27 | 28 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 29 | 30 | add_subdirectory(src) 31 | 32 | if (BUILD_EXAMPLE) 33 | add_subdirectory(example) 34 | endif (BUILD_EXAMPLE) 35 | 36 | if (BUILD_TESTS) 37 | find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} REQUIRED Test) 38 | enable_testing() 39 | add_subdirectory(tests) 40 | endif (BUILD_TESTS) 41 | 42 | include(CMakePackageConfigHelpers) 43 | 44 | add_library(kColorPicker 45 | ${KCOLORPICKER_SRCS} 46 | ${CMAKE_CURRENT_SOURCE_DIR}/include/kColorPicker/KColorPicker.h 47 | ${CMAKE_CURRENT_SOURCE_DIR}/icons/kColorPicker_icons.qrc 48 | ) 49 | 50 | target_include_directories(kColorPicker 51 | PUBLIC 52 | $ 53 | $ 54 | $ 55 | ) 56 | 57 | target_link_libraries(kColorPicker PUBLIC Qt${QT_MAJOR_VERSION}::Widgets) 58 | 59 | target_compile_definitions(kColorPicker PRIVATE KIMAGEANNOTATOR_LIB) 60 | 61 | set_target_properties(kColorPicker 62 | PROPERTIES 63 | ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib 64 | LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib 65 | RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin 66 | VERSION ${PROJECT_VERSION} 67 | SOVERSION 0 68 | ) 69 | 70 | install(TARGETS kColorPicker 71 | EXPORT kColorPicker-targets 72 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 73 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 74 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 75 | ) 76 | 77 | install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/kColorPicker 78 | DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/kColorPicker-Qt${QT_MAJOR_VERSION} 79 | ) 80 | 81 | configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/kColorPickerConfig.cmake.in 82 | ${CMAKE_CURRENT_BINARY_DIR}/cmake/kColorPicker-Qt${QT_MAJOR_VERSION}Config.cmake 83 | INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/kColorPicker-Qt${QT_MAJOR_VERSION} 84 | ) 85 | 86 | write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/cmake/kColorPicker-Qt${QT_MAJOR_VERSION}Config-version.cmake 87 | VERSION ${PROJECT_VERSION} 88 | COMPATIBILITY AnyNewerVersion 89 | ) 90 | 91 | install(FILES 92 | ${CMAKE_CURRENT_BINARY_DIR}/cmake/kColorPicker-Qt${QT_MAJOR_VERSION}Config.cmake 93 | ${CMAKE_CURRENT_BINARY_DIR}/cmake/kColorPicker-Qt${QT_MAJOR_VERSION}Config-version.cmake 94 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/kColorPicker-Qt${QT_MAJOR_VERSION} 95 | ) 96 | 97 | 98 | export(EXPORT kColorPicker-targets 99 | FILE ${CMAKE_CURRENT_BINARY_DIR}/cmake/kColorPicker-Qt${QT_MAJOR_VERSION}-targets.cmake 100 | NAMESPACE kColorPicker:: 101 | ) 102 | 103 | install(EXPORT kColorPicker-targets 104 | FILE kColorPicker-targets.cmake 105 | NAMESPACE kColorPicker:: 106 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/kColorPicker-Qt${QT_MAJOR_VERSION} 107 | ) 108 | 109 | # uninstall target 110 | if(NOT TARGET uninstall) 111 | configure_file( 112 | "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" 113 | "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" 114 | IMMEDIATE @ONLY) 115 | 116 | add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) 117 | endif() 118 | 119 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # kColorPicker [![Build Status][github-badge]][github-url] 2 | QToolButton with color popup menu with lets you select a color. The popup features a color dialog button which can be used to add custom colors to the popup menu. 3 | 4 | Version 0.3.1 5 | 6 | ![kColorPicker](https://i.imgur.com/VkhUvFa.png "kColorPicker") 7 | 8 | ### Building from source 9 | 1. Get the latest release from GitHub by cloning the repo: 10 | `$ git clone https://github.com/ksnip/kColorPicker` 11 | 2. Change to repo directory: 12 | `$ cd kColorPicker` 13 | 3. Make new build directory and enter it: 14 | `$ mkdir build && cd build` 15 | 4. Create the makefile and build the project: 16 | `$ cmake .. && make` 17 | to build with Qt6, pass `-DBUILD_WITH_QT6=true` to the `cmake` command 18 | 5. Install shared library (not required when only using the example): 19 | `$ sudo make install` 20 | 6. Run the example application: 21 | `$ ./example/kColorPicker-example` 22 | 23 | 24 | ### Shared vs Static 25 | You can either build the project as shared library by providing the flag `-DBUILD_SHARED_LIBS=ON` 26 | to cmake or `-DBUILD_SHARED_LIBS=OFF` to build as static library. On Windows we currently can 27 | only build as static library. 28 | 29 | 30 | ### Integrate library in project 31 | 32 | 1. Let cmake find the shared library, optionally with version 33 | `set(KCOLORPICKER_MIN_VERSION "0.x.x")` 34 | to build with Qt5: 35 | `find_package(kColorPicker-Qt5 ${KCOLORPICKER_MIN_VERSION} REQUIRED)` 36 | to build with Qt6: 37 | `find_package(kColorPicker-Qt6 ${KCOLORPICKER_MIN_VERSION} REQUIRED)` 38 | 39 | 2. Link the library with your application 40 | `target_link_libraries(myApp kColorPicker)` 41 | 42 | 43 | [github-badge]: https://github.com/ksnip/kColorPicker/actions/workflows/build.yml/badge.svg 44 | [github-url]: https://github.com/ksnip/kColorPicker/actions 45 | -------------------------------------------------------------------------------- /cmake/cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") 2 | message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") 3 | endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") 4 | 5 | file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) 6 | string(REGEX REPLACE "\n" ";" files "${files}") 7 | foreach(file ${files}) 8 | message(STATUS "Uninstalling $ENV{DESTDIR}${file}") 9 | if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 10 | exec_program( 11 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 12 | OUTPUT_VARIABLE rm_out 13 | RETURN_VALUE rm_retval 14 | ) 15 | if(NOT "${rm_retval}" STREQUAL 0) 16 | message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") 17 | endif(NOT "${rm_retval}" STREQUAL 0) 18 | else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 19 | message(STATUS "File $ENV{DESTDIR}${file} does not exist.") 20 | endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 21 | endforeach(file) 22 | 23 | -------------------------------------------------------------------------------- /cmake/kColorPickerConfig.cmake.in: -------------------------------------------------------------------------------- 1 | include(CMakeFindDependencyMacro) 2 | 3 | @PACKAGE_INIT@ 4 | 5 | find_dependency(Qt@QT_MAJOR_VERSION@ @QT_MIN_VERSION@ COMPONENTS Widgets) 6 | 7 | if(NOT TARGET kColorPicker::kColorPicker) 8 | include("${CMAKE_CURRENT_LIST_DIR}/kColorPicker-targets.cmake") 9 | endif() 10 | -------------------------------------------------------------------------------- /example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(kColorPicker-example main.cpp) 2 | 3 | target_link_libraries(kColorPicker-example kColorPicker) 4 | -------------------------------------------------------------------------------- /example/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Damir Porobic 3 | * 4 | * This program 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 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #include 21 | #include 22 | #include "kColorPicker/KColorPicker.h" 23 | 24 | using kColorPicker::KColorPicker; 25 | 26 | int main(int argc, char **argv) 27 | { 28 | QApplication app(argc, argv); 29 | auto widget = new QWidget(); 30 | widget->setFixedWidth(200); 31 | widget->setFixedHeight(200); 32 | auto layout = new QVBoxLayout(); 33 | auto colorPicker = new KColorPicker(true); 34 | colorPicker->setColor(QColor(Qt::red)); 35 | layout->addWidget(colorPicker); 36 | widget->setLayout(layout); 37 | widget->show(); 38 | 39 | return app.exec(); 40 | } 41 | -------------------------------------------------------------------------------- /icons/ellipsis.64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksnip/kColorPicker/522e38b61e0786b97b2114c273a4551c869335be/icons/ellipsis.64.png -------------------------------------------------------------------------------- /icons/kColorPicker_icons.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ellipsis.64.png 5 | 6 | 7 | -------------------------------------------------------------------------------- /include/kColorPicker/KColorPicker.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Damir Porobic 3 | * 4 | * This program 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 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #ifndef KCOLORPICKER_KCOLORPICKER_H 21 | #define KCOLORPICKER_KCOLORPICKER_H 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include "kColorPicker/KColorPickerExport.h" 28 | 29 | namespace kColorPicker { 30 | 31 | class KColorPickerPrivate; 32 | 33 | class KCOLORPICKER_EXPORT KColorPicker : public QToolButton 34 | { 35 | Q_OBJECT 36 | 37 | Q_DECLARE_PRIVATE(KColorPicker) 38 | 39 | public: 40 | explicit KColorPicker(bool showAlphaChannel = false, QWidget *parent = nullptr); 41 | ~KColorPicker() override; 42 | void setFixedSize(const QSize &size); 43 | void setFixedSize(int width, int height); 44 | QColor color() const; 45 | void resetColors(bool showAlphaChannel = false); 46 | 47 | public Q_SLOTS: 48 | void setColor(const QColor &color); 49 | 50 | Q_SIGNALS: 51 | void colorChanged(const QColor &color) const; 52 | 53 | private: 54 | QScopedPointer const d_ptr; 55 | 56 | private Q_SLOTS: 57 | void setColorIcon(const QColor &color); 58 | void setIconSize(const QSize &size); 59 | void colorSelected(const QColor &color); 60 | }; 61 | 62 | } 63 | 64 | #endif //KCOLORPICKER_KCOLORPICKER_H 65 | -------------------------------------------------------------------------------- /include/kColorPicker/KColorPickerExport.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Damir Porobic 3 | * 4 | * This program 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 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #ifndef KCOLORPICKER_KCOLORPICKEREXPORT_H 21 | #define KCOLORPICKER_KCOLORPICKEREXPORT_H 22 | 23 | #include 24 | 25 | #if defined(_WIN32) 26 | # define KCOLORPICKER_EXPORT 27 | #else 28 | #if defined(KCOLORPICKER_LIB) 29 | # define KCOLORPICKER_EXPORT Q_DECL_EXPORT 30 | #else 31 | # define KCOLORPICKER_EXPORT Q_DECL_IMPORT 32 | #endif 33 | #endif 34 | 35 | #endif //KCOLORPICKER_KCOLORPICKEREXPORT_H 36 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(KCOLORPICKER_SRCS 2 | ${CMAKE_CURRENT_SOURCE_DIR}/KColorPicker.cpp 3 | ${CMAKE_CURRENT_SOURCE_DIR}/PopupMenu.cpp 4 | ${CMAKE_CURRENT_SOURCE_DIR}/IconCreator.cpp 5 | ${CMAKE_CURRENT_SOURCE_DIR}/buttons/AbstractPopupMenuButton.cpp 6 | ${CMAKE_CURRENT_SOURCE_DIR}/buttons/ColorButton.cpp 7 | ${CMAKE_CURRENT_SOURCE_DIR}/buttons/ColorDialogButton.cpp 8 | ${CMAKE_CURRENT_SOURCE_DIR}/common/ScaledSizeProvider.cpp 9 | ) 10 | 11 | set(KCOLORPICKER_SRCS ${KCOLORPICKER_SRCS} PARENT_SCOPE) 12 | 13 | -------------------------------------------------------------------------------- /src/IconCreator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Damir Porobic 3 | * 4 | * This program 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 program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #include "IconCreator.h" 21 | 22 | namespace kColorPicker { 23 | 24 | QIcon IconCreator::createIcon(const QColor &color, const QSize &size) 25 | { 26 | auto background = getBackgroundBrush(size); 27 | 28 | QPixmap pixmap(size); 29 | QPainter painter(&pixmap); 30 | 31 | // Paint background 32 | painter.setPen(Qt::NoPen); 33 | painter.setBrush(background); 34 | painter.drawRect(0, 0, size.width(), size.height()); 35 | 36 | // Paint color 37 | painter.setBrush(color); 38 | painter.drawRect(0, 0, size.width(), size.height()); 39 | 40 | // Paint border 41 | auto penWidth = painter.pen().width(); 42 | painter.setPen(QColor(Qt::gray)); 43 | painter.drawRect(0, 0, size.width() - penWidth, size.height() - penWidth); 44 | 45 | return { pixmap }; 46 | } 47 | 48 | QImage IconCreator::getBackgroundBrush(const QSize &size) 49 | { 50 | auto halfWidth = size.width() / 2; 51 | auto halfHeight = size.height() / 2; 52 | auto background = QImage(size, QImage::Format_ARGB32_Premultiplied); 53 | background.fill(Qt::white); 54 | QPainter painter(&background); 55 | painter.setPen(Qt::NoPen); 56 | painter.setBrush(Qt::gray); 57 | painter.drawRect(0, 0, halfWidth, halfHeight); 58 | painter.drawRect(halfWidth, halfHeight, size.width(), size.height()); 59 | 60 | return background; 61 | } 62 | 63 | } // namespace kColorPicker -------------------------------------------------------------------------------- /src/IconCreator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Damir Porobic 3 | * 4 | * This program 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 program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #ifndef KCOLORPICKER_ICONCREATOR_H 21 | #define KCOLORPICKER_ICONCREATOR_H 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | namespace kColorPicker { 29 | 30 | class IconCreator 31 | { 32 | public: 33 | explicit IconCreator() = delete; 34 | ~IconCreator() = delete; 35 | static QIcon createIcon(const QColor &color, const QSize &size); 36 | static QImage getBackgroundBrush(const QSize &size); 37 | }; 38 | 39 | } // namespace kColorPicker 40 | 41 | #endif //KCOLORPICKER_ICONCREATOR_H 42 | -------------------------------------------------------------------------------- /src/KColorPicker.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Damir Porobic 3 | * 4 | * This program 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 program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #include "kColorPicker/KColorPicker.h" 21 | 22 | #include "IconCreator.h" 23 | #include "PopupMenu.h" 24 | 25 | inline void initResource() 26 | { 27 | Q_INIT_RESOURCE(kColorPicker_icons); 28 | } 29 | 30 | namespace kColorPicker { 31 | 32 | class KColorPickerPrivate 33 | { 34 | Q_DISABLE_COPY(KColorPickerPrivate) 35 | 36 | Q_DECLARE_PUBLIC(KColorPicker) 37 | 38 | explicit KColorPickerPrivate(KColorPicker *kColorPicker, bool showAlphaChannel = false, QWidget *parent = nullptr); 39 | 40 | KColorPicker *const q_ptr; 41 | QSize mIconSize; 42 | PopupMenu *mPopupMenu; 43 | QColor mSelectedColor; 44 | }; 45 | 46 | KColorPicker::KColorPicker(bool showAlphaChannel, QWidget *parent) : d_ptr(new KColorPickerPrivate(this, showAlphaChannel, parent)) 47 | { 48 | // Default Colors 49 | resetColors(showAlphaChannel); 50 | } 51 | 52 | KColorPicker::~KColorPicker() 53 | {} 54 | 55 | void KColorPicker::setColor(const QColor &color) 56 | { 57 | Q_D(KColorPicker); 58 | d->mSelectedColor = color; 59 | setColorIcon(color); 60 | d->mPopupMenu->selectColor(color); 61 | } 62 | 63 | void KColorPicker::colorSelected(const QColor &color) 64 | { 65 | Q_D(KColorPicker); 66 | d->mSelectedColor = color; 67 | setColorIcon(color); 68 | emit colorChanged(color); 69 | } 70 | 71 | void KColorPicker::setFixedSize(const QSize &size) 72 | { 73 | Q_D(const KColorPicker); 74 | QToolButton::setFixedSize(size); 75 | setIconSize(size); 76 | setColorIcon(d->mSelectedColor); 77 | } 78 | 79 | void KColorPicker::setFixedSize(int width, int height) 80 | { 81 | Q_D(const KColorPicker); 82 | QToolButton::setFixedSize(width, height); 83 | setIconSize(QSize(width, height)); 84 | setColorIcon(d->mSelectedColor); 85 | } 86 | 87 | QColor KColorPicker::color() const 88 | { 89 | Q_D(const KColorPicker); 90 | return d->mSelectedColor; 91 | } 92 | 93 | void KColorPicker::resetColors(bool showAlphaChannel) 94 | { 95 | Q_D(const KColorPicker); 96 | d->mPopupMenu->removeColors(); 97 | 98 | d->mPopupMenu->addColor(QColor(Qt::red)); 99 | d->mPopupMenu->addColor(QColor(Qt::green)); 100 | d->mPopupMenu->addColor(QColor(Qt::blue)); 101 | d->mPopupMenu->addColor(QColor(Qt::yellow)); 102 | d->mPopupMenu->addColor(QColor(Qt::magenta)); 103 | d->mPopupMenu->addColor(QColor(Qt::cyan)); 104 | d->mPopupMenu->addColor(QColor(Qt::white)); 105 | d->mPopupMenu->addColor(QColor(Qt::black)); 106 | 107 | if(showAlphaChannel) { 108 | d->mPopupMenu->addColor(QColor(0, 255, 255, 100)); 109 | d->mPopupMenu->addColor(QColor(255, 0, 255, 100)); 110 | d->mPopupMenu->addColor(QColor(255, 255, 0, 100)); 111 | d->mPopupMenu->addColor(QColor(255, 255, 255, 100)); 112 | } 113 | } 114 | 115 | void KColorPicker::setIconSize(const QSize &size) 116 | { 117 | Q_D(KColorPicker); 118 | auto scaleFactor = 0.6; 119 | d->mIconSize = size * scaleFactor; 120 | QToolButton::setIconSize(d->mIconSize); 121 | } 122 | 123 | void KColorPicker::setColorIcon(const QColor &color) 124 | { 125 | Q_D(KColorPicker); 126 | auto icon = IconCreator::createIcon(color, d->mIconSize); 127 | setIcon(icon); 128 | setToolTip(color.name()); 129 | } 130 | 131 | // 132 | // KColorPickerPrivate 133 | // 134 | 135 | KColorPickerPrivate::KColorPickerPrivate(KColorPicker *kColorPicker, bool showAlphaChannel, QWidget *parent) : 136 | q_ptr(kColorPicker), 137 | mPopupMenu(new PopupMenu(showAlphaChannel, parent)) 138 | { 139 | initResource(); 140 | 141 | mIconSize = QSize(25, 25); 142 | kColorPicker->setPopupMode(QToolButton::InstantPopup); 143 | kColorPicker->setMenu(mPopupMenu); 144 | kColorPicker->connect(mPopupMenu, &PopupMenu::colorChanged, kColorPicker, &KColorPicker::colorSelected); 145 | } 146 | 147 | } // namespace kColorPicker 148 | -------------------------------------------------------------------------------- /src/PopupMenu.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Damir Porobic 3 | * 4 | * This program 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 program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #include "PopupMenu.h" 21 | 22 | namespace kColorPicker { 23 | 24 | PopupMenu::PopupMenu(bool showAlphaChannel, QWidget *parent) : 25 | QMenu(parent), 26 | mButtonGroup(new QButtonGroup(this)), 27 | mLayout(new QGridLayout(this)), 28 | mColorDialogButton(new ColorDialogButton(QIcon(QLatin1String(":/icons/ellipsis")), showAlphaChannel)) 29 | { 30 | mLayout->setSpacing(0); 31 | mLayout->setContentsMargins(5, 5, 5, 5); 32 | setLayout(mLayout); 33 | 34 | connect(mColorDialogButton, &AbstractPopupMenuButton::colorSelected, this, &PopupMenu::colorSelected); 35 | } 36 | 37 | PopupMenu::~PopupMenu() 38 | { 39 | qDeleteAll(mColorButtons); 40 | delete mColorDialogButton; 41 | } 42 | 43 | void PopupMenu::addColor(const QColor &color) 44 | { 45 | if (!isColorInGrid(color)) { 46 | addColorButton(color); 47 | } 48 | } 49 | 50 | void PopupMenu::removeColors() 51 | { 52 | for (auto button : mColorButtons) { 53 | mButtonGroup->removeButton(button); 54 | mLayout->removeWidget(button); 55 | disconnect(button, &AbstractPopupMenuButton::colorSelected, this, &PopupMenu::colorSelected); 56 | } 57 | 58 | qDeleteAll(mColorButtons); 59 | mColorButtons.clear(); 60 | 61 | generateGrid(); 62 | } 63 | 64 | void PopupMenu::selectColor(const QColor &color) 65 | { 66 | addColor(color); 67 | 68 | for (auto button : mColorButtons) { 69 | if (button->color() == color) { 70 | button->setChecked(true); 71 | return; 72 | } 73 | } 74 | } 75 | 76 | void PopupMenu::generateGrid() 77 | { 78 | auto row = 0; 79 | auto column = 0; 80 | 81 | clearGrid(); 82 | 83 | for (auto button : mColorButtons) { 84 | mLayout->addWidget(button, row, column % 4); 85 | column++; 86 | if (column % 4 == 0) { 87 | row++; 88 | } 89 | } 90 | 91 | mLayout->addWidget(mColorDialogButton, row, column % 4); 92 | } 93 | 94 | ColorButton *PopupMenu::createButton(const QColor &color) 95 | { 96 | auto icon = IconCreator::createIcon(color, ScaledSizeProvider::scaledSize(QSize(25, 25))); 97 | auto button = new ColorButton(icon, color); 98 | return button; 99 | } 100 | 101 | void PopupMenu::addColorButton(const QColor &color) 102 | { 103 | auto button = createButton(color); 104 | mButtonGroup->addButton(button); 105 | mColorButtons.append(button); 106 | connect(button, &AbstractPopupMenuButton::colorSelected, this, &PopupMenu::colorSelected); 107 | generateGrid(); 108 | } 109 | 110 | void PopupMenu::clearGrid() 111 | { 112 | for (auto button : mColorButtons) { 113 | mLayout->removeWidget(button); 114 | } 115 | } 116 | 117 | bool PopupMenu::isColorInGrid(const QColor &color) 118 | { 119 | for (auto button : mColorButtons) { 120 | if (button->color() == color) { 121 | return true; 122 | } 123 | } 124 | return false; 125 | } 126 | 127 | void PopupMenu::colorSelected(const QColor &color) 128 | { 129 | emit colorChanged(color); 130 | selectColor(color); 131 | hide(); 132 | } 133 | 134 | QSize PopupMenu::sizeHint() const 135 | { 136 | return mLayout->sizeHint(); 137 | } 138 | 139 | } // namespace kColorPicker 140 | -------------------------------------------------------------------------------- /src/PopupMenu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Damir Porobic 3 | * 4 | * This program 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 program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #ifndef KCOLORPICKER_POPUPMENU_H 21 | #define KCOLORPICKER_POPUPMENU_H 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include "IconCreator.h" 28 | #include "buttons/ColorButton.h" 29 | #include "buttons/ColorDialogButton.h" 30 | 31 | namespace kColorPicker { 32 | 33 | class PopupMenu : public QMenu 34 | { 35 | Q_OBJECT 36 | public: 37 | PopupMenu(bool showAlphaChannel, QWidget *parent); 38 | ~PopupMenu() override; 39 | void addColor(const QColor &color); 40 | void removeColors(); 41 | void selectColor(const QColor &color); 42 | QSize sizeHint() const; 43 | 44 | signals: 45 | void colorChanged(const QColor &color) const; 46 | 47 | private: 48 | QButtonGroup *mButtonGroup; 49 | QGridLayout *mLayout; 50 | QList mColorButtons; 51 | ColorDialogButton *mColorDialogButton; 52 | 53 | void generateGrid(); 54 | static ColorButton *createButton(const QColor &color); 55 | void addColorButton(const QColor &color); 56 | void clearGrid(); 57 | bool isColorInGrid(const QColor &color); 58 | 59 | private slots: 60 | void colorSelected(const QColor &color); 61 | }; 62 | 63 | } // namespace kColorPicker 64 | 65 | #endif //KCOLORPICKER_POPUPMENU_H 66 | -------------------------------------------------------------------------------- /src/buttons/AbstractPopupMenuButton.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Damir Porobic 3 | * 4 | * This program 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 program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #include "AbstractPopupMenuButton.h" 21 | 22 | namespace kColorPicker { 23 | 24 | AbstractPopupMenuButton::AbstractPopupMenuButton(const QIcon &icon) : 25 | mHoverColor(QColor(QLatin1String("#add8e6"))) 26 | { 27 | setIcon(icon); 28 | setFixedSize(iconSize() + QSize(8, 8)); 29 | connect(this, &QToolButton::clicked, this, &AbstractPopupMenuButton::buttonClicked); 30 | } 31 | 32 | void AbstractPopupMenuButton::paintEvent(QPaintEvent *event) 33 | { 34 | QPainter painter(this); 35 | QStyleOption styleOption; 36 | styleOption.initFrom(this); 37 | auto rect = event->rect(); 38 | auto scaleRatio = devicePixelRatioF(); 39 | auto buttonRect = QRectF(rect.x() + (2 / scaleRatio), rect.y() + (2 / scaleRatio), rect.width() - 5, rect.height() - 5); 40 | 41 | if(styleOption.state & QStyle::State_MouseOver) 42 | { 43 | auto defaultPen = painter.pen(); 44 | auto defaultBrush = painter.brush(); 45 | painter.setPen(mHoverColor); 46 | painter.setBrush(mHoverColor); 47 | painter.drawRect(buttonRect); 48 | painter.setPen(defaultPen); 49 | painter.setBrush(defaultBrush); 50 | } 51 | 52 | painter.drawPixmap(buttonRect.topLeft() + QPointF(2, 2), icon().pixmap(iconSize())); 53 | 54 | if(isChecked()) { 55 | painter.drawRect(buttonRect); 56 | } 57 | } 58 | 59 | } // namespace kColorPicker 60 | -------------------------------------------------------------------------------- /src/buttons/AbstractPopupMenuButton.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Damir Porobic 3 | * 4 | * This program 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 program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #ifndef KCOLORPICKER_ABSTRACTPOPUPMENUBUTTON_H 21 | #define KCOLORPICKER_ABSTRACTPOPUPMENUBUTTON_H 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "src/common/ScaledSizeProvider.h" 29 | 30 | namespace kColorPicker { 31 | 32 | class AbstractPopupMenuButton : public QToolButton 33 | { 34 | Q_OBJECT 35 | public: 36 | explicit AbstractPopupMenuButton(const QIcon &icon); 37 | 38 | signals: 39 | void colorSelected(const QColor &color) const; 40 | 41 | protected slots: 42 | void paintEvent(QPaintEvent *event) override; 43 | virtual void buttonClicked() = 0; 44 | 45 | private: 46 | QColor mHoverColor; 47 | }; 48 | 49 | } // namespace kColorPicker 50 | 51 | #endif //KCOLORPICKER_ABSTRACTPOPUPMENUBUTTON_H 52 | -------------------------------------------------------------------------------- /src/buttons/ColorButton.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Damir Porobic 3 | * 4 | * This program 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 program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #include "ColorButton.h" 21 | 22 | namespace kColorPicker { 23 | 24 | ColorButton::ColorButton(const QIcon &icon, const QColor &color) : AbstractPopupMenuButton(icon) 25 | { 26 | setCheckable(true); 27 | setToolTip(getColorName(color)); 28 | mColor = color; 29 | } 30 | 31 | QColor ColorButton::color() const 32 | { 33 | return mColor; 34 | } 35 | 36 | void ColorButton::buttonClicked() 37 | { 38 | emit colorSelected(mColor); 39 | } 40 | 41 | QString ColorButton::getColorName(const QColor &color) 42 | { 43 | auto format = color.alpha() < 255 ? QColor::HexArgb : QColor::HexRgb; 44 | 45 | return color.name(format); 46 | } 47 | 48 | } // namespace kColorPicker -------------------------------------------------------------------------------- /src/buttons/ColorButton.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Damir Porobic 3 | * 4 | * This program 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 program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #ifndef KCOLORPICKER_COLORBUTTON_H 21 | #define KCOLORPICKER_COLORBUTTON_H 22 | 23 | #include "AbstractPopupMenuButton.h" 24 | 25 | namespace kColorPicker { 26 | 27 | class ColorButton : public AbstractPopupMenuButton 28 | { 29 | Q_OBJECT 30 | public: 31 | ColorButton(const QIcon &icon, const QColor &color); 32 | QColor color() const; 33 | 34 | protected: 35 | void buttonClicked() override; 36 | 37 | private: 38 | QColor mColor; 39 | 40 | static QString getColorName(const QColor &color); 41 | }; 42 | 43 | } // namespace kColorPicker 44 | 45 | #endif //KCOLORPICKER_COLORBUTTON_H 46 | -------------------------------------------------------------------------------- /src/buttons/ColorDialogButton.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Damir Porobic 3 | * 4 | * This program 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 program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #include "ColorDialogButton.h" 21 | 22 | namespace kColorPicker { 23 | 24 | ColorDialogButton::ColorDialogButton(const QIcon &icon, bool showAlphaChannel) : 25 | AbstractPopupMenuButton(icon), 26 | mShowAlphaChannel(showAlphaChannel) 27 | { 28 | setCheckable(false); 29 | } 30 | 31 | void ColorDialogButton::buttonClicked() 32 | { 33 | auto color = QColorDialog::getColor(Qt::white, this, QString(), getColorDialogOptions()); 34 | emit colorSelected(color); 35 | } 36 | 37 | QFlags ColorDialogButton::getColorDialogOptions() const 38 | { 39 | return mShowAlphaChannel ? QColorDialog::ShowAlphaChannel : QFlags(); 40 | } 41 | 42 | } // namespace kColorPicker -------------------------------------------------------------------------------- /src/buttons/ColorDialogButton.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Damir Porobic 3 | * 4 | * This program 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 program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #ifndef KCOLORPICKER_COLORDIALOGBUTTON_H 21 | #define KCOLORPICKER_COLORDIALOGBUTTON_H 22 | 23 | #include 24 | 25 | #include "AbstractPopupMenuButton.h" 26 | 27 | namespace kColorPicker { 28 | 29 | class ColorDialogButton : public AbstractPopupMenuButton 30 | { 31 | Q_OBJECT 32 | public: 33 | explicit ColorDialogButton(const QIcon &icon, bool showAlphaChannel); 34 | 35 | protected: 36 | void buttonClicked() override; 37 | 38 | private: 39 | bool mShowAlphaChannel; 40 | QFlags getColorDialogOptions() const; 41 | }; 42 | 43 | } // namespace kColorPicker 44 | 45 | #endif //KCOLORPICKER_COLORDIALOGBUTTON_H 46 | -------------------------------------------------------------------------------- /src/common/ScaledSizeProvider.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Damir Porobic 3 | * 4 | * This program 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 program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #include "ScaledSizeProvider.h" 21 | 22 | namespace kColorPicker { 23 | 24 | QSize ScaledSizeProvider::scaledSize(const QSize &size) 25 | { 26 | return size * scaleFactor(); 27 | } 28 | 29 | qreal ScaledSizeProvider::scaleFactor() 30 | { 31 | static auto scaleFactor = getScaleFactor(); 32 | return scaleFactor; 33 | } 34 | 35 | qreal ScaledSizeProvider::getScaleFactor() 36 | { 37 | #if defined(__linux__) 38 | if(isGnomeEnvironment()) { 39 | auto screen = QApplication::primaryScreen(); 40 | auto logicalDotsPerInch = (int) screen->logicalDotsPerInch(); 41 | auto physicalDotsPerInch = (int) screen->physicalDotsPerInch(); 42 | return (qreal)logicalDotsPerInch / (qreal)physicalDotsPerInch; 43 | } 44 | #endif 45 | 46 | return 1; 47 | } 48 | 49 | #if defined(__linux__) 50 | bool ScaledSizeProvider::isGnomeEnvironment() 51 | { 52 | auto currentDesktop = QString(qgetenv("XDG_CURRENT_DESKTOP")); 53 | return currentDesktop.contains(QLatin1String("gnome"), Qt::CaseInsensitive) 54 | || currentDesktop.contains(QLatin1String("unity"), Qt::CaseInsensitive); 55 | } 56 | #endif 57 | 58 | } // namespace kColorPicker -------------------------------------------------------------------------------- /src/common/ScaledSizeProvider.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Damir Porobic 3 | * 4 | * This program 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 program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #ifndef KCOLORPICKER_SCALEDSIZEPROVIDER_H 21 | #define KCOLORPICKER_SCALEDSIZEPROVIDER_H 22 | 23 | #include 24 | 25 | #if defined(__linux__) 26 | #include 27 | #include 28 | #endif 29 | 30 | namespace kColorPicker { 31 | 32 | class ScaledSizeProvider 33 | { 34 | public: 35 | static QSize scaledSize(const QSize &size); 36 | 37 | private: 38 | static qreal scaleFactor(); 39 | static qreal getScaleFactor(); 40 | 41 | #if defined(__linux__) 42 | static bool isGnomeEnvironment(); 43 | #endif 44 | 45 | ScaledSizeProvider() = default; 46 | ~ScaledSizeProvider() = default; 47 | }; 48 | 49 | } // namespace kColorPicker 50 | 51 | #endif //KCOLORPICKER_SCALEDSIZEPROVIDER_H 52 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(UNITTEST_SRC 2 | buttons/ColorButtonTest.cpp 3 | ) 4 | 5 | add_library(KCOLORPICKER_STATIC STATIC ${KCOLORPICKER_SRCS}) 6 | 7 | target_link_libraries(KCOLORPICKER_STATIC Qt${QT_MAJOR_VERSION}::Widgets kColorPicker) 8 | 9 | foreach (UnitTest ${UNITTEST_SRC}) 10 | get_filename_component(UnitTestName ${UnitTest} NAME_WE) 11 | add_executable(${UnitTestName} ${UnitTest}) 12 | target_link_libraries(${UnitTestName} KCOLORPICKER_STATIC Qt${QT_MAJOR_VERSION}::Test) 13 | add_test(${UnitTestName} ${UnitTestName}) 14 | endforeach (UnitTest) 15 | -------------------------------------------------------------------------------- /tests/buttons/ColorButtonTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Damir Porobic 3 | * 4 | * This program 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 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | 21 | #include "ColorButtonTest.h" 22 | 23 | void ColorButtonTest::Clicked_Should_EmitColorSelected() 24 | { 25 | auto color = QColor(Qt::blue); 26 | ColorButton colorButton(QIcon(), color); 27 | QSignalSpy spy(&colorButton, &ColorButton::colorSelected); 28 | 29 | colorButton.click(); 30 | 31 | QCOMPARE(spy.count(), 1); 32 | auto selectedColor = qvariant_cast(spy.at(0).at(0)); 33 | QCOMPARE(selectedColor, color); 34 | } 35 | 36 | QTEST_MAIN(ColorButtonTest); 37 | -------------------------------------------------------------------------------- /tests/buttons/ColorButtonTest.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Damir Porobic 3 | * 4 | * This program 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 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program 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 General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #ifndef KCOLORPICKER_COLORBUTTONTEST_H 21 | #define KCOLORPICKER_COLORBUTTONTEST_H 22 | 23 | #include 24 | 25 | #include "src/buttons/ColorButton.h" 26 | #include "src/common/ScaledSizeProvider.h" 27 | 28 | using kColorPicker::ColorButton; 29 | using kColorPicker::ScaledSizeProvider; 30 | 31 | class ColorButtonTest : public QObject 32 | { 33 | Q_OBJECT 34 | 35 | private slots: 36 | void Clicked_Should_EmitColorSelected(); 37 | }; 38 | 39 | #endif // KCOLORPICKER_COLORBUTTONTEST_H 40 | --------------------------------------------------------------------------------