pax_global_header00006660000000000000000000000064136647501440014524gustar00rootroot0000000000000052 comment=f2eca13bbc836cec09daae02579f10d5e85e71e8 Qt-Color-Widgets-v2.2.0/000077500000000000000000000000001366475014400147575ustar00rootroot00000000000000Qt-Color-Widgets-v2.2.0/.gitignore000066400000000000000000000000221366475014400167410ustar00rootroot00000000000000build/ *.pro.user Qt-Color-Widgets-v2.2.0/CMakeLists.txt000066400000000000000000000120771366475014400175260ustar00rootroot00000000000000# # Copyright (C) 2013-2020 Mattia Basaglia # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # cmake_minimum_required (VERSION 3.1 FATAL_ERROR) set(COLORWIDGET_PROJECT_NAME QtColorWidgets) project(${COLORWIDGET_PROJECT_NAME} CXX) set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_CURRENT_LIST_DIR}) include (CheckCXXCompilerFlag) include (cmake/install.cmake) include (cmake/qt-configuration.cmake) include (cmake/versioning.cmake) SET (${COLORWIDGET_PROJECT_NAME}_VERSION_MAJOR 2) SET (${COLORWIDGET_PROJECT_NAME}_VERSION_MINOR 2) SET (${COLORWIDGET_PROJECT_NAME}_VERSION_PATCH 0) SET (${COLORWIDGET_PROJECT_NAME}_VERSION "${${COLORWIDGET_PROJECT_NAME}_VERSION_MAJOR}.${${COLORWIDGET_PROJECT_NAME}_VERSION_MINOR}.${${COLORWIDGET_PROJECT_NAME}_VERSION_PATCH}") set (QT_SUPPORTED_VERSIONS 5) select_qt ( QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}" QT_DEFAULT_VERSION 5) set (REQUIRED_QT_COMPONENTS Widgets ) find_qt ( QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}" REQUIRED_COMPONENTS "${REQUIRED_QT_COMPONENTS}" OPTIONAL_COMPONENTS "") # Auto generate moc files set(CMAKE_AUTOMOC ON) # Auto generate moc files set(CMAKE_AUTOUIC ON) # Auto generate moc files set(CMAKE_AUTORCC ON) option(BUILD_SHARED_LIBS "Build the shared library" ON) option(BUILD_STATIC_LIBS "Build the static library" OFF) set (TARGET_NAME ${COLORWIDGET_PROJECT_NAME}) set (TARGET_OUTPUT_SUFFIX "-Qt${QT_VERSION}${${COLORWIDGET_PROJECT_NAME}_VERSION_MAJOR}") set (INCLUDE_PREFIX "QtColorWidgets") set (COLOR_WIDGETS_LIBRARY "${TARGET_NAME}") if ( ${BUILD_STATIC_LIBS} ) add_definitions(-DQTCOLORWIDGETS_STATICALLY_LINKED) endif() add_library (${TARGET_NAME} "") set_target_properties(${TARGET_NAME} PROPERTIES EXPORT_NAME "${TARGET_NAME}${TARGET_OUTPUT_SUFFIX}") set_target_properties (${TARGET_NAME} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON VERSION ${${COLORWIDGET_PROJECT_NAME}_VERSION} SOVERSION ${${COLORWIDGET_PROJECT_NAME}_VERSION_MAJOR} "INTERFACE_${COLORWIDGET_PROJECT_NAME}_MAJOR_VERSION" ${${COLORWIDGET_PROJECT_NAME}_VERSION_MAJOR} COMPATIBLE_INTERFACE_STRING "${COLORWIDGET_PROJECT_NAME}_MAJOR_VERSION" COMPILE_DEFINITIONS QTCOLORWIDGETS_LIBRARY OUTPUT_NAME "${TARGET_NAME}${TARGET_OUTPUT_SUFFIX}") check_cxx_compiler_flag ("-Wall" Wall_FLAG_SUPPORTED) if (Wall_FLAG_SUPPORTED) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall") endif (Wall_FLAG_SUPPORTED) check_cxx_compiler_flag ("-pedantic" pedantic_FLAG_SUPPORTED) if (pedantic_FLAG_SUPPORTED) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pedantic") endif (pedantic_FLAG_SUPPORTED) check_cxx_compiler_flag ("-Wextra" Wextra_FLAG_SUPPORTED) if (Wextra_FLAG_SUPPORTED) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wextra") endif (Wextra_FLAG_SUPPORTED) set (EXPORT_HEADER "${INCLUDE_PREFIX}/colorwidgets_global.hpp") generate_versioning_information ( TARGET_NAME ${TARGET_NAME} EXPORT_HEADER ${EXPORT_HEADER} EXPORT_MACRO QCP_EXPORT VERSIONED_ENTITY ${COLORWIDGET_PROJECT_NAME} INCLUDE_PREFIX ${INCLUDE_PREFIX} COMPANY_NAME "Mattia Basaglia" COMPANY_COPYRIGHT "Mattia Basaglia Copyright (C) 2013-2017" FILE_DESCRIPTION "Color wheel widget and dialog for Qt${QT_VERSION}" ) target_include_directories(${TARGET_NAME} PUBLIC $ $ PUBLIC $ $ ) add_subdirectory (${CMAKE_CURRENT_SOURCE_DIR}/include/${INCLUDE_PREFIX}) add_subdirectory (${CMAKE_CURRENT_SOURCE_DIR}/resources/${INCLUDE_PREFIX}) add_subdirectory (${CMAKE_CURRENT_SOURCE_DIR}/src/${INCLUDE_PREFIX}) use_qt ( TARGET_NAME ${TARGET_NAME} QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}" REQUIRED_COMPONENTS "${REQUIRED_QT_COMPONENTS}" OPTIONAL_COMPONENTS "") install_project ( PROJECT_NAME ${COLORWIDGET_PROJECT_NAME} TARGET_NAME ${TARGET_NAME} TARGET_OUTPUT_SUFFIX ${TARGET_OUTPUT_SUFFIX} EXPORT_HEADER ${EXPORT_HEADER} INCLUDE_PREFIX ${INCLUDE_PREFIX} HEADER_MATCHING_REGEX "^.*\.h$|^.*\.hpp$|^.*$" VERSION_HEADER ${CMAKE_CURRENT_BINARY_DIR}/${COLORWIDGET_PROJECT_NAME}_version.h NAMESPACE "") add_subdirectory (gallery) option(QTCOLORWIDGETS_DESIGNER_PLUGIN "Build QtDesigner plugin" ON) if (${QTCOLORWIDGETS_DESIGNER_PLUGIN}) find_package (Qt5Designer QUIET) if (Qt5Designer_FOUND) add_subdirectory (color_widgets_designer_plugin) endif(Qt5Designer_FOUND) endif() Qt-Color-Widgets-v2.2.0/COPYING000066400000000000000000000167431366475014400160250ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. Qt-Color-Widgets-v2.2.0/LICENSE-EXCEPTION000066400000000000000000000016641366475014400173270ustar00rootroot00000000000000Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions of the GNU Lesser General Public License version 3 cover the whole combination. As a special exception, the copyright holders of this library give you permission to combine this library with independent modules to produce an executable, and to copy and distribute the resulting executable under terms of any of the GNU General Public licenses, as published by the Free Software Foundation, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obliged to do so. If you do not wish to do so, delete this exception statement from your version. Qt-Color-Widgets-v2.2.0/QtColorWidgets.pc.in000066400000000000000000000005161366475014400206240ustar00rootroot00000000000000prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix} libdir=@CMAKE_INSTALL_LIBDIR@ includedir=${prefix}/include Name: QtColorWidgets Description: Color wheel widget and dialog for Qt Version: @QtColorWidgets_VERSION@ Libs: -L${libdir} -l@i_target_name@@i_target_output_suffix@ Cflags: -I${includedir}/@i_project_name@ -I${includedir} Qt-Color-Widgets-v2.2.0/README.md000066400000000000000000000047141366475014400162440ustar00rootroot00000000000000Color Widgets ============= Here is a color dialog that is more user-friendly than the default QColorDialog and several other color-related widgets The provided widgets are: * ColorWheel, An analog widget used to select a color * ColorPreview, A simple widget that displays a color * GradientSlider, A slider that has a gradient background * HueSlider, A variant of GradientSlider that has a rainbow background * ColorSelector, A ColorPreview that shows a ColorDialog when clicked * ColorDialog, A dialog that uses the above widgets to provide a better user experience than QColorDialog * ColorListWidget, A widget to edit a list of colors * Swatch, A widget to display a color palette * ColorPaletteWidget, A widget to use and manage a list of palettes * Color2DSlider, An analog widget used to select 2 color components * ColorLineEdit, A widget to manipulate a string representing a color * HarmonyColorWheel, A ColorWheel which allows defining multiple colors, separated by hue * GradientListModel, A QAbstractListModel used to list gradients (useful for combo boxes, list views and the like) they are all in the color_widgets namespace. See [the gallery](gallery/README.md) for more information and screenshots. Using it in a project --------------------- For QMake-based projects, include color_widgets.pri in the QMake project file. For CMake-based projects, add this as subdirectory, it will be compiled as a library and you can link the required targets to ColorWidgets. All the required files are in ./src and ./include. Installing as a Qt Designer/Creator Plugin ------------------------------------------ The sources for the designer plugin are in ./color_widgets_designer_plugin Compile the library and install in (Qt SDK)/Tools/QtCreator/bin/designer/ (Qt SDK)/(Qt Version)/(Toolchain)/plugins/designer mkdir build && cd build && cmake .. && make QtColorWidgetsPlugin && make install Latest Version -------------- The latest version of the sources can be found at the following locations: * https://gitlab.com/mattia.basaglia/Qt-Color-Widgets * git://gitlab.com/mattia.basaglia/Qt-Color-Widgets.git License ------- LGPLv3+, See COPYING. As a special exception, this library can be included in any project under the terms of any of the GNU liceses, distributing the whole project under a different GNU license, see LICENSE-EXCEPTION for details. Copyright (C) 2013-2020 Mattia Basaglia Qt-Color-Widgets-v2.2.0/cmake/000077500000000000000000000000001366475014400160375ustar00rootroot00000000000000Qt-Color-Widgets-v2.2.0/cmake/QtColorWidgets-config.cmake000066400000000000000000000001441366475014400232150ustar00rootroot00000000000000include("${CMAKE_CURRENT_LIST_DIR}/@CMAKE_BASE_FILE_NAME@@CMAKE_FILE_OUTPUT_SUFFIX@-targets.cmake") Qt-Color-Widgets-v2.2.0/cmake/install.cmake000066400000000000000000000053001366475014400205050ustar00rootroot00000000000000function (install_project PROJECT_NAME i_project_name TARGET_NAME i_target_name TARGET_OUTPUT_SUFFIX i_target_output_suffix EXPORT_HEADER i_export_header INCLUDE_PREFIX i_include_prefix HEADER_MATCHING_REGEX i_header_matching_regex VERSION_HEADER i_version_header NAMESPACE i_namespace) install (TARGETS ${i_target_name} EXPORT ${i_target_name} RUNTIME DESTINATION bin INCLUDES DESTINATION include ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) install (DIRECTORY include/ DESTINATION include FILES_MATCHING REGEX ${i_header_matching_regex} REGEX "CMakeLists\.txt" EXCLUDE) install (FILES ${i_version_header} DESTINATION include/${i_include_prefix} COMPONENT Devel) install (FILES include/${i_export_header} DESTINATION include/${i_include_prefix} COMPONENT Devel) install( EXPORT ${i_target_name} DESTINATION lib/cmake/${i_target_name}${i_target_output_suffix} FILE "${i_target_name}${i_target_output_suffix}.cmake" COMPONENT Devel) include(CMakePackageConfigHelpers) string (TOLOWER ${i_target_name} CMAKE_BASE_FILE_NAME) string (TOLOWER ${i_target_output_suffix} CMAKE_FILE_OUTPUT_SUFFIX) write_basic_package_version_file( "${CMAKE_CURRENT_BINARY_DIR}/${i_target_name}/${CMAKE_BASE_FILE_NAME}${CMAKE_FILE_OUTPUT_SUFFIX}-config-version.cmake" VERSION ${${i_project_name}_VERSION} COMPATIBILITY SameMajorVersion ) export(EXPORT ${i_target_name} FILE "${CMAKE_CURRENT_BINARY_DIR}/${i_target_name}/${CMAKE_BASE_FILE_NAME}${CMAKE_FILE_OUTPUT_SUFFIX}-targets.cmake" ) configure_file("cmake/${i_project_name}-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${i_target_name}/${CMAKE_BASE_FILE_NAME}${CMAKE_FILE_OUTPUT_SUFFIX}-config.cmake" @ONLY ) set(ConfigPackageLocation "lib/cmake/${i_target_name}${i_target_output_suffix}") install(EXPORT ${i_target_name} FILE "${CMAKE_BASE_FILE_NAME}${CMAKE_FILE_OUTPUT_SUFFIX}-targets.cmake" NAMESPACE "${i_namespace}" DESTINATION ${ConfigPackageLocation} ) install( FILES "${CMAKE_CURRENT_BINARY_DIR}/${i_target_name}/${CMAKE_BASE_FILE_NAME}${CMAKE_FILE_OUTPUT_SUFFIX}-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${i_target_name}/${CMAKE_BASE_FILE_NAME}${CMAKE_FILE_OUTPUT_SUFFIX}-config-version.cmake" DESTINATION ${ConfigPackageLocation} COMPONENT Devel ) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/${i_project_name}.pc.in ${CMAKE_CURRENT_BINARY_DIR}/${i_target_name}${i_target_output_suffix}.pc @ONLY ) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${i_target_name}${i_target_output_suffix}.pc DESTINATION lib/pkgconfig ) endfunction (install_project) Qt-Color-Widgets-v2.2.0/cmake/modules/000077500000000000000000000000001366475014400175075ustar00rootroot00000000000000Qt-Color-Widgets-v2.2.0/cmake/modules/ProjectVersioning.cmake000066400000000000000000000044321366475014400241660ustar00rootroot00000000000000define_property (TARGET PROPERTY GIT_DESCRIBE BRIEF_DOCS "Advanced version info for developers" FULL_DOCS "String with information that is important for developers during development process. This information includes git commit hash, durty status of repo, distance from the last tag.") define_property (TARGET PROPERTY GIT_UNTRACKED_FILES BRIEF_DOCS "Information about presence of untracked files" FULL_DOCS "Used in helper functions generation to add .with-untracked suffix to version string. Suffix is only added if there are some untracked not ignored files in repository.") set(HERE_DIR ${CMAKE_CURRENT_LIST_DIR}) function (target_version_information TARGET_NAME i_target_name EXPORT_HEADER i_export_header EXPORT_MACRO i_export_macro VERSIONED_ENTITY i_versioned_entity) find_file ( headerFileTemplate "ProjectVersioning/version.h.in" PATHS ${CMAKE_MODULE_PATH}) if ( NOT ${headerFileTemplate} ) set(headerFileTemplate "${HERE_DIR}/ProjectVersioning/version.h.in") endif() find_file ( sourceFileTemplate "ProjectVersioning/version.c.in" PATHS ${CMAKE_MODULE_PATH}) if ( NOT ${sourceFileTemplate} ) set(sourceFileTemplate "${HERE_DIR}/ProjectVersioning/version.c.in") endif() exec_program ( "git" ${CMAKE_SOURCE_DIR} ARGS "describe --always --dirty --long --tags" OUTPUT_VARIABLE gitDescribe) exec_program ( "git" ${CMAKE_SOURCE_DIR} ARGS "ls-files --others --exclude-standard" OUTPUT_VARIABLE gitUntracked) if (gitUntracked) set (gitUntracked ".with-untracked") endif (gitUntracked) configure_file ( "${headerFileTemplate}" "${CMAKE_CURRENT_BINARY_DIR}/${i_versioned_entity}_version.h") configure_file( "${sourceFileTemplate}" "${CMAKE_BINARY_DIR}/${i_versioned_entity}_version.c") target_sources ("${i_target_name}" PRIVATE $ $ PRIVATE "${CMAKE_BINARY_DIR}/${i_versioned_entity}_version.c") set_target_properties (${i_target_name} PROPERTIES GIT_DESCRIBE "${gitDescribe}" GIT_UNTRACKED_FILES "${gitUntracked}") unset (headerFileTemplate PARENT_SCOPE) unset (sourceFileTemplate PARENT_SCOPE) endfunction (target_version_information) Qt-Color-Widgets-v2.2.0/cmake/modules/ProjectVersioning/000077500000000000000000000000001366475014400231615ustar00rootroot00000000000000Qt-Color-Widgets-v2.2.0/cmake/modules/ProjectVersioning/version.c.in000066400000000000000000000013551366475014400254230ustar00rootroot00000000000000#include "${i_versioned_entity}_version.h" unsigned int @i_versioned_entity@_versionMajor () { return ${${i_versioned_entity}_VERSION_MAJOR}; } unsigned int @i_versioned_entity@_versionMinor () { return ${${i_versioned_entity}_VERSION_MINOR}; } unsigned int @i_versioned_entity@_versionPatch () { return ${${i_versioned_entity}_VERSION_PATCH}; } const char* @i_versioned_entity@_versionGitInfo () { return "${gitDescribe}" "${gitUntracked}"; } const char* @i_versioned_entity@_versionFullString () { return "${${i_versioned_entity}_VERSION_MAJOR}." "${${i_versioned_entity}_VERSION_MINOR}." "${${i_versioned_entity}_VERSION_PATCH}" "${${i_versioned_entity}_VERSION_PRE_RELEASE}" "+${gitDescribe}" "${gitUntracked}"; } Qt-Color-Widgets-v2.2.0/cmake/modules/ProjectVersioning/version.h.in000066400000000000000000000007761366475014400254360ustar00rootroot00000000000000#ifndef @CMAKE_PROJECT_NAME@_VERSION_H #define @CMAKE_PROJECT_NAME@_VERSION_H #include "@i_export_header@" @i_export_macro@ unsigned int @i_versioned_entity@_versionMajor (); @i_export_macro@ unsigned int @i_versioned_entity@_versionMinor (); @i_export_macro@ unsigned int @i_versioned_entity@_versionPatch (); @i_export_macro@ const char* @i_versioned_entity@_versionGitInfo (); @i_export_macro@ const char* @i_versioned_entity@_versionFullString (); #endif /* @CMAKE_PROJECT_NAME@_VERSION_H */ Qt-Color-Widgets-v2.2.0/cmake/modules/VersionInfo.in000066400000000000000000000077031366475014400223070ustar00rootroot00000000000000/* The MIT License (MIT) Copyright (c) 2015, by [halex2005](mailto:akharlov@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #pragma once #ifndef PRODUCT_VERSION_MAJOR #define PRODUCT_VERSION_MAJOR @PRODUCT_VERSION_MAJOR@ #endif #ifndef PRODUCT_VERSION_MINOR #define PRODUCT_VERSION_MINOR @PRODUCT_VERSION_MINOR@ #endif #ifndef PRODUCT_VERSION_PATCH #define PRODUCT_VERSION_PATCH @PRODUCT_VERSION_PATCH@ #endif #ifndef PRODUCT_VERSION_BUILD #define PRODUCT_VERSION_BUILD @PRODUCT_VERSION_REVISION@ #endif #ifndef FILE_VERSION_MAJOR #define FILE_VERSION_MAJOR @PRODUCT_VERSION_MAJOR@ #endif #ifndef FILE_VERSION_MINOR #define FILE_VERSION_MINOR @PRODUCT_VERSION_MINOR@ #endif #ifndef FILE_VERSION_PATCH #define FILE_VERSION_PATCH @PRODUCT_VERSION_PATCH@ #endif #ifndef FILE_VERSION_BUILD #define FILE_VERSION_BUILD @PRODUCT_VERSION_REVISION@ #endif #ifndef __TO_STRING #define __TO_STRING_IMPL(x) #x #define __TO_STRING(x) __TO_STRING_IMPL(x) #endif #define PRODUCT_VERSION_MAJOR_MINOR_STR __TO_STRING(PRODUCT_VERSION_MAJOR) "." __TO_STRING(PRODUCT_VERSION_MINOR) #define PRODUCT_VERSION_MAJOR_MINOR_PATCH_STR PRODUCT_VERSION_MAJOR_MINOR_STR "." __TO_STRING(PRODUCT_VERSION_PATCH) #define PRODUCT_VERSION_FULL_STR PRODUCT_VERSION_MAJOR_MINOR_PATCH_STR "." __TO_STRING(PRODUCT_VERSION_BUILD) #define PRODUCT_VERSION_RESOURCE PRODUCT_VERSION_MAJOR,PRODUCT_VERSION_MINOR,PRODUCT_VERSION_PATCH,PRODUCT_VERSION_BUILD #define PRODUCT_VERSION_RESOURCE_STR PRODUCT_VERSION_FULL_STR "\0" #define FILE_VERSION_MAJOR_MINOR_STR __TO_STRING(FILE_VERSION_MAJOR) "." __TO_STRING(FILE_VERSION_MINOR) #define FILE_VERSION_MAJOR_MINOR_PATCH_STR FILE_VERSION_MAJOR_MINOR_STR "." __TO_STRING(FILE_VERSION_PATCH) #define FILE_VERSION_FULL_STR FILE_VERSION_MAJOR_MINOR_PATCH_STR "." __TO_STRING(FILE_VERSION_BUILD) #define FILE_VERSION_RESOURCE FILE_VERSION_MAJOR,FILE_VERSION_MINOR,FILE_VERSION_PATCH,FILE_VERSION_BUILD #define FILE_VERSION_RESOURCE_STR FILE_VERSION_FULL_STR "\0" #ifndef USE_ICON #define USE_ICON @USE_ICON@ #endif #if USE_ICON #ifndef PRODUCT_ICON #define PRODUCT_ICON "@PRODUCT_ICON@" #endif #endif #ifndef PRODUCT_COMMENTS #define PRODUCT_COMMENTS "@PRODUCT_COMMENTS@\0" #endif #ifndef PRODUCT_COMPANY_NAME #define PRODUCT_COMPANY_NAME "@PRODUCT_COMPANY_NAME@\0" #endif #ifndef PRODUCT_COMPANY_COPYRIGHT #define PRODUCT_COMPANY_COPYRIGHT "@PRODUCT_COMPANY_COPYRIGHT@\0" #endif #ifndef PRODUCT_FILE_DESCRIPTION #define PRODUCT_FILE_DESCRIPTION "@PRODUCT_FILE_DESCRIPTION@\0" #endif #ifndef PRODUCT_INTERNAL_NAME #define PRODUCT_INTERNAL_NAME "@PRODUCT_NAME@\0" #endif #ifndef PRODUCT_ORIGINAL_FILENAME #define PRODUCT_ORIGINAL_FILENAME "@PRODUCT_ORIGINAL_FILENAME@\0" #endif #ifndef PRODUCT_BUNDLE #define PRODUCT_BUNDLE "@PRODUCT_BUNDLE@\0" #endif Qt-Color-Widgets-v2.2.0/cmake/modules/VersionResource.rc000066400000000000000000000044521366475014400231770ustar00rootroot00000000000000/* The MIT License (MIT) Copyright (c) 2015, by [halex2005](mailto:akharlov@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "VersionInfo.h" #include "winresrc.h" #if USE_ICON IDI_ICON1 ICON PRODUCT_ICON #endif LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT VS_VERSION_INFO VERSIONINFO FILEVERSION FILE_VERSION_RESOURCE PRODUCTVERSION PRODUCT_VERSION_RESOURCE FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x4L FILETYPE 0x1L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "041904b0" BEGIN VALUE "Comments", PRODUCT_COMMENTS VALUE "CompanyName", PRODUCT_COMPANY_NAME VALUE "FileDescription", PRODUCT_FILE_DESCRIPTION VALUE "FileVersion", FILE_VERSION_RESOURCE_STR VALUE "InternalName", PRODUCT_INTERNAL_NAME VALUE "LegalCopyright", PRODUCT_COMPANY_COPYRIGHT VALUE "OriginalFilename", PRODUCT_ORIGINAL_FILENAME VALUE "ProductName", PRODUCT_BUNDLE VALUE "ProductVersion", PRODUCT_VERSION_RESOURCE_STR END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x419, 1200 END END Qt-Color-Widgets-v2.2.0/cmake/modules/generate_product_version.cmake000066400000000000000000000133261366475014400256150ustar00rootroot00000000000000# The MIT License (MIT) # Copyright (c) 2015, by [halex2005](mailto:akharlov@gmail.com) # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. include (CMakeParseArguments) set (GenerateProductVersionCurrentDir ${CMAKE_CURRENT_LIST_DIR}) # generate_product_version() function # # This function uses VersionInfo.in template file and VersionResource.rc file # to generate WIN32 resource with version information and general resource strings. # # Usage: # generate_product_version( # SomeOutputResourceVariable # NAME MyGreatProject # ICON ${PATH_TO_APP_ICON} # VERSION_MAJOR 2 # VERSION_MINOR 3 # VERSION_PATH ${BUILD_COUNTER} # VERSION_REVISION ${BUILD_REVISION} # ) # where BUILD_COUNTER and BUILD_REVISION could be values from your CI server. # # You can use generated resource for your executable targets: # add_executable(target-name ${target-files} ${SomeOutputResourceVariable}) # # You can specify resource strings in arguments: # NAME - name of executable (no defaults, ex: Microsoft Word) # BUNDLE - bundle (${NAME} is default, ex: Microsoft Office) # USE_ICON - flag that shows whether icon is used or not # ICON - path to application icon (${CMAKE_SOURCE_DIR}/product.ico by default) # VERSION_MAJOR - 1 is default # VERSION_MINOR - 0 is default # VERSION_PATCH - 0 is default # VERSION_REVISION - 0 is default # COMPANY_NAME - your company name (no defaults) # COMPANY_COPYRIGHT - ${COMPANY_NAME} (C) Copyright ${CURRENT_YEAR} is default # COMMENTS - ${NAME} v${VERSION_MAJOR}.${VERSION_MINOR} is default # ORIGINAL_FILENAME - ${NAME} is default # INTERNAL_NAME - ${NAME} is default # FILE_DESCRIPTION - ${NAME} is default function(generate_product_version outfiles) set (options) set (oneValueArgs NAME BUNDLE USE_ICON ICON VERSION_MAJOR VERSION_MINOR VERSION_PATCH VERSION_REVISION COMPANY_NAME COMPANY_COPYRIGHT COMMENTS ORIGINAL_FILENAME INTERNAL_NAME FILE_DESCRIPTION) set (multiValueArgs) cmake_parse_arguments(PRODUCT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if (NOT PRODUCT_BUNDLE OR "${PRODUCT_BUNDLE}" STREQUAL "") set(PRODUCT_BUNDLE "${PRODUCT_NAME}") endif() if (USE_ICON) if (NOT PRODUCT_ICON OR "${PRODUCT_ICON}" STREQUAL "") set(PRODUCT_ICON "${CMAKE_SOURCE_DIR}/product.ico") endif() else () set (USE_ICON 0) endif () if (NOT PRODUCT_VERSION_MAJOR EQUAL 0 AND (NOT PRODUCT_VERSION_MAJOR OR "${PRODUCT_VERSION_MAJOR}" STREQUAL "")) set(PRODUCT_VERSION_MAJOR 1) endif() if (NOT PRODUCT_VERSION_MINOR EQUAL 0 AND (NOT PRODUCT_VERSION_MINOR OR "${PRODUCT_VERSION_MINOR}" STREQUAL "")) set(PRODUCT_VERSION_MINOR 0) endif() if (NOT PRODUCT_VERSION_PATCH EQUAL 0 AND (NOT PRODUCT_VERSION_PATCH OR "${PRODUCT_VERSION_PATCH}" STREQUAL "")) set(PRODUCT_VERSION_PATCH 0) endif() if (NOT PRODUCT_VERSION_REVISION EQUAL 0 AND (NOT PRODUCT_VERSION_REVISION OR "${PRODUCT_VERSION_REVISION}" STREQUAL "")) set(PRODUCT_VERSION_REVISION 0) endif() if (NOT PRODUCT_COMPANY_COPYRIGHT OR "${PRODUCT_COMPANY_COPYRIGHT}" STREQUAL "") string(TIMESTAMP PRODUCT_CURRENT_YEAR "%Y") set(PRODUCT_COMPANY_COPYRIGHT "${PRODUCT_COMPANY_NAME} (C) Copyright ${PRODUCT_CURRENT_YEAR}") endif() if (NOT PRODUCT_COMMENTS OR "${PRODUCT_COMMENTS}" STREQUAL "") set(PRODUCT_COMMENTS "${PRODUCT_NAME} v${PRODUCT_VERSION_MAJOR}.${PRODUCT_VERSION_MINOR}") endif() if (NOT PRODUCT_ORIGINAL_FILENAME OR "${PRODUCT_ORIGINAL_FILENAME}" STREQUAL "") set(PRODUCT_ORIGINAL_FILENAME "${PRODUCT_NAME}") endif() if (NOT PRODUCT_INTERNAL_NAME OR "${PRODUCT_INTERNAL_NAME}" STREQUAL "") set(PRODUCT_INTERNAL_NAME "${PRODUCT_NAME}") endif() if (NOT PRODUCT_FILE_DESCRIPTION OR "${PRODUCT_FILE_DESCRIPTION}" STREQUAL "") set(PRODUCT_FILE_DESCRIPTION "${PRODUCT_NAME}") endif() set (_VersionInfoFile ${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.h) set (_VersionResourceFile ${CMAKE_CURRENT_BINARY_DIR}/VersionResource.rc) configure_file( ${GenerateProductVersionCurrentDir}/VersionInfo.in ${_VersionInfoFile} @ONLY) configure_file( ${GenerateProductVersionCurrentDir}/VersionResource.rc ${_VersionResourceFile} COPYONLY) list(APPEND ${outfiles} ${_VersionInfoFile} ${_VersionResourceFile}) set (${outfiles} ${${outfiles}} PARENT_SCOPE) endfunction() Qt-Color-Widgets-v2.2.0/cmake/qt-configuration.cmake000066400000000000000000000035221366475014400223340ustar00rootroot00000000000000function (select_qt QT_SUPPORTED_VERSIONS i_qt_supported_versions QT_DEFAULT_VERSION i_default_qt_version) set (QT_VERSION ${i_default_qt_version} CACHE STRING "Qt version to build against") set_property ( CACHE QT_VERSION PROPERTY STRINGS ${i_qt_supported_versions}) endfunction (select_qt) macro (find_qt QT_SUPPORTED_VERSIONS i_qt_supported_versions REQUIRED_COMPONENTS i_required_components OPTIONAL_COMPONENTS i_optional_components) # Auto generate moc files if (4 EQUAL QT_VERSION) find_package (Qt4 4.8 REQUIRED COMPONENTS ${i_required_components} OPTIONAL_COMPONENTS ${i_optional_components}) elseif (5 EQUAL QT_VERSION) find_package (Qt5 5.9 REQUIRED COMPONENTS ${i_required_components} OPTIONAL_COMPONENTS ${i_optional_components}) else (5 EQUAL QT_VERSION) message (FATAL_ERROR "Unsupported version of Qt: ${QT_VERSION}") endif (4 EQUAL QT_VERSION) endmacro (find_qt) function (use_qt TARGET_NAME i_target_name QT_SUPPORTED_VERSIONS i_qt_supported_versions REQUIRED_COMPONENTS i_required_components OPTIONAL_COMPONENTS i_optional_components) if (4 EQUAL QT_VERSION) foreach (COMPONENT IN LISTS i_required_components, i_optional_components) target_link_libraries (${i_target_name} PRIVATE Qt4::${COMPONENT} ) endforeach (COMPONENT IN LISTS i_required_components, i_optional_components) elseif (5 EQUAL QT_VERSION) foreach (COMPONENT IN LISTS i_required_components) target_link_libraries (${i_target_name} PRIVATE Qt5::${COMPONENT} ) endforeach (COMPONENT IN LISTS i_required_components, i_optional_components) else (5 EQUAL QT_VERSION) message (FATAL_ERROR "Unsupported version of Qt: ${QT_VERSION}") endif (4 EQUAL QT_VERSION) endfunction (use_qt) Qt-Color-Widgets-v2.2.0/cmake/versioning.cmake000066400000000000000000000026451366475014400212330ustar00rootroot00000000000000include (ProjectVersioning) function (generate_versioning_information TARGET_NAME i_target_name EXPORT_HEADER i_export_header EXPORT_MACRO i_export_macro VERSIONED_ENTITY i_versioned_entity INCLUDE_PREFIX i_include_prefix COMPANY_NAME i_company_name COMPANY_COPYRIGHT i_company_copyright FILE_DESCRIPTION i_file_description ) target_version_information ( TARGET_NAME ${i_target_name} EXPORT_HEADER ${i_export_header} EXPORT_MACRO ${i_export_macro} VERSIONED_ENTITY ${i_versioned_entity} ) if (WIN32) include (generate_product_version) get_target_property (gitDescribe ${i_target_name} GIT_DESCRIBE) get_target_property (gitUntracked ${i_target_name} GIT_UNTRACKED_FILES) generate_product_version ( win32VersionInfoFiles NAME ${i_versioned_entity} VERSION_MAJOR ${${i_versioned_entity}_VERSION_MAJOR} VERSION_MINOR ${${i_versioned_entity}_VERSION_MINOR} VERSION_PATCH ${${i_versioned_entity}_VERSION_PATCH} COMPANY_NAME ${i_company_name} COMPANY_COPYRIGHT ${i_company_copyright} COMMENTS "${gitDescribe}${gitUntracked}" FILE_DESCRIPTION ${i_file_description} ) target_sources (${i_target_name} PRIVATE ${win32VersionInfoFiles}) endif (WIN32) endfunction (generate_versioning_information) Qt-Color-Widgets-v2.2.0/color_widgets.pri000066400000000000000000000065231366475014400203450ustar00rootroot00000000000000# Copyright (C) 2013-2019 Mattia Basaglia # # # This software is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This software is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Color Widgets. If not, see . CONFIG += c++11 INCLUDEPATH += $$PWD/src $$PWD/include SOURCES += \ $$PWD/src/QtColorWidgets/abstract_widget_list.cpp \ $$PWD/src/QtColorWidgets/bound_color_selector.cpp \ $$PWD/src/QtColorWidgets/color_2d_slider.cpp \ $$PWD/src/QtColorWidgets/color_delegate.cpp \ $$PWD/src/QtColorWidgets/color_dialog.cpp \ $$PWD/src/QtColorWidgets/color_line_edit.cpp \ $$PWD/src/QtColorWidgets/color_list_widget.cpp \ $$PWD/src/QtColorWidgets/color_names.cpp \ $$PWD/src/QtColorWidgets/color_palette.cpp \ $$PWD/src/QtColorWidgets/color_palette_model.cpp \ $$PWD/src/QtColorWidgets/color_palette_widget.cpp \ $$PWD/src/QtColorWidgets/color_preview.cpp \ $$PWD/src/QtColorWidgets/color_selector.cpp \ $$PWD/src/QtColorWidgets/color_utils.cpp \ $$PWD/src/QtColorWidgets/color_wheel.cpp \ $$PWD/src/QtColorWidgets/gradient_editor.cpp \ $$PWD/src/QtColorWidgets/gradient_list_model.cpp \ $$PWD/src/QtColorWidgets/gradient_slider.cpp \ $$PWD/src/QtColorWidgets/harmony_color_wheel.cpp \ $$PWD/src/QtColorWidgets/hue_slider.cpp \ $$PWD/src/QtColorWidgets/swatch.cpp HEADERS += \ $$PWD/include/QtColorWidgets/abstract_widget_list.hpp \ $$PWD/include/QtColorWidgets/bound_color_selector.hpp \ $$PWD/include/QtColorWidgets/color_2d_slider.hpp \ $$PWD/include/QtColorWidgets/color_delegate.hpp \ $$PWD/include/QtColorWidgets/color_dialog.hpp \ $$PWD/include/QtColorWidgets/color_line_edit.hpp \ $$PWD/include/QtColorWidgets/color_list_widget.hpp \ $$PWD/include/QtColorWidgets/color_names.hpp \ $$PWD/include/QtColorWidgets/color_palette.hpp \ $$PWD/include/QtColorWidgets/color_palette_model.hpp \ $$PWD/include/QtColorWidgets/color_palette_widget.hpp \ $$PWD/include/QtColorWidgets/color_preview.hpp \ $$PWD/include/QtColorWidgets/color_selector.hpp \ $$PWD/include/QtColorWidgets/color_utils.hpp \ $$PWD/include/QtColorWidgets/color_wheel.hpp \ $$PWD/include/QtColorWidgets/color_wheel_private.hpp \ $$PWD/include/QtColorWidgets/colorwidgets_global.hpp \ $$PWD/include/QtColorWidgets/gradient_delegate.hpp \ $$PWD/include/QtColorWidgets/gradient_editor.hpp \ $$PWD/include/QtColorWidgets/gradient_helper.hpp \ $$PWD/include/QtColorWidgets/gradient_list_model.hpp \ $$PWD/include/QtColorWidgets/gradient_slider.hpp \ $$PWD/include/QtColorWidgets/harmony_color_wheel.hpp \ $$PWD/include/QtColorWidgets/hue_slider.hpp \ $$PWD/include/QtColorWidgets/swatch.hpp FORMS += \ $$PWD/src/QtColorWidgets/color_dialog.ui \ $$PWD/src/QtColorWidgets/color_palette_widget.ui RESOURCES += \ $$PWD/resources/QtColorWidgets/color_widgets.qrc Qt-Color-Widgets-v2.2.0/color_widgets.pro000066400000000000000000000023761366475014400203550ustar00rootroot00000000000000# # Copyright (C) 2013-2020 Mattia Basaglia # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # TEMPLATE=lib CONFIG += dll QT += core gui widgets DEFINES += QTCOLORWIDGETS_LIBRARY TARGET=QtColorWidgets-Qt5 VERSION=2.2.0 OBJECTS_DIR = out/obj MOC_DIR = out/generated UI_DIR = out/generated RCC_DIR = out/generated include(color_widgets.pri) build_all:!build_pass { CONFIG -= build_all CONFIG += release } unix { LIB_TARGET = lib$${TARGET}.so } win32 { LIB_TARGET = $${TARGET}.dll } isEmpty(PREFIX) { PREFIX = /usr/local } target.path = $$PREFIX/lib headers.path = $$PREFIX/include/QtColorWidgets headers.files = $$HEADERS INSTALLS += target headers Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/000077500000000000000000000000001366475014400230615ustar00rootroot00000000000000Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/CMakeLists.txt000066400000000000000000000117721366475014400256310ustar00rootroot00000000000000# Copyright (C) 2013-2020 Mattia Basaglia # # # This software is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This software is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Color Widgets. If not, see . cmake_minimum_required (VERSION 3.1 FATAL_ERROR) project(QtColorWidgetsPlugin CXX) set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake/modules ${CMAKE_CURRENT_LIST_DIR}/..) include (CheckCXXCompilerFlag) include (../cmake/qt-configuration.cmake) include (../cmake/versioning.cmake) SET (${PROJECT_NAME}_VERSION_MAJOR 2) SET (${PROJECT_NAME}_VERSION_MINOR 2) SET (${PROJECT_NAME}_VERSION_PATCH 0) SET (${PROJECT_NAME}_VERSION "${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}.${${PROJECT_NAME}_VERSION_PATCH}") set (QT_SUPPORTED_VERSIONS 5) select_qt ( QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}" QT_DEFAULT_VERSION 5) set (REQUIRED_QT_COMPONENTS Designer ) find_qt ( QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}" REQUIRED_COMPONENTS "${REQUIRED_QT_COMPONENTS}" OPTIONAL_COMPONENTS "") # Auto generate moc files set(CMAKE_AUTOMOC ON) # Auto generate moc files set(CMAKE_AUTOUIC ON) # Auto generate moc files set(CMAKE_AUTORCC ON) check_cxx_compiler_flag ("-Wall" Wall_FLAG_SUPPORTED) if (Wall_FLAG_SUPPORTED) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall") endif (Wall_FLAG_SUPPORTED) check_cxx_compiler_flag ("-pedantic" pedantic_FLAG_SUPPORTED) if (pedantic_FLAG_SUPPORTED) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pedantic") endif (pedantic_FLAG_SUPPORTED) check_cxx_compiler_flag ("-Wextra" Wextra_FLAG_SUPPORTED) if (Wextra_FLAG_SUPPORTED) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wextra") endif (Wextra_FLAG_SUPPORTED) # Library set (TARGET_NAME ${PROJECT_NAME}) set (TARGET_OUTPUT_SUFFIX "-Qt${QT_VERSION}${${PROJECT_NAME}_VERSION_MAJOR}") add_library (${TARGET_NAME} SHARED "") set_target_properties(${TARGET_NAME} PROPERTIES EXPORT_NAME "${TARGET_NAME}${TARGET_OUTPUT_SUFFIX}") set_target_properties (${TARGET_NAME} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON VERSION ${${PROJECT_NAME}_VERSION} SOVERSION ${${PROJECT_NAME}_VERSION_MAJOR} "INTERFACE_${PROJECT_NAME}_MAJOR_VERSION" ${${PROJECT_NAME}_VERSION_MAJOR} COMPATIBLE_INTERFACE_STRING "${PROJECT_NAME}_MAJOR_VERSION" OUTPUT_NAME "${TARGET_NAME}${TARGET_OUTPUT_SUFFIX}") target_link_libraries(${TARGET_NAME} PRIVATE ${COLOR_WIDGETS_LIBRARY}) use_qt ( TARGET_NAME ${TARGET_NAME} QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}" REQUIRED_COMPONENTS "${REQUIRED_QT_COMPONENTS}" OPTIONAL_COMPONENTS "") # Sources set(SOURCES color_preview_plugin.cpp color_wheel_plugin.cpp color_widget_plugin_collection.cpp gradient_slider_plugin.cpp hue_slider_plugin.cpp color_selector_plugin.cpp color_list_plugin.cpp swatch_plugin.cpp color_palette_widget_plugin.cpp color_2d_slider_plugin.cpp color_line_edit_plugin.cpp gradient_editor_plugin.cpp # add new sources above this line ) foreach (SOURCE IN LISTS SOURCES) target_sources (${TARGET_NAME} PRIVATE $) endforeach (SOURCE IN SOURCES) set(HEADERS color_preview_plugin.hpp color_wheel_plugin.hpp color_widget_plugin_collection.hpp gradient_slider_plugin.hpp hue_slider_plugin.hpp color_selector_plugin.hpp color_list_plugin.hpp swatch_plugin.hpp color_palette_widget_plugin.hpp color_2d_slider_plugin.hpp color_line_edit_plugin.hpp gradient_editor_plugin.hpp # add new headers above this line ) foreach (HEADER IN LISTS HEADERS) target_sources (${TARGET_NAME} PRIVATE $) endforeach (HEADER IN HEADERS) # install get_target_property (QT_QMAKE_EXECUTABLE Qt5::qmake LOCATION) execute_process ( COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_PLUGINS OUTPUT_VARIABLE QT_INSTALL_PLUGINS OUTPUT_STRIP_TRAILING_WHITESPACE) # install(TARGETS ${COLOR_WIDGETS_PLUGIN} DESTINATION ${QT_INSTALL_PLUGINS}/designer OPTIONAL) execute_process ( COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_LIBS OUTPUT_VARIABLE QT_INSTALL_LIBS OUTPUT_STRIP_TRAILING_WHITESPACE) # install(TARGETS ${COLOR_WIDGETS_PLUGIN} DESTINATION ${QT_INSTALL_LIBS}/qtcreator/plugins OPTIONAL) add_custom_target(${TARGET_NAME}_install COMMAND cp $ ${QT_INSTALL_PLUGINS}/designer COMMAND cp $ ${QT_INSTALL_LIBS}/qtcreator/plugins DEPENDS ${TARGET_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/color_2d_slider_plugin.cpp000066400000000000000000000042311366475014400302100ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "color_2d_slider_plugin.hpp" #include "QtColorWidgets/color_2d_slider.hpp" Color2DSlider_Plugin::Color2DSlider_Plugin(QObject *parent) : QObject(parent), initialized(false) { } void Color2DSlider_Plugin::initialize(QDesignerFormEditorInterface *) { initialized = true; } bool Color2DSlider_Plugin::isInitialized() const { return initialized; } QWidget *Color2DSlider_Plugin::createWidget(QWidget *parent) { return new color_widgets::Color2DSlider(parent); } QString Color2DSlider_Plugin::name() const { return "color_widgets::Color2DSlider"; } QString Color2DSlider_Plugin::group() const { return "Color Widgets"; } QIcon Color2DSlider_Plugin::icon() const { color_widgets::Color2DSlider w; w.resize(64,64); QPixmap pix(64,64); w.render(&pix); return QIcon(pix); } QString Color2DSlider_Plugin::toolTip() const { return "An analog widget to select 2 color components at the same time"; } QString Color2DSlider_Plugin::whatsThis() const { return toolTip(); } bool Color2DSlider_Plugin::isContainer() const { return false; } QString Color2DSlider_Plugin::domXml() const { return "\n" " \n" " \n" "\n"; } QString Color2DSlider_Plugin::includeFile() const { return "QtColorWidgets/color_2d_slider.hpp"; } Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/color_2d_slider_plugin.hpp000066400000000000000000000031061366475014400302150ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_WIDGETS_COLOR_2D_SLIDER_PLUGIN_HPP #define COLOR_WIDGETS_COLOR_2D_SLIDER_PLUGIN_HPP #include #include class Color2DSlider_Plugin : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: Color2DSlider_Plugin(QObject *parent = 0); void initialize(QDesignerFormEditorInterface *core); bool isInitialized() const; QWidget *createWidget(QWidget *parent); QString name() const; QString group() const; QIcon icon() const; QString toolTip() const; QString whatsThis() const; bool isContainer() const; QString domXml() const; QString includeFile() const; private: bool initialized; }; #endif // COLOR_WIDGETS_COLOR_2D_SLIDER_PLUGIN_HPP Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/color_line_edit_plugin.cpp000066400000000000000000000041641366475014400303020ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "color_line_edit_plugin.hpp" #include "QtColorWidgets/color_line_edit.hpp" QWidget* ColorLineEdit_Plugin::createWidget(QWidget *parent) { color_widgets::ColorLineEdit *widget = new color_widgets::ColorLineEdit(parent); return widget; } QIcon ColorLineEdit_Plugin::icon() const { return QIcon::fromTheme("edit-rename"); } QString ColorLineEdit_Plugin::domXml() const { return "\n" " \n" " \n" "\n"; } bool ColorLineEdit_Plugin::isContainer() const { return false; } ColorLineEdit_Plugin::ColorLineEdit_Plugin(QObject *parent) : QObject(parent), initialized(false) { } void ColorLineEdit_Plugin::initialize(QDesignerFormEditorInterface *) { initialized = true; } bool ColorLineEdit_Plugin::isInitialized() const { return initialized; } QString ColorLineEdit_Plugin::name() const { return "color_widgets::ColorLineEdit"; } QString ColorLineEdit_Plugin::group() const { return "Color Widgets"; } QString ColorLineEdit_Plugin::toolTip() const { return "A widget to manipulate a string representing a color"; } QString ColorLineEdit_Plugin::whatsThis() const { return toolTip(); } QString ColorLineEdit_Plugin::includeFile() const { return "QtColorWidgets/color_line_edit.hpp"; } Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/color_line_edit_plugin.hpp000066400000000000000000000034061366475014400303050ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_WIDGETS_COLOR_LINE_EDIT_PLUGIN_HPP #define COLOR_WIDGETS_COLOR_LINE_EDIT_PLUGIN_HPP #include #include class ColorLineEdit_Plugin : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: explicit ColorLineEdit_Plugin(QObject *parent = nullptr); void initialize(QDesignerFormEditorInterface *core) Q_DECL_OVERRIDE; bool isInitialized() const Q_DECL_OVERRIDE; QWidget *createWidget(QWidget *parent) Q_DECL_OVERRIDE; QString name() const Q_DECL_OVERRIDE; QString group() const Q_DECL_OVERRIDE; QIcon icon() const Q_DECL_OVERRIDE; QString toolTip() const Q_DECL_OVERRIDE; QString whatsThis() const Q_DECL_OVERRIDE; bool isContainer() const Q_DECL_OVERRIDE; QString domXml() const Q_DECL_OVERRIDE; QString includeFile() const Q_DECL_OVERRIDE; private: bool initialized; }; #endif // COLOR_WIDGETS_COLOR_LINE_EDIT_PLUGIN_HPP Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/color_list_plugin.cpp000066400000000000000000000040751366475014400273220ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "color_list_plugin.hpp" #include "QtColorWidgets/color_list_widget.hpp" ColorListWidget_Plugin::ColorListWidget_Plugin(QObject *parent) : QObject(parent) { } void ColorListWidget_Plugin::initialize(QDesignerFormEditorInterface *) { initialized = true; } bool ColorListWidget_Plugin::isInitialized() const { return initialized; } QWidget *ColorListWidget_Plugin::createWidget(QWidget *parent) { return new color_widgets::ColorListWidget(parent); } QString ColorListWidget_Plugin::name() const { return "color_widgets::ColorListWidget"; } QString ColorListWidget_Plugin::group() const { return "Color Widgets"; } QIcon ColorListWidget_Plugin::icon() const { return QIcon::fromTheme("format-stroke-color"); } QString ColorListWidget_Plugin::toolTip() const { return "An editable list of colors"; } QString ColorListWidget_Plugin::whatsThis() const { return toolTip(); } bool ColorListWidget_Plugin::isContainer() const { return false; } QString ColorListWidget_Plugin::domXml() const { return "\n" " \n" " \n" "\n"; } QString ColorListWidget_Plugin::includeFile() const { return "QtColorWidgets/color_list_widget.hpp"; } Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/color_list_plugin.hpp000066400000000000000000000030171366475014400273220ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_LIST_PLUGIN_HPP #define COLOR_LIST_PLUGIN_HPP #include class ColorListWidget_Plugin : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: explicit ColorListWidget_Plugin(QObject *parent = 0); void initialize(QDesignerFormEditorInterface *core); bool isInitialized() const; QWidget *createWidget(QWidget *parent); QString name() const; QString group() const; QIcon icon() const; QString toolTip() const; QString whatsThis() const; bool isContainer() const; QString domXml() const; QString includeFile() const; private: bool initialized; }; #endif // COLOR_LIST_PLUGIN_HPP Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/color_palette_widget_plugin.cpp000066400000000000000000000063071366475014400313500ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "color_palette_widget_plugin.hpp" #include "QtColorWidgets/color_palette_widget.hpp" ColorPaletteWidget_Plugin::ColorPaletteWidget_Plugin(QObject *parent) : QObject(parent), initialized(false) { } void ColorPaletteWidget_Plugin::initialize(QDesignerFormEditorInterface *) { initialized = true; } bool ColorPaletteWidget_Plugin::isInitialized() const { return initialized; } QWidget* ColorPaletteWidget_Plugin::createWidget(QWidget *parent) { color_widgets::ColorPaletteWidget *wid = new color_widgets::ColorPaletteWidget(parent); color_widgets::ColorPalette palette1; color_widgets::ColorPalette palette2; int columns = 12; palette1.setName("Palette 1"); palette2.setName("Palette 2"); palette1.setColumns(columns); palette2.setColumns(columns); for ( int i = 0; i < 6; i++ ) { for ( int j = 0; j < columns; j++ ) { float f = float(j)/columns; palette1.appendColor(QColor::fromHsvF(i/8.0,1-f,0.5+f/2)); palette2.appendColor(QColor::fromHsvF(i/8.0,1-f,1-f)); } } color_widgets::ColorPaletteModel *model = new color_widgets::ColorPaletteModel; model->setParent(wid); model->addPalette(palette1, false); model->addPalette(palette2, false); wid->setModel(model); return wid; } QString ColorPaletteWidget_Plugin::name() const { return "color_widgets::ColorPaletteWidget"; } QString ColorPaletteWidget_Plugin::group() const { return "Color Widgets"; } QIcon ColorPaletteWidget_Plugin::icon() const { color_widgets::ColorPalette w; w.setColumns(6); for ( int i = 0; i < 4; i++ ) { for ( int j = 0; j < w.columns(); j++ ) { float f = float(j)/w.columns(); w.appendColor(QColor::fromHsvF(i/5.0,1-f,0.5+f/2)); } } return QIcon(w.preview(QSize(64,64))); } QString ColorPaletteWidget_Plugin::toolTip() const { return "A widget that displays a color palette"; } QString ColorPaletteWidget_Plugin::whatsThis() const { return toolTip(); } bool ColorPaletteWidget_Plugin::isContainer() const { return false; } QString ColorPaletteWidget_Plugin::domXml() const { return "\n" " \n" " \n" "\n"; } QString ColorPaletteWidget_Plugin::includeFile() const { return "QtColorWidgets/color_palette_widget.hpp"; } Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/color_palette_widget_plugin.hpp000066400000000000000000000031371366475014400313530ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_WIDGETS_COLOR_PALETTE_WIDGET_PLUGIN_HPP #define COLOR_WIDGETS_COLOR_PALETTE_WIDGET_PLUGIN_HPP #include #include class ColorPaletteWidget_Plugin : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: ColorPaletteWidget_Plugin(QObject *parent = 0); void initialize(QDesignerFormEditorInterface *core); bool isInitialized() const; QWidget *createWidget(QWidget *parent); QString name() const; QString group() const; QIcon icon() const; QString toolTip() const; QString whatsThis() const; bool isContainer() const; QString domXml() const; QString includeFile() const; private: bool initialized; }; #endif // COLOR_WIDGETS_COLOR_PALETTE_WIDGET_PLUGIN_HPP Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/color_preview_plugin.cpp000066400000000000000000000041421366475014400300230ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "color_preview_plugin.hpp" #include "QtColorWidgets/color_preview.hpp" #include ColorPreview_Plugin::ColorPreview_Plugin(QObject *parent) : QObject(parent), initialized(false) { } void ColorPreview_Plugin::initialize(QDesignerFormEditorInterface *) { if (initialized) return; initialized = true; } bool ColorPreview_Plugin::isInitialized() const { return initialized; } QWidget *ColorPreview_Plugin::createWidget(QWidget *parent) { return new color_widgets::ColorPreview(parent); } QString ColorPreview_Plugin::name() const { return "color_widgets::ColorPreview"; } QString ColorPreview_Plugin::group() const { return "Color Widgets"; } QIcon ColorPreview_Plugin::icon() const { return QIcon(); } QString ColorPreview_Plugin::toolTip() const { return "Display a color"; } QString ColorPreview_Plugin::whatsThis() const { return toolTip(); } bool ColorPreview_Plugin::isContainer() const { return false; } QString ColorPreview_Plugin::domXml() const { return "\n" " \n" " \n" "\n"; } QString ColorPreview_Plugin::includeFile() const { return "QtColorWidgets/color_preview.hpp"; } //Q_EXPORT_PLUGIN2(color_widgets, ColorPreview_Plugin); Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/color_preview_plugin.hpp000066400000000000000000000030001366475014400300200ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_PREVIEW_PLUGIN_HPP #define COLOR_PREVIEW_PLUGIN_HPP #include class ColorPreview_Plugin : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: ColorPreview_Plugin(QObject *parent = 0); void initialize(QDesignerFormEditorInterface *core); bool isInitialized() const; QWidget *createWidget(QWidget *parent); QString name() const; QString group() const; QIcon icon() const; QString toolTip() const; QString whatsThis() const; bool isContainer() const; QString domXml() const; QString includeFile() const; private: bool initialized; }; #endif // COLOR_PREVIEW_PLUGIN_HPP Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/color_selector_plugin.cpp000066400000000000000000000041361366475014400301650ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "color_selector_plugin.hpp" #include "QtColorWidgets/color_selector.hpp" #include ColorSelector_Plugin::ColorSelector_Plugin(QObject *parent) : QObject(parent), initialized(false) { } void ColorSelector_Plugin::initialize(QDesignerFormEditorInterface *) { if (initialized) return; initialized = true; } bool ColorSelector_Plugin::isInitialized() const { return initialized; } QWidget *ColorSelector_Plugin::createWidget(QWidget *parent) { return new color_widgets::ColorSelector(parent); } QString ColorSelector_Plugin::name() const { return "color_widgets::ColorSelector"; } QString ColorSelector_Plugin::group() const { return "Color Widgets"; } QIcon ColorSelector_Plugin::icon() const { return QIcon(); } QString ColorSelector_Plugin::toolTip() const { return "Display a color and opens a color dialog on click"; } QString ColorSelector_Plugin::whatsThis() const { return toolTip(); } bool ColorSelector_Plugin::isContainer() const { return false; } QString ColorSelector_Plugin::domXml() const { return "\n" " \n" " \n" "\n"; } QString ColorSelector_Plugin::includeFile() const { return "QtColorWidgets/color_selector.hpp"; } Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/color_selector_plugin.hpp000066400000000000000000000030051366475014400301640ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_SELECTOR_PLUGIN_HPP #define COLOR_SELECTOR_PLUGIN_HPP #include class ColorSelector_Plugin : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: ColorSelector_Plugin(QObject *parent = 0); void initialize(QDesignerFormEditorInterface *core); bool isInitialized() const; QWidget *createWidget(QWidget *parent); QString name() const; QString group() const; QIcon icon() const; QString toolTip() const; QString whatsThis() const; bool isContainer() const; QString domXml() const; QString includeFile() const; private: bool initialized; }; #endif // COLOR_SELECTOR_PLUGIN_HPP Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/color_wheel_plugin.cpp000066400000000000000000000046171366475014400274550ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "color_wheel_plugin.hpp" #include "QtColorWidgets/color_wheel.hpp" ColorWheel_Plugin::ColorWheel_Plugin(QObject *parent) : QObject(parent), initialized(false) { } void ColorWheel_Plugin::initialize(QDesignerFormEditorInterface *) { initialized = true; } bool ColorWheel_Plugin::isInitialized() const { return initialized; } QWidget *ColorWheel_Plugin::createWidget(QWidget *parent) { return new color_widgets::ColorWheel(parent); } QString ColorWheel_Plugin::name() const { return "color_widgets::ColorWheel"; } QString ColorWheel_Plugin::group() const { return "Color Widgets"; } QIcon ColorWheel_Plugin::icon() const { color_widgets::ColorWheel w; w.resize(64,64); w.setWheelWidth(8); QPixmap pix(64,64); w.render(&pix); return QIcon(pix); } QString ColorWheel_Plugin::toolTip() const { return "A widget that allows an intuitive selection of HSL parameters for a QColor"; } QString ColorWheel_Plugin::whatsThis() const { return toolTip(); } bool ColorWheel_Plugin::isContainer() const { return false; } QString ColorWheel_Plugin::domXml() const { return "\n" " \n" " \n" " \n" " 0\n" " 0\n" " \n" " \n" " \n" "\n"; } QString ColorWheel_Plugin::includeFile() const { return "QtColorWidgets/color_wheel.hpp"; } Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/color_wheel_plugin.hpp000066400000000000000000000030121366475014400274460ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_WHEEL_PLUGIN_HPP #define COLOR_WHEEL_PLUGIN_HPP #include #include class ColorWheel_Plugin : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: ColorWheel_Plugin(QObject *parent = 0); void initialize(QDesignerFormEditorInterface *core); bool isInitialized() const; QWidget *createWidget(QWidget *parent); QString name() const; QString group() const; QIcon icon() const; QString toolTip() const; QString whatsThis() const; bool isContainer() const; QString domXml() const; QString includeFile() const; private: bool initialized; }; #endif // COLOR_WHEEL_PLUGIN_HPP Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/color_widget_plugin_collection.cpp000066400000000000000000000041131366475014400320360ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "color_widget_plugin_collection.hpp" #include "color_preview_plugin.hpp" #include "color_wheel_plugin.hpp" #include "gradient_slider_plugin.hpp" #include "hue_slider_plugin.hpp" #include "color_selector_plugin.hpp" #include "color_list_plugin.hpp" #include "swatch_plugin.hpp" #include "color_palette_widget_plugin.hpp" #include "color_2d_slider_plugin.hpp" #include "color_line_edit_plugin.hpp" #include "gradient_editor_plugin.hpp" // add new plugin headers above this line ColorWidgets_PluginCollection::ColorWidgets_PluginCollection(QObject *parent) : QObject(parent) { widgets.push_back(new ColorPreview_Plugin(this)); widgets.push_back(new ColorWheel_Plugin(this)); widgets.push_back(new GradientSlider_Plugin(this)); widgets.push_back(new HueSlider_Plugin(this)); widgets.push_back(new ColorSelector_Plugin(this)); widgets.push_back(new ColorListWidget_Plugin(this)); widgets.push_back(new Swatch_Plugin(this)); widgets.push_back(new ColorPaletteWidget_Plugin(this)); widgets.push_back(new Color2DSlider_Plugin(this)); widgets.push_back(new ColorLineEdit_Plugin(this)); widgets.push_back(new GradientEditor_Plugin(this)); // add new plugins above this line } QList ColorWidgets_PluginCollection::customWidgets() const { return widgets; } Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/color_widget_plugin_collection.hpp000066400000000000000000000026271366475014400320530ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_WIDGET_PLUGIN_COLLECTION_HPP #define COLOR_WIDGET_PLUGIN_COLLECTION_HPP #include class ColorWidgets_PluginCollection : public QObject, public QDesignerCustomWidgetCollectionInterface { Q_OBJECT Q_PLUGIN_METADATA(IID "mattia.basaglia.ColorWidgetsPlugin") Q_INTERFACES(QDesignerCustomWidgetCollectionInterface) public: explicit ColorWidgets_PluginCollection(QObject *parent = 0); QList customWidgets() const; private: QList widgets; }; #endif // COLOR_WIDGET_PLUGIN_COLLECTION_HPP Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/gradient_editor_plugin.cpp000066400000000000000000000046151366475014400303140ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "gradient_editor_plugin.hpp" #include "QtColorWidgets/gradient_editor.hpp" QWidget* GradientEditor_Plugin::createWidget(QWidget *parent) { color_widgets::GradientEditor *widget = new color_widgets::GradientEditor(parent); return widget; } QIcon GradientEditor_Plugin::icon() const { color_widgets::GradientEditor w; w.resize(64,16); QGradientStops cols; cols.push_back({0.2, Qt::green}); cols.push_back({0.5, Qt::yellow}); cols.push_back({0.8, Qt::red}); w.setStops(cols); QPixmap pix(64,64); pix.fill(Qt::transparent); w.render(&pix, QPoint(0,16)); return QIcon(pix); } QString GradientEditor_Plugin::domXml() const { return "\n" " \n" " \n" "\n"; } bool GradientEditor_Plugin::isContainer() const { return false; } GradientEditor_Plugin::GradientEditor_Plugin(QObject *parent) : QObject(parent), initialized(false) { } void GradientEditor_Plugin::initialize(QDesignerFormEditorInterface *) { initialized = true; } bool GradientEditor_Plugin::isInitialized() const { return initialized; } QString GradientEditor_Plugin::name() const { return "color_widgets::GradientEditor"; } QString GradientEditor_Plugin::group() const { return "Color Widgets"; } QString GradientEditor_Plugin::toolTip() const { return "Widget to edit gradient stops"; } QString GradientEditor_Plugin::whatsThis() const { return toolTip(); } QString GradientEditor_Plugin::includeFile() const { return "QtColorWidgets/gradient_editor.hpp"; } Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/gradient_editor_plugin.hpp000066400000000000000000000034101366475014400303110ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_WIDGETS_GRADIENT_EDITOR_PLUGIN_HPP #define COLOR_WIDGETS_GRADIENT_EDITOR_PLUGIN_HPP #include #include class GradientEditor_Plugin : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: explicit GradientEditor_Plugin(QObject *parent = nullptr); void initialize(QDesignerFormEditorInterface *core) Q_DECL_OVERRIDE; bool isInitialized() const Q_DECL_OVERRIDE; QWidget *createWidget(QWidget *parent) Q_DECL_OVERRIDE; QString name() const Q_DECL_OVERRIDE; QString group() const Q_DECL_OVERRIDE; QIcon icon() const Q_DECL_OVERRIDE; QString toolTip() const Q_DECL_OVERRIDE; QString whatsThis() const Q_DECL_OVERRIDE; bool isContainer() const Q_DECL_OVERRIDE; QString domXml() const Q_DECL_OVERRIDE; QString includeFile() const Q_DECL_OVERRIDE; private: bool initialized; }; #endif // COLOR_WIDGETS_GRADIENT_EDITOR_PLUGIN_HPP Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/gradient_slider_plugin.cpp000066400000000000000000000045711366475014400303110ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "gradient_slider_plugin.hpp" #include "QtColorWidgets/gradient_slider.hpp" #include GradientSlider_Plugin::GradientSlider_Plugin(QObject *parent) : QObject(parent), initialized(false) { } void GradientSlider_Plugin::initialize(QDesignerFormEditorInterface *) { if (initialized) return; initialized = true; } bool GradientSlider_Plugin::isInitialized() const { return initialized; } QWidget *GradientSlider_Plugin::createWidget(QWidget *parent) { return new color_widgets::GradientSlider(parent); } QString GradientSlider_Plugin::name() const { return "color_widgets::GradientSlider"; } QString GradientSlider_Plugin::group() const { return "Color Widgets"; } QIcon GradientSlider_Plugin::icon() const { color_widgets::GradientSlider w; w.resize(64,16); QVector cols; cols.push_back(Qt::green); cols.push_back(Qt::yellow); cols.push_back(Qt::red); w.setColors(cols); QPixmap pix(64,64); pix.fill(Qt::transparent); w.render(&pix,QPoint(0,16)); return QIcon(pix); } QString GradientSlider_Plugin::toolTip() const { return "Slider over a gradient"; } QString GradientSlider_Plugin::whatsThis() const { return toolTip(); } bool GradientSlider_Plugin::isContainer() const { return false; } QString GradientSlider_Plugin::domXml() const { return "\n" " \n" " \n" "\n"; } QString GradientSlider_Plugin::includeFile() const { return "QtColorWidgets/gradient_slider.hpp"; } Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/gradient_slider_plugin.hpp000066400000000000000000000014011366475014400303030ustar00rootroot00000000000000#ifndef GRADIENT_SLIDER_PLUGIN_HPP #define GRADIENT_SLIDER_PLUGIN_HPP #include class GradientSlider_Plugin : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: GradientSlider_Plugin(QObject *parent = 0); void initialize(QDesignerFormEditorInterface *core); bool isInitialized() const; QWidget *createWidget(QWidget *parent); QString name() const; QString group() const; QIcon icon() const; QString toolTip() const; QString whatsThis() const; bool isContainer() const; QString domXml() const; QString includeFile() const; private: bool initialized; }; #endif // GRADIENT_SLIDER_PLUGIN_HPP Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/hue_slider_plugin.cpp000066400000000000000000000042701366475014400272710ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * \copyright Copyright (C) 2014 Calle Laakkonen * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "hue_slider_plugin.hpp" #include "QtColorWidgets/hue_slider.hpp" #include HueSlider_Plugin::HueSlider_Plugin(QObject *parent) : QObject(parent), initialized(false) { } void HueSlider_Plugin::initialize(QDesignerFormEditorInterface *) { if (initialized) return; initialized = true; } bool HueSlider_Plugin::isInitialized() const { return initialized; } QWidget *HueSlider_Plugin::createWidget(QWidget *parent) { return new color_widgets::HueSlider(parent); } QString HueSlider_Plugin::name() const { return "color_widgets::HueSlider"; } QString HueSlider_Plugin::group() const { return "Color Widgets"; } QIcon HueSlider_Plugin::icon() const { color_widgets::HueSlider w; w.resize(64,16); QPixmap pix(64,64); pix.fill(Qt::transparent); w.render(&pix,QPoint(0,16)); return QIcon(pix); } QString HueSlider_Plugin::toolTip() const { return "Slider over a hue gradient"; } QString HueSlider_Plugin::whatsThis() const { return toolTip(); } bool HueSlider_Plugin::isContainer() const { return false; } QString HueSlider_Plugin::domXml() const { return "\n" " \n" " \n" "\n"; } QString HueSlider_Plugin::includeFile() const { return "QtColorWidgets/hue_slider.hpp"; } Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/hue_slider_plugin.hpp000066400000000000000000000013501366475014400272720ustar00rootroot00000000000000#ifndef HUE_SLIDER_PLUGIN_HPP #define HUE_SLIDER_PLUGIN_HPP #include class HueSlider_Plugin : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: HueSlider_Plugin(QObject *parent = 0); void initialize(QDesignerFormEditorInterface *core); bool isInitialized() const; QWidget *createWidget(QWidget *parent); QString name() const; QString group() const; QIcon icon() const; QString toolTip() const; QString whatsThis() const; bool isContainer() const; QString domXml() const; QString includeFile() const; private: bool initialized; }; #endif // HUE_SLIDER_PLUGIN_HPP Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/new_plugin000077500000000000000000000143611366475014400251630ustar00rootroot00000000000000#!/bin/bash # # Copyright (C) 2013-2020 Mattia Basaglia # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . SELFDIR=$(dirname $(readlink -se "${BASH_SOURCE[0]}")) function class_to_underscore() { echo "$1" | sed -r -e 's/([a-z])([A-Z])/\1_\L\2/g' -e 's/[A-Z]/\L\0/g' } function class_to_header() { echo "$(class_to_underscore "$1").hpp" } function header_to_source() { echo "$1" | sed -r -e 's/\.h(pp)?$/.cpp/i' } function read_arg() { varname=$1 prompt="$2" default="$3" [ "$default" ] && prompt="${prompt} [$default]" read -p "$prompt: " -i "$default" $varname [ -z "${!varname}" ] && eval "$varname=\"$default\"" } function header_to_guard() { echo "$1" | tr [:lower:] [:upper:] | tr /. _ } read_arg class "Class name" [ -z "$class" ] && exit 1 read_arg description "Description" read_arg header "Header" "$(class_to_header "$class")" read_arg plugin "Plugin Class" "${class}_Plugin" read_arg plugin_header "Plugin Header" "$(class_to_header "$plugin")" read_arg plugin_source "Plugin Source" "$(header_to_source "$plugin_header")" read_arg plugin_path "Plugin Path" "$SELFDIR" read_arg plugin_author "Author" "$(git config user.name)" read_arg plugin_copyright "Copyright" "2013-$(date +%Y) $plugin_author" echo "Summary:" echo " Class: $class" echo " Description: $description" echo " Header: $header" echo " Plugin Class: $plugin" echo " Plugin Header: $plugin_header" echo " Plugin Source: $plugin_source" echo " Plugin Path: $plugin_path" echo " Author: $plugin_author" echo " Copyright: $plugin_copyright" object_name="$(class_to_underscore $class)" cat >"$plugin_path/$plugin_source" <. * */ #include "$plugin_header" #include "QtColorWidgets/$header" QWidget* $plugin::createWidget(QWidget *parent) { color_widgets::$class *widget = new color_widgets::$class(parent); return widget; } QIcon $plugin::icon() const { return QIcon(); } QString $plugin::domXml() const { return "\n" " \n" " \n" "\n"; } bool $plugin::isContainer() const { return false; } $plugin::$plugin(QObject *parent) : QObject(parent), initialized(false) { } void $plugin::initialize(QDesignerFormEditorInterface *) { initialized = true; } bool $plugin::isInitialized() const { return initialized; } QString $plugin::name() const { return "color_widgets::$class"; } QString $plugin::group() const { return "Color Widgets"; } QString $plugin::toolTip() const { return "$description"; } QString $plugin::whatsThis() const { return toolTip(); } QString $plugin::includeFile() const { return "QtColorWidgets/$header"; } PLUGIN header_guard="COLOR_WIDGETS_$(header_to_guard "$plugin_header")" cat >"$plugin_path/$plugin_header" <. * */ #ifndef $header_guard #define $header_guard #include #include class $plugin : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: explicit $plugin(QObject *parent = nullptr); void initialize(QDesignerFormEditorInterface *core) Q_DECL_OVERRIDE; bool isInitialized() const Q_DECL_OVERRIDE; QWidget *createWidget(QWidget *parent) Q_DECL_OVERRIDE; QString name() const Q_DECL_OVERRIDE; QString group() const Q_DECL_OVERRIDE; QIcon icon() const Q_DECL_OVERRIDE; QString toolTip() const Q_DECL_OVERRIDE; QString whatsThis() const Q_DECL_OVERRIDE; bool isContainer() const Q_DECL_OVERRIDE; QString domXml() const Q_DECL_OVERRIDE; QString includeFile() const Q_DECL_OVERRIDE; private: bool initialized; }; #endif // $header_guard PLUGIN sed -i -r \ -e "\\~# add new sources above this line~i\\$plugin_source" \ -e "\\~# add new headers above this line~i\\$plugin_header" \ "$plugin_path/CMakeLists.txt" sed -i -r \ -e "\\~// add new plugin headers above this line~i#include \"$plugin_header\"" \ -e "\\~// add new plugins above this line~i\ widgets.push_back(new $plugin(this));" \ "$plugin_path/color_widget_plugin_collection.cpp" Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/swatch_plugin.cpp000066400000000000000000000050021366475014400264310ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "swatch_plugin.hpp" #include "QtColorWidgets/swatch.hpp" Swatch_Plugin::Swatch_Plugin(QObject *parent) : QObject(parent), initialized(false) { } void Swatch_Plugin::initialize(QDesignerFormEditorInterface *) { initialized = true; } bool Swatch_Plugin::isInitialized() const { return initialized; } QWidget* Swatch_Plugin::createWidget(QWidget *parent) { color_widgets::Swatch *wid = new color_widgets::Swatch(parent); wid->palette().setColumns(12); for ( int i = 0; i < 6; i++ ) { for ( int j = 0; j < wid->palette().columns(); j++ ) { float f = float(j)/wid->palette().columns(); wid->palette().appendColor(QColor::fromHsvF(i/8.0,1-f,0.5+f/2)); } } return wid; } QString Swatch_Plugin::name() const { return "color_widgets::Swatch"; } QString Swatch_Plugin::group() const { return "Color Widgets"; } QIcon Swatch_Plugin::icon() const { color_widgets::ColorPalette w; w.setColumns(6); for ( int i = 0; i < 4; i++ ) { for ( int j = 0; j < w.columns(); j++ ) { float f = float(j)/w.columns(); w.appendColor(QColor::fromHsvF(i/5.0,1-f,0.5+f/2)); } } return QIcon(w.preview(QSize(64,64))); } QString Swatch_Plugin::toolTip() const { return "A widget that displays a color palette"; } QString Swatch_Plugin::whatsThis() const { return toolTip(); } bool Swatch_Plugin::isContainer() const { return false; } QString Swatch_Plugin::domXml() const { return "\n" " \n" " \n" "\n"; } QString Swatch_Plugin::includeFile() const { return "QtColorWidgets/swatch.hpp"; } Qt-Color-Widgets-v2.2.0/color_widgets_designer_plugin/swatch_plugin.hpp000066400000000000000000000030351366475014400264420ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_WIDGETS_SWATCH_PLUGIN_HPP #define COLOR_WIDGETS_SWATCH_PLUGIN_HPP #include #include class Swatch_Plugin : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: Swatch_Plugin(QObject *parent = 0); void initialize(QDesignerFormEditorInterface *core); bool isInitialized() const; QWidget *createWidget(QWidget *parent); QString name() const; QString group() const; QIcon icon() const; QString toolTip() const; QString whatsThis() const; bool isContainer() const; QString domXml() const; QString includeFile() const; private: bool initialized; }; #endif // COLOR_WIDGETS_SWATCH_PLUGIN_HPP Qt-Color-Widgets-v2.2.0/gallery/000077500000000000000000000000001366475014400164165ustar00rootroot00000000000000Qt-Color-Widgets-v2.2.0/gallery/CMakeLists.txt000066400000000000000000000030541366475014400211600ustar00rootroot00000000000000# # Copyright (C) 2013-2020 Mattia Basaglia # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . set (QT_SUPPORTED_VERSIONS 5) select_qt ( QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}" QT_DEFAULT_VERSION 5) set (REQUIRED_QT_COMPONENTS Widgets ) find_qt ( QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}" REQUIRED_COMPONENTS "${REQUIRED_QT_COMPONENTS}" OPTIONAL_COMPONENTS "") set(SCREENSHOT_SOURCES screenshot.cpp) set(SCREENSHOT_BINARY screenshot_bin) add_executable(${SCREENSHOT_BINARY} EXCLUDE_FROM_ALL ${SCREENSHOT_SOURCES}) use_qt ( TARGET_NAME ${SCREENSHOT_BINARY} QT_SUPPORTED_VERSIONS "${QT_SUPPORTED_VERSIONS}" REQUIRED_COMPONENTS "${REQUIRED_QT_COMPONENTS}" OPTIONAL_COMPONENTS "") target_link_libraries(${SCREENSHOT_BINARY} PRIVATE ${COLOR_WIDGETS_LIBRARY}) add_custom_target(gallery COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${SCREENSHOT_BINARY} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${SCREENSHOT_BINARY} ) Qt-Color-Widgets-v2.2.0/gallery/Color2DSlider.png000066400000000000000000000134201366475014400215330ustar00rootroot00000000000000‰PNG  IHDR€ÀCüð pHYsÄÄ•+ÂIDATxœåœ_¨å×UÇ×¹3™f¦3I£M+šL1I[ˆUZ[ hAúЇDЧ>ô¥Ð>‹‚  â“èƒ*ø”'±O‘€­ˆ6m¬ Ñ¢M°Ie&é4¥“LÒü›³}8÷ü~{­õ]ÿöïwîLñG¸wïµ×^{ïÏwíuÎsoZk¢ %¿Þ·À¹Ýò;tÜ[k¨ÑôUtý¯)7""j472_ Îëîö˜·ÜÄÝwüuµ_ž[‡›Í¦~žãRÂQ]kßj¯ms|ªd§»L³«T Z¡†ÐX{íU9Ä~öå§;ü y‚C Ù$Þuì'ýû$‡ÌSsvUÍw'yáIJ¢e°.(P^X‡‚åÉý´‰©U3=íÙ (;à뺥‰R>BõŒ–ÔÄBK2=wÜœ#ŸÅèú&Í"“ÝŽ®p¡%™žŠ— ¢ +hAbuGãj³d”øV-œQV‚œ”÷‹RxQ,ˆ9ô)U4”ŒZb ÈàÜP‚œd_¡±K¿>ú$t®„Û—ÁíÝ·U”–ƒÎ£ ÃŒ¶2½*’WJ²™8E¦¤MþX”¡§E3ïÙÙÇáVeи¡çT‚fˆP†½Öœ¼$Iôúrh ¼i⃸ñ Ðiž±@ FUII¢w€&çeP–n,@žæÆæµ$Ùab¦-S²·¤.U¨“ /A0ñýr´<å©($] €Ìº%/¥vèÀo€Ï4ñžgÑ…hÍ‚ì˜0yèöh€~@çþî¥8%IE0@Ðçkî_Fo‘ôN:'$I9Ëd‘ÍQ^”þăøÉ; Œ#’ÁÝc—–„áÆ7 §éj`²Ë½H#ÙÎÚ06_7+C>÷Ej÷C;÷¾ø ¡Õ/Ãj+úæ‡o¿b(C×6AÛSr7`*Aý`›€ûì¶ Ó EJ Ç€,¾ª @G_#ü4„Ï"ÐΦ?%2W;‹ê ³C¢½T³¾­KМ¿‰â³T”ã¸)fŽììLž–ÁÅ:än@_‚¦óØHd£7§¹Ê ñÝQ2Éè4!CFœÚ–C'F$@_‚ῆ†bI9 £–GJ¢èC£dd™2jˆÐÈäô’%Èÿ‡ÏÜ%X-ý­Œ‰o uhnLyJseì-ШÅèÐ%H]GŒ2q˦GßDiñ2hRBéÊ0͵f–Ã|t š2V§eă¹k}3Hº™2èà ¥IÙÒâ_]` BbdhojÍ]ÅLÕe(MˆîP$€øDl€œ4\eÈMü¥CuG†æ?Ð(eúþt“am ³r€Aäú ;ô;Nÿu8!ÉÜ%{ÈJFád`Ca^÷¬¡¢>ÐŒl‚²e©rT‚œ×áä%€ïPûfȶ%Ã_âb@Æ=˜1…@2Bm¤N J^‚¸<ß!Vœþdæ¸Ly{:NüÞ?¡ ”Ê»¨:í°~èµÿ]ºÔdúÒŸŒ˜V+å;:@’]óÞÖœ¸ ÝQ‚2—@üLP’xdÕ‘A‰±Ž6yÖ~²·Î“G&Ò%Hü&ðÙÝñZTL†¬¯–QhC¬‹=‹uïiÞ€¾ÁwŒ4ó>>wdÙ | #ðÑFJkh”ô%&¸m”ÜÓFÁg:¤™0Ω ¤º¾‘ÐrŒ }`”)¿åU½¹O¤ÙÚ¸b°)q“Ý™TSݾ°ÈˆBDj­~ ‰ °ÁE¾c¦áÇ¿äŽZ28™Þ â„ÂZ4-åM R¤ˆc,AÎ%èó=zžœ1waD³™ÞO¼¬)â!ÆËš‚àz·ÀK-qÂ^*;™)¾P9‹¸Îâ⌯¢Š+À^AÓ`3dšØo&ï\U¥,€_‚,mª£K¸gº%ˆË©­ØõJЊ]b y­ÑÒ®ö·ÑÕK´ÓzŠ®ràŠs°„•Ô¥®þDl>ö*õ½…íÌÍ£¬Šç°ãÎLã‚ÛTºáwe!èü-Ipg°,7‡lÒm@e7¾M(E2|ôT4¸3·ÎÁO|ææ  þLÕÌn.†%ƒäëˆG†ÝR…ìY‚I´äÉdºMÜ{ah†` BbH@Ur|ƒDvÒávùïž¾ü7O]ûúóï\ÿÞé;ÏßñÐßóɇÏ=x_ZL3êd¼~X²ÑÁã?.>ŸÛŸÈ®ŠŠ>QW~. ÃÂM6ô2öúKßþ—ßû“kÿý RÏÝ¿ð±KŸÿÕƒÓ‡ În6yvõ«‰ÖÁÑøVœ¬Ww%¾%äuYú‹Û£/ÓkW®>ùk¿ÿÖµW5}"zé‹O½ñâ·?ð;Ÿ§S‡SF‹ëµKU‘ï8Ó»]fï¬uÔØyJ2ð®Ä­ÀÅ'Ô"ˆ.µÍOÿîo韾ðî÷úSw|àý§ï:ÿÚå«ßúÇ}á/þºÝØ\{æÙoüÙ~쳿 ÑhÔ•B2Ô‡ò8yï;Šþ\'K6¦qûÔ}þ‰/¿úüe":s×ÿƒß8<n{¢s÷¾÷ö{ï¹ã¡þý7ÿZ»òWñ—~öÌûîî¦OdE·šX×´ŸØl6mÓÚ¦‰ÆfÓ„½Íöcïþóì¼Ñ;H;Ɇp;²Ó¦Ñ¦}óKÿ°=äýŸyäÔ¹³“}Û8ÿà}?ü‹?³EwõKÿL]â ö¶“áïÿ'KU²ë¥

üž‡?L»¢A»˜¨Ñv¹67`Ô8 uðØcmc:õ¤©Ÿõÿa-S”Œ óuÙÇÜׯ¾üO¿ýGo}ÿ$LDç?xéþ_ÿ ž¼Y›?ùÈ#XÓœù½ñ‹'óvÊ¡!BsÉnXŠˆNÞ~æî=tíëÏ¿ùkšþÅO|ôÒç~åàðd?E7Õ試°¬Eúÿ4ÝÏBœ’ÊVˆI%„én»óÂOþÖç®~噟üê+ÿó¿ï¼úúé;Ï_øà¥‹ŸøèÙûÞרm6Ðôèå,‰Ö¦j̲€ÿv´G?½Ôð÷ÂdpÃYD?ð‘Ýõ‘ÉÓÍïýM¸Ù*Ñ7ú?SÍÒ/A§Qg ·áŒõèeÐABg×—ÄR ,AýªÏ* (Œ[SÁ­7%Àôj8Çó ;S>aææ—€Ó3KhŸ¤Z–ø<@Ð_˜Ú”S(£Ç*R%ÛøX¨$e§Ñ— }Ñ¢ÜpËpwÒ6™Ñ™DVC&egh.A~‚; 5€‘¸…ÒC dnЉpÈW‚¼!©“Ó?’ŒéΖÎz‡,Jð*÷عÏß’Nµéë•;ÚH— *ý0¯‹wE«úu̽Âzö·_å häX%Ȳ(¾I²&k1‚θŠ@̲@L%ˆ¯¨•ÓÚ(‹/ E_”—LƒÓI"ž,™ rOå¸&‹XKyB˼Ž%€.A Õ ‡˜p«^_¹‚–”›« X ÆÜ|ÁˆgF§" /A¯$}ÿÅÀw#äFÈͦ™BlpO¹r##ñµlx%HéáÓOþÃ'Îܦ ZÅÇ6‚µ4b¿^¡t†F¦º&«$1uÂ%é% èïüá”ì=ÈiÃŒ º¤ã Ö챑 ËÖU’ȹ³¢YÙíÓ/÷éðkBSDÒ)ˆXN­¬Ýmr] ©u…о_;‘᨟Ô}^ãQ®?ž5ŽêÌ5 š9_€ØšÒ}3°JÐdt.DH¿Eï\É]Ñ”,i»Ã{£¤ö#F ŒBUð(ñÝt Šj÷ܵÉ)š¢Ó*ÁaÉé\ÝŒÁ‘9*ãXÓ·mùwÂðçú!ß®à:YXÍ”›‡Õ£=¡*L£™'ô Ž«SàÙí;å¹;MÖ³S%(JHž”g?ãIÝ ãÌ0ú¤ìTe'ôg…i›–oÕ‰ï0ðò›bªNUåd¢Ê?¿³$5zQ€j *ÑoöÏÒkÁ# „­’²ÂV Û ´ýcpHž³oW×]Â7/ÀŠh˜3—y‡ñ­%À¾è'éþo•¥áÿ-eMúˆöyŸÉY— •š ¬p—e÷ú«%¨Ì‚ŽhpìêNV‚nîÊ+AÛµÎ°Š´ð Ë€j9;_M·e O,ÃZ¥Î¬tŸäÜa1Ê%ˆŠ4üKÄáÁªþS»ê?µ«þ³¢ù»#›ŒIé˜ð乂“t3“ Z¬ud–  µ}B· t}ÂŒO‰räÖΠ°ˆ ÙswÓ­¹ñôé¾xŽ w(èdÄÛƒbd^WX 2ΰr?·,DÖ;‚¿Ìò°e1lÊ4¥…'€.AÖ™Ý!/èk4îPp¢!K IÓ‰ð”Æ[ž…¤&ÞíÏïÚ ‚Á!bCñU cŠFãß HÓ¹ ЮºS "#ÝòX fi #“Ú€™PdÂöùÌ®HºŽÜÛ5YÃnj#KÞº•­IÁÒº:”Á~àBZ?RúÃCâ„<-²PÓ"XÄé©„Á÷@»i(Pf‹>Ld„ˆA|%7N\xJâ¬~Û^ 2ø ~giÊ=#ÅNÌšÝ\âGÛ åæPv†X 2(x©ÚMA–rAȽ ÝD¾ÅtRAÝ„T®Ó< à1ÕóEò»£ñM1”6Vç–Ê}c1Õ°Î4{hû• }ÈÞ Èl:‚[–³Î.j±ËYâô'ùdù†s ¢=pY¦_JÑ)¥´ …ága‚ÉÙz=NpªU.\>EqŒþ`aN‘%ÈÙÜâë ¯!ƒþQâ/Ý-C¡0ÀËÚ>N 2—)ñò£Cqk(%0 …Nê #žhSv†@ Ês/c¥hG_–¤Ëò…à‰ô ‰g.A»¤DÊ[g¸Å×Òô»ófXiî áDîÁÂ݇%¢0»Ü>öŸ H|”À¨!@_‚ïÛÝ/úäè˜ÄGyäFÒ9íKPw3s0:®Ö¢bÔZ´©Ó®´¨“àrT=Æ %(Ü ßVœ€È~ô½Dá&®Ûv0Cñ6€%(J½Ð!¾Ë#9¤n†á€ÓÔŠL†ƒx¼„Aú8sC‡(8^yš²™p˜ž° çOžG3¶‡ýÅOn@M!À¶U÷4q£>ǰÔÑúØ7 ²•ŒÌ…ý@a>ÉÍŒeÉI`úÌ%È 1~TZÿ´·ú~Œ§\‚¨ávÖvGYœa7BGµ5È\Á¤[–€ãfˆH• ä’”ÅÜó+ú åWôï‡åélŒ {ƒF 2–Ì@§LfÑ2îF;ƒ¾¼=7”\no²AOP‚ø’`hOæ©”s’{¥EJ%~¿tâD˜Ü$W%¨’qÌ9òO)DÉK«Ë ”t²wl•?‰”X5Ï‘ò'¡ÜaVA¿âžMÔø1ðKж·ä´Ñ”ÒWÓɘ2"Uz ö×%ˆ¹æ¢{ûFCz´Pí´Ëѯ½d "¿¹³'¤¡C?g.þ¶ÊÞ•ïO’‚ùñU„¨­µÅÒ.è¾³SšÒÛ£c;—iƒ%ˆÆÏCúH¹é)註Ú>óšÕ7ɾ‹QY‚ÂpÕÝT7Ô×¹„£Šžêç5žz B–`÷‘@[l‡ìE1,žl K|¹Ý¹%¬—\Ç„ž¶HÛúáÕÃAP‚ò¡3»LFƒ™2´Éä{:þ`"*#æÃJP.¹­üt½³ÊÒ¾q-îàê íÇ÷òJ¹‰Ò>”½Œ;áì]š¡å¡7ìÞï†(Wìëeö8ÍGíYôu»qD râú¡ë³JSs<=´÷h(*Aîüà3ÏáQxUG'ŒÆï>’£‰‰•wAùÐ ‚µÖÂõã[é”ùdïÙ§L|?>‰” ºuL{fc®pä8«ŸyŽ– %›Ø›ÿXÒÜ\ÿz Z²‰sS/«®x<s%h•݈‹ãðp߯qÖ+AÕg¿Ñ¿oâã0'NœX'~uå›÷ܤýàeOÞ´•ÿß=Ãÿ$:pfÈb5jIEND®B`‚Qt-Color-Widgets-v2.2.0/gallery/ColorDialog.png000066400000000000000000001303571366475014400213330ustar00rootroot00000000000000‰PNG  IHDRë|`ò pHYsÄÄ•+ IDATxœì]wxÕúþΙ-©»!ÐCïMÒAð êUEšb×+êµ÷+^ûÕŸýŠØ@ºŠ¢^E H„j u³iÛÎùý1;³Sw&urÞgŸyÎÎwvæÌÎî»ß¾ßw¾ƒ ‹\ÀÀÀÀÀÐ#=†*‚18CCcp†† Æà ŒÁ*ƒ30004T0g```h¨` ÎÀÀÀÐPÁœ¡¡‚18CCcp†† Æà ŒÁ*ƒ30004TX"=†ˆ!++«ÄíÎÏÏô@dHJJr:;u2ì‰X}p†Æ‰¬¬,Œ %%¥.Oºqã¦É“¯7ì¶cÇÌq;8óÁ)JÜîQ£FFzÚHMMݸq“a7Æà ‘O(¥fºåååöa ÎÀÀÀP§0ÉàfÀœ¡¡"###ÒChHrõ¿Ö—Ÿ–®ý×äW§åÇ~ùà¡ÙÓ¯»aæì'?ÛtÎÁQ2Ô28{|¯;Þyó¶^Ñ(´³bûò¯Ê¯{êáñ¬(d#çÖ¼ýqé¤;‡Ç"ձ€š{˜cp†0 ¥~öÜ£ŸÿlÕWóŸè¹ÿ­×¿Ë&‘Cm'™pY›Œ>Çwìµw±o™{÷-×Nš:ý‘ןê%“ß½²Ìrûã[B%?¢NþaLEahT^üД¯EÇ…xÜ~áú{v­KãÆÌ½ªC4è~ÕØÎßü–‘3¹]«J¹\ $/çü¹Ý»m¯½þù‹ñîóü…¯;ΟÞ!ptÉk?4»ç+šáC•<$›ÑÃÀP5p¦Ì}éªæA¦9ß?÷ìÍŽüWŒ–äå—çl{aê:þÄ‹›÷-'\Œ–¡€ÐzÂ-“z%p ý§Lèòí–Ýœʾ~ó—.÷Ï‘€ PéCÖÜèƒ34.pÑÎÄÄ&A'eÑÂ7a|. ÅEn €b›$Du¸áµy3Ú1Á±‘‚kÙ¶yI^¡/ø³í÷ù±ÕNÿZùÍáÓèÅ)ëåÅnúü5»'¾²ðÌp*¥°gï>—«Xaq:zNM0g`”Т…íľý%c‡ÄCYæÚߎøí—@Ô€ñÃ>~Ѹº›“óºNžp'viÏD”Æ®ó„«[Þóé‚mqñê“}¦ p¹|åÂ;ÓäÈ’‡_(¾mÁý—&š#T^DIi›²xóŠââP}o‡Ã9kúM•’Xƒ30Dš~ߟoý÷w/lšß¼ÿðáMw øAw¿<û‹yoÞ÷ù…rbKè0|ÖÓ¶‰ôhê\‡çÎ-{ç½Û®=Ufk=ðÚžšØchÒ$.Ø!Íao|bB¬ÕÜ)Pp8ãgNŸºdÙŠââbp83§Ou8ãieTÆà È1áåo&H÷àÖ7½÷ÍM|ÛÒjìoŽ Ù¦Í 6¢Ú½ûõ±w×Ñ "ÜaöÇ¿HwpM‡ÞþÒÐÛõúsÝïZðc¥Î ¸ÙNGüÌiS—,ÿfN›êtÄ›LAÁœ¡#îÁ§#=xò—µ‘Bƒ”¥ÇŒ›¦ò é~dN©c ÎÀÐPQoË¥2„‡B'q8ãÕ;)˜¢pÆà u 3ùà&sƃ3004R$%%EæÄFäŒ1¦„&&%¹2004R8Î]»vÕýyFá„’}û÷9Æ > Â"—a'†‹G)..ŽÔ’ÇzHLLt::uîdØ“18CCSQ*ƒ30004T°\”šZŽŠ pv!Î.ÆgÊPA…ä@%ðòQðp`³Q›ìVjµ€ÝFãbhb”ð°ÓÄÒ:–´‹%íl4Ì¥ˆ20040¯:àÏÅÇÎpÎrûÎãÌ|¼gûp@lpXÒwR€TxQ…À‹‚/q©zò +'íbI‡xÒÝèèM:"v1X$³ @Ïá#G,ÛŽp'¹=9Ü!&ɺÆwb+Dź9ýœAñþ!Ѥ3sÒƒ€9ÆíÙgùý0—qÄ’Q‚ò ‰•3·3 Y›?”Ôj¥IñþÁŽÀàxÿè˜@_ä``¸èÁ\Å(—å·Öu»-ë‹Q®U’µ º: iÝN›9ücã}ãbý—s4BÏjŒÁe¸€Oo¶~·Ùú]÷'ŠÄG5Õ’*3¸ù Š Œ÷]ç»ÎBÚDú f``¨I0ÈÅg·~·Ñº*“Û®fFEVŸµké…H‹ñÅ{`P¬oRŒï:Ž´Šô[ÎÀÀPhÔ îÏ&ëO?ÚýiÙ`†Q-o Ps´š?EQþÑ1ÞÙ6ßDöH߆ª£‘æ¢eã¬ïl‹ÖØ–£|P!CÑ—%çüV³²•t ßÖyD&Úš/Äò§bV ¶bÃkùÝoùÝJ“ìÞévï͘t ;.†‹YYY%nw}«‹’””ät:;vêdسqùàèVËúÅövX6# À•4t½×0Rx5Û5u(Å#ü? ÅZý£lž8ÿ8 í30\üÈÊÊÂRRRêò¤7nš<ùzÃn;vìÀ×±£‰7Ü žÕ¶o—Ø><ι@åbƒÄׯÂS,øÎT‹áÔŽví!Œ®ÙAÏ7W4ˆe“ײ zX½s÷&­04”¸Ý£FŒô(´‘ššºqã&Ãn?ƒ—£²¶‹ì ó(Ä;ÝT£a Ÿ`s’ˆyÙ$<‹'z‹¦–"•P@« î` ú>õoÎsxïS±304DJ<1¹þN^^žaŸ‹™Á=Pñ¥}ѧö÷òQ/’@œÀÚ(\Œ.¸‡_€4ŒÓ­–ÂMÒte}ó0ZFxâVkß å’£0 t¢þ…ì ÏCÄs@TeÎÀÀ` “ n'ƒ{ÁûmÅ<û;¹øï~R„‚‹D˼o€…†žÓ­©Ÿ(P#rЦBb(ž„é¯VNÀÄ0º€¢žÂ–÷©÷Ñ€o€­r—ÁP'ÈÈȈôêíÂÐEE.HH0^‘G‹Á)ÐuÖ_^‹ú÷)œÍOÉá!zßR7ä xÓR!EMåz©&ªÁ„{j†„ŽT[µK®é˜ƒ>‰ó&DðYlsï|/“ÀD笇p¹]€%(4¤;©¤[°!ß)}‰îk͇ÿ;«ùÚ_§ü“ü¨•oW{¨f/ù§øá‘½SRH}ð¢"×ÂÅK`ö¬U qóŽ]À!.óæØi÷ÄÜ‘O „‹h£AÝ ’mÉÓЖ¨öKÛ"ªó×™xª¸[áµÅþ0.¹¢< ÿÞ@è¸Õ2Ýj¹¡•º"MP……E /u¹\.—ká⥅…E¢Éä¡./D…ÏD?3!îÊ4K:Ï< §o ª†Nçû„¶zT.BÁæšÖ*# kkî4Çõ2R¤ $^- ^†6<Ü‚(¨Þ5nø3?»÷Žwvx#=†H‚ÿV¹.Yæró¹].×Â%Ë ‹\4ôµ3FƒWQ(Ðï­ÿ›=· 87Ap†N°Z"¸ †èÆ3A_H‘œ@¥ŸˆOõn€¡DJ‘ï7ï•kºšßÃ8(~ ¢ÄB?µÐï|🺾Š*Ü?VüwÁÚÙ…‹£uçAÓ™3¾•¶C‹ö­;”4vpËðqè…íëÏuÛ/ pmÇ̾ÃßÙZý£2Ô*N¬ý¿çßÙÐõ¹ÕÏ â?ÔùÓGó{fž‡Ú†<²è¥q±$wëg/¾û¿Ý¹þØvCf=òðM½âÌ~%(€ìììþ}û(,ÙÙÙ NåÎ0hØ ~Ÿ}2ú¹ß,ë…l9%} Ô ]Š"8¨² ñLµö-¥f¤Ãæê§†„n NW< #v‡f‚‰Ëpyâ4ÏFo  ¯|ø- ­«qYu Z°þ­W×ÅÞý²Ë[sî 'çÆ5Õãgš—¶â³¬Icj‚ÁÙë|íùç˜~IŠí8xHµÉPKðúõݧçŸhß1IzßÙß<þÔ¯ÿñÌÒ×;'Xƒ.ÉýåÕÓZ=õé›#ç×¾yÿ¿>Lùâ±áæ8œIúöéÆj •Á ¶%/Gý§•"9MkÒ·Âû&€°¬2ž©ç}«ŸrZ|]5¨“µÕ{4;hf‚k†:±dÒ¬™“4³XÛôÈÛ;¤ömº6·€@[ÓtI}í¯¾çÆ¾Í‚/Ð8”Þ”Š]¿m‹÷âÄö1 IŸn´úƒõ‡fví€C®½¶Kpöz‰cë™óhÞ𾪠H^Îùs»wÛ^{ýóãÝ;æ?þø _wœcyy…=Ú&|PÝn«(«0IÌtFO*:êÕ/l_" zô-8‘ºôÍJ-‚sJ*W )RïÛI[ôôîÒÕ?¸} Wûo£&ÛýɉþQÂðü%ÜîR˶R.£Ô’APŽ"í$|¶¸”ĸ¨–ÈdÑ—ZAL÷)ˆ*™á·ÍöƼJ¡^ÿÝGqÇÝúÔ¸Y®ÃÿßKOæ<ûÁƒýIÖº/—ÿº÷\9`¨¸KF…Jþ£¸Ö­›ßvZZ‰CѲÂ"bQoµ4mêtuñTgR‚àÊqG|5ø¯›¡² ´žpˤ^ @Bÿ)º|»ewñ]¢£<%^áÎPÇÝ,ʤžØU”,|bfì‡ñ1APƒ¾õœniƒ`ù${Тr©ˆêç6Ð?~€o\ëH—cE`‰¤ÆRî>ì¶®+³üZfÙ‚¡ÂPBQ·E<¸UÈ&TÍÚ2O(X+rÞ­åqK©¥K­]w Áâì:þÎéÛg~±çL·ö¹ÏÝðúKÏuŒEþÞñºOè%ñ“0Æ”’à󀻨š+Æ«¢¾=_èJË£G±‰M¬ùò$qþ¼\WBb¤û†kÙ¶yI^¡/è¿ù}~lµ[¸¶ÚVüOR[`rîX6¤Œha6"D)ìÙ»Ïå*VXœN‡^„S #õ£uýåqÓããÀûŽTð%$ƒ@‹s&ñ˜òþHœÔ#ãCl4ú2ßõÏ—­ø²øÄ ¥«®ñü#âô­†tmêùGJéªnÅ'Z•­ˆó]ÏÑh:×’¦º t*ÖVp:öŠ)mñü¯Ž/ß$ÈÙÝ›ödŸwUøå¹û׬ÝoëÔ¹q¹ÊâRº¶‰E(økã¹üâxg\ùÉcg}@)œÜªiá}9~ðçnüåO·–å×> ‡#®ðÄÑ€üϳ}À#üë¿üéxѾ•+¶'^>¦Kƒq©¸Î®n™þé‚m¹>RqvãâÕ'û ƒâ|ú‡/¶æú¨çÌoK~ȽtlªÙ? ”¥Ò6å¯=û6¥¥‹¿öìKi›Â[M -õý€ÀKQ¾c_ T BPµä Z …•uÃ1à¾þ¡Wúnã›Cã#ríU¢Ñ±¾ ±¾ ¹Ë­«Ê¬+–­9àHîw‡ÒH¦k+8Ӓ虞؇½ñÏÖr©ÝJƒº¬ùð‡ÿ;SP°:Zv~Ó¿îã¹á¶ô÷߸gNl\T³K&Œ°³µ3õš­ýsÚªØËþüþÔkî¹ñàûÏݲ.¡©ÃÙið¨ž*ÔǤy(à:O˜5ìõOî± ÅU/¼q©ÐŦÞñòí ßéŽÏ ý¶¤ã|fV7+€O}d†ˆ‚ëpãܹeï¼wÛµ§Êl­^ûÂS›c€„Ñþëä+oÝ9þ_ö©7¾ðØØÓéà@Àጟ9}ê’e+Š‹‹ÀápÌœ>Õ጗ªt†¨×+<¸PÉ­1On°d.‘n( ®Ì@±éªØ‰‚°ÚC é8Ñ;õJßÔ–$%Òo@ €Oz¬+|¶ ³FDðo ‚ß­hP€@ˆµ‘{âR+ @ìcÊ¿ ¸*ÅzL"##ƒÕE1_E]Ùjݯ¿Nšt]ßµU«¾»òÊ¿‰O]®â%Ë¿€™Ó¦:q?BhÍšŸÇþhõ×?‰ÏÝû° œ ©÷ €bæ›"ÿDŒd* \ê†#;Ø&z§LòÎêX÷[{àHJŒçqð<àþðÛl_"ð(T™ª&høÚ¢Ué‰Ó ãsåbÎ_QÞìkb¹~ë-œñ ï7ò‘_ÖFz†T!q83nšÊ7¤û‘9‡¾ž2øN.sZìãPž„gˆ|‹Âk)ꆔǥI)Ñ4jŠwælïœf¤$5W\àR®üRêyÊo¬_ˆÉˆÁÐ™Ž´-MJQš¤â¸„ÊÅržÌ¸³cK›°÷Ä_ü¨·åRÂC¡“8œñêÒ ]ÔÇHæjkÚU±\@EògéV¶SŒdª˜êH¦tg uÜæ¹{çc/_Üô-‘VÖò×-î}ØóOD㱜…ä©„ AÖ²þ ú™‚( ÿ…Ø3¬¥«#vÁ õÔ̪Þ1ø"Ûê™1ÏW ¯$©H\öTäePyŠ Åãà MæT<¶Î½ãŸÏ&Ò¤º¿ÌÈѦ¨âêÞO+žÚDýN©ÀµY[ïUOÊcÏL·¹¾ˆä30h!))Bß}jðÀSB‡W¿üCû7F¿MCInJÁV‘@!>¥¡¨ á™8êx´âÙ î?ÿáy8ž:´ÇÑH@Äó¤¯d¿ßó‡¶ZBT ¼›Déthí¤4æÜö‚#v¥ Zp:»víªûó"ŒÂ?%ûöïs:ƒõ%…}Ӿ╨/$Žœ_âÚIÝ¿€Äß“=Å@Â$Ÿp×ù&=]þlSÚ,Ò—[qÁb}†£_¥(@CÙ&a²n!§[ÃçïaEò³ɲ + õG)..ŽÔ’ÇzHLLt::uîdس^08:7já{ö•¾&*âÛŠÌBñi(¹P/Ø-ÐõåŠûYaÏpÀ(Í‚ÁL“ Ã7„;#sºUœ.½{ž¦ÿ,o5—‘8C ò NÎZôžýG[Mâz>xBÄâñ8ó°ç;=·[êkâM=ƒŸ£XÉ- ¦x²V7ôœî€6}ómOó–·žËHœ¡úˆ¼þ¦}å{öï´$o½©àzI)ʼt•o¦’õ÷zîfôm–ú§‡û3G•“µVΉFôRŸ¾‚ýÜ;QgÞŒôe20\ ˆ°>ÏþÓÓQ tmM E¡ƒÔÎ8‚€6§Mß+{mœt¯®¡ƒ ¬µ{îr—Mtåo¹"uÉuï!òv¯zZþ#Ò—ÈÀаI|‘í·§£é8Úœ¾'®ÙyèÐHÿÐßÝÿcô]M¸+Ê£Ò©ýM´3RÌÐ7Pˆ>þ”íøÖݳbæ‡õ¾Ã{âŠYšdš°²ô?}ëfü pž=qg&#ßíûCµˆ[s ¡§¥ƒ–úZ\á chLÈÊÊ*q»ë[]”¤¤$§ÓÙ±S½©‹’…Ï_÷F ª0G߯$Þ´ü¶ôµö£¨w½ö;yöœÐ o©KnšÄ)ŽsþÄ×ûÕî. deea)))uyÒ7Mž|½a·;v`ŽëØÑ€Äëb®yòÎŒý¼ùtVÛ ÆRa “´À}¾.})™6©ƒÁ3„±vp·û5îøõœoÕé[Bâ(P»ufÉØ ”3»ì7C•Qâv52Ò£ÐFjjêÆ› »Õ…þtÔw‡q®–êÍ …I±_6…g„¿ïO¥o2ú®' –ä’Nkü1#ªEßeœseFïz*Ò—ÅÐ()ñÄä=yyy†‡ªuÿѺï Û:&ž)["ñþ¾+K_Œ£Ñµ=ló 8¾¤ã·þ¸¨*}‹ÛÛ‘…ÖÓ?Fú²j 5¸ÊZíª(9¸øèoUâ '|e5=úÚ-/{ÆÖZ3CeA)Í>y.ãÏ)³{Ù+öiû×úÑK-@̶ûÝW¥’h燌ŒŒH¡!¡Þ. ]T䀄ãyÔ¨E'@ï^YˆÊ«GßÁmÒêëÒç˜÷]O@)=vüø–-é›Ó6oݲåÌéÓ­Z¶šºkƒußßpÙñª%¢H·¨¼ &íÞ’qߊ|äúŒ WM@##Ì! mÉ6ô”Í¡-§z ¾„·¾PìÏévPlãÍ3žà¯e̪÷´®z‰ô¢ô¯WvÕ3~;Ù;%…Ô¿.*r-\¼fÏšQ¯Eÿ̶ýwË1­pex_[üZ‡¬É4ñÛÒg“iBí–Á”Ò#G¤mݲeëÖÍé›sÏ_ „`@”sûÛ•`k^ÒsUüî+Pù…Êé' Áì–3왟yzÜÑ‹f`¨yˆ ^TäúbÉ2—Ë /½eæt‘Ä2µJm1øiìz!jœ5‰›“¤ HwŠ©)]YúD{’\KCeJé¡#YéÛ¶¤glKß²%7/Ê7pSBùíø+®Õ¡¤×7q;&"ê®´ʧQÛŸ÷¥L$±­ëþÂÉÙo¸7óú/Ÿ¹<ªîOÎp‘ƒÿ°óô]ì æ4*‡ IDATs»\®…K–IIÜ j…Á)Ї£W—"¿d9y3Ä­±µƒuiÙÃ}íjcœ š „Ì:”¾=#=cë–íyyy *!nÂoíQQ#G³²q}Kû.Ý5Ñ i|R×ÝÖ'q(N{¸ôo+jdI¶åLÙ1~Þ×4Žåùó»^÷ß·èÑAL›cQqbíÿ=ÿΆ®Ï­~f¨ €[tóìÏù%=¬ƒžýþ?·ùiÁ¿í>å"1mLžóÐmƒ’ÌJ~”@vvvÿ¾}–ììì§rgÔ ƒ¯²üÕrÔˆ¾åoà“²»Gø»×Æ ¤ „ì?œ™öGFúöŒ-n/,,B%cŒŒ¡€†qs˜ã·Ã†‹æo2²¬×'±»fC Pi\¾Ózâgë‘U¾ÎÆ3 1æòNË6¤å\=©%Oáå­ßÿ„Ñ7ƒß©_ß}zþ‰öC\Œ;ÎZôû Aö ~|zöÚÁÈ{l&ñä§s{5ñýîÕ^˜×ùËgGÇ™: ¯¢ôíÓ;ŒÕ$jžÁ PùÑ¿êÐ7èûÝ QN‚ÛÇ*&^ãK­ñ2ðÀÞC™id¤ïؾõÏí.w1 ˆP„1Ê35"‚[‘Ä‘@â‚„2~¼âà¾æ¯èôXԡת¦ŸHŸÆl~¬¸Íh•XÍëm>rLÏE?o8uíô @Kþü=#jÄ }là9òÝÛÿ°ÿ\Q©×Öfè­Ý÷·¶’|'ÿÿ™þI‹óîêÆ@àÐç·Ï-™³ø ù;—þ÷óÿíÍóGµ8éžû'ug«77lpöø^w¼3'eýÛO‹;ÆBÁ5_Ö·_z÷ó­0 Î×=:‡ßkí4~D÷ÿ~ª@œ)/¼ m„šgð—£6çóO@ÅÑ•ÐR.ówyÜÃJdÔ0üÀîCÒwü‘¶sû¶;Ü¥%@H¸‰ÁS^< í šž8ÆxìØ±êsUtyÒ’»Å’»©*$.Ñ[PI^TÆËå—ý_5¯%×wÁWOLÕ‘£îm¿íL¸ìåžVšÔcümÃêÖÌRðû¿»lÇè'†§¬’3«^}#­ó£ó–§:óíÑWçµþð±Á±ŒÃ2pò É@ŽkS,-ܸüxâ»Cãw¹lÿÞ#I=gµ07U/;8h?µïþÜÛûö@RÏj½È1tì€y_lÊšÖ±[ñÖu»“ÇÜÒ‘Ô¤[*?Å7i`jߺü †S~É©Íkt›ôÜ€$ @óW^ðï´ƒÁë¢NCD8ñí²¿zN½¿«ü“¼Ío½ûWêœ.1=S¥R:IxÔäç<õ; ΀Õ;ŒtÉ9@Ÿ”ÍN¦Ž[cƒÇçÝ•y }÷Žô¿vlÛ÷WyYïh!#J(–D#1€T'Á除ž8rQÆŽ«—ùD£’Ë~·iAÌ‘x€Dox²dò÷`.ÅJ(nà˜!Î_Ÿ9=ñøÆý)£ç¤`ð_عré[Žú1¦ÅgüÉÃ}½¨0êÂüBïîywÍø„ßíó’åþº©4ÄÐ’­_~[Q×àÝgQÁ8œä$Û '.Æ-Õ&9‰c™“Ôjµ:Ì`½ž´äl±œÛ\©,”ÐS¡½þ_‡ñÀUîË"‡­ïåÃñkKV•÷˜ùdS¤ÔUL›wî’dZ~ò·ÍY~ϽÆÉ­šfìËñ÷hcñçnüåO78eäøvO.ÿ"£ËìA-£hÙùc9¸}ÇfÌ¿8Q¾ëë¯Nzàª6¢Ôí=ùó /¥3_xjl3y¹¶Ø¢¬æ"™ ¥mÊâÍ+Š‹Cõ½ç¬é7UJb©±Ü[æq\¬O߆"8 d÷IÙ &‡G™§bû¡ýiûv¥ïݵ3ë ×뀠» ƒŠs%i$ &ˆž¸N†‰¶'.uÒ1Æ#FŒˆŠ2šô‚pÙðÏâJ/°¶ÂY·ïYâé[uÞ=K÷1—Eýïû.³†óÿz¹ögOÜûÙ£wü×~ìÈ‘mÒä/Àm®¹çƃï?w˺„¦g§Á£z¨àÚN~æqÿÇ ™ùF±E·è~ÝýÏ2¿8ArYºÎ~Õ›#"5ùv,ûhÝÉBòÊ­¿¾ÂïáÚÍúðË{»›Y'—âÎø™Ó§.Y¶¢¸¸ÇÌéSÎxA¨3…šYá¡ùûÇ-ËÁ¥á<(ƒË|U:cœ¿kõÇsñ¡´¢|Û¡}iv§ïÿk×ÑC~Ÿ€ÐNAG„ò\Œ„Ô@@‚‰ßò“*Ø$[ „bm"„Ì}á…Y³n6s ÖSkc×Ý„š`ª?G$®Uñ}»ÀÂ&Jddd°º(æë¢¨+[­ûõ×I“®«ã»¶jÕwW^ù7ñ©ËU¼dù—0sÚT§3üC­Yóó8Už®5ã2,°ÌÁå ‘y"6 E|¯;£o)ÜåeÛïOÏÜ“v௿Ž"ÕµÀ ØH¤‡TBQ$t‡1©=q½4pŒñèËF›¼_Û+|m¯¶ûŸ‰_s¹B ì:kß±À3øÞš|£2Öü´&ÒC¨6~Y«½Ÿ/ï3y"|n¤:‰Ãá˜qÓT¾!Ýo2f_ ^†üoÛ÷púô r¾)qóÖXjyµbbõÓÐá*+Ýšµ?=sOú¡½»gJCŽ6@ˆ¸ ESBø|@E‰~Iµ‘†I‘a’PôLãö:´­Ì UåC_·d¯GÞ2S8h“xÔ¦·¼fS+ Ößr© á¡ÐIÎxõNjNL®ÿÔv0yU“0Õp©)yFµ"ñÕLCDaiÉ–#ûÓïK?´gï©ã4À;Ú$ø«'q´EâÆi$Ê™îñšÈãXˤŒv"Bä,¯ „BÆŒS©+%±­+<þ<@UpÞ„Ül{FCÝÃL>x­ðàÀí*Oß õÊ»šÞçi\ÞD^Iñ–#ÒìOÏÚwàìI ”òL-u·#RâH‚i‚RbŲ@e©CNºDc!j EŒv†1I%”ËF_VÙ ÷ô›c;°œËˬ´.1ÙÓ?ô ¹,öj߆F¤¤¤ÈœØˆœù鉉ÆÃ«.ƒ¯´¿€¼Fô ¾VºáàÍŠñ¸ø ù_(qm9z0íèô#û3ÏžH¨†® áÒHBÚ´¦I'×[Û¤—ë­i=qŒqTTTjêÀJ¿ ØR~ÙÿÅ­¼ZÒ„Ê‘8.ʱí^éMQÝ[Âиát:wíÚÕ¿ÿ:>/ ¡dÿþýN§q™Ùjå¢P€¡ñ?ÂE’¯è碀Ö×”ÞàëöqÙ„*¡žã¼»(ýøÁ´£ÓŽÌ:@’7"I M˜”¥‘ȲD &ÓH‚&UÊ c’n !cÇŽ}ïýªö¶Ä¬¾Ã¶ÿk€ª8à|#м‡ûá­Õ›¢ÉÀG)..ŽÔ’ÇzHLLt::uîdسZ>øz˹CØ-™ÅaÝp 9ÅIí/•WúŸx=ÇÙâ‚ô‡Òg¦;x4?G#„çk‰Z"Q·ù Y"ˆPŠ¡¶¼l7åš$ÑN$I/Ëõ–º’yâc–úþ)b`¨%TÑ_m½ò4p0ç}·{{Ö[ú¦@^H?w4íìÑô3G.”¹eÔŒ0P•£­å‰‹î0KÔT?„0£ªX ¾Ií”8éá¡’ah›Ô)‰ê@(Æ8&&¦_¿~5ð>G'x/½Ã¾ép¿ø «¢TœgݽڗZ×¥-ê ªÈà‹l'åô-UQÔÊ8R4¢©å>O%jàÖ¥™EçÓsŽ¥åÛröh^Y €TרªMâ $î*Ô! c’‰æAE]Ñ[í³¼ÍB9AcÑXP2løpŽ3S‚ÍÃçØÒæ£@yIÀ¾y!cp†F‹ª0øYìùÝRhš¾5òRnöumJ#_^ŽPº¿('ýü‰ôóǶœ?QPγ¶ž®­Kâ¡\@{b}“„©5H&™6-‹@j˜Ô5­B“9WMÓÈVõzBÆxøð5u h\3ïÀ›íióŒC—ÚñÌ}páYÒ¤UM ‰¡¡* þ½5Ç\ ´8ØÁö §z VJ÷å¤çžH¿p|Ë…l—§\;_[dj}GSªœé.¥HlD¬UpÒ¥®º¦I퉫¡á<ñ°N: úàà –t¨<£ÿiß²|^“N·Ò=°þù½g<«VÈÐQ_eÍ•¬„ :"8è¸äèFoû–¤NsÀý”ì.ÊIÏËNÏËÞš›íöyBº¶j"»!‰I–w¦4œÄ†X«ëm˜®vÒ±–I’ªL«Ÿ­ˆ€Bzö왘˜Xƒw‡8[yûßd۶ȼr¢h[·¯b ÎÐ8Qi?=pÅZ4­×Vúé7{5×5¯aø(ÙíÊIË?™–2#ÿd‰× ($ I@gÒ\NQ°'K­"LiHÇ@„P@ÚuHB%Ú4!XˤŠvršÄÊ›ô¡&,<«Uš¤ƒ!@1ÆÃ† ¯ñ›å<Ë–¾(|â`˜¶%3œ!‰­ÃŸeþç‹jrÐ µ»o»9|‡J3ø÷Ö\U¡2¤o„1 ×‰Ä Ô¤'…—v礞JÏ?•Qt¦Ì'am… bàh‡‚“jmšg7Y©UÁ×0i¯9)צÍ ÔÔX¬š¦a’fyK4ãrW¼¿O6¼&%þƒHbGœ{¬Ê$nÍøÎ3á¾ðgyâ¡959h†ZF‘jd5*Áà”R„ÐwÖ·³,×ð’Öõª‘€qpRRP˜®Œ@†«ÂªL Q›$žx(Úi6×[&qT/×[ÓI“ë­‘­ˆäià”ÒAƒjq)%ï°›,™[*ë}‹;-;×1ghl¨D]”¼‚ü[º×l_þ€\­WµK†‰—„T¸¼Äò+`…¾gQvˆ§sùÜÄ·­ì|zÙùô’s»*òÉíò6Õ7…/Q¢QfDg%„PD( °&ËŒP~–IØ*‚Úԫ.„1©¶áLêÒ+*BHÏž½Þÿ ŠK:˜*/vÜ×ùÊÍzßòÔÑ̵à0ÔŽÈÃÀP?Q ÿ‹+w€PØ~Öl‡Õ°3+$eˆˆ²Á¨Þ0q L]ùÉräz_³ÏÊ´ƒ`.âÝV‘›V–“^~awYªäßj“xö4$Vq Ò0)ÏB‰UzCb•ÃT¹+½R_ç’‘Ú„„jV·Ìž=sæ,“Ÿ–ª!öýÙÖ­«ÂJ( —\bu¿½)Щ ¶004T‚ÁßµŸŸuNéùœ/„5Û`ÍvX»ŠJ4^Ö¹LH…‰—.tÃ5\hês!ñnõä¦W\H«¸°·¢€wóôç*8ÒeOѯl±@dH¬Òƒ`@”ÖT±ÀÚ^5Í`A5 „|8ï£.]j··uÇêØ7¦i·ÂW(*‚µ|ö¿=“Ùö •`ðé1'ÖXùÎ wø°e/¬Þk¶ÃÞã@•ŽyttôÓo¼Ú¥{rÓ*Îð¹heÔ“$ŽTô†=kCâPkXOÜ´“®ñc£8µ–“®m’DF8'Ji’˜¸|ù TËëR"o¹ãÖöÈ[!£fMÖVX€€oÈU¥Ï/«Õ20Ô+˜ep ÐÅ‘™Fß' pê¬É€Õ°~”” ÿ½Æ¨Ž„æU&µc¨Œ[ªÅ›‡6±*=ñàA ‰Uz]†ê‡i'ª4]“øöBÆÿÈ#šù¨Tqÿ¾Î²{€üƒ^BöSgS׊#lùc†Æ³aŸ#Ø›WÅÄ à8VšEÁm[À]×Âw/Aþ÷ðëðÐä¦]ÚÇ<»¨Š,|»øˆÿTÚÖÜ)†§T;Æpkn1 ¾Â‡5!~ö#FüɸIÖAr|N²År“¤âÏ%;¾ø*µIrFþº¸0&õ%‡1 çÂ'lÕ&éVÌþ\›Y(Røú?€ réð”ø¬b ¨ Ÿ9Z7ãd`¨0Ëà–r©åd X t5›s`³Ã¸Ká­ûWÿ¹í¯Œ?3’Æ'c;`¤ËÑé2;Æ â,«o &%ß0&yÉySÖAAŽXÂõŠã‡¶ ¼É)xSRmØ ŽPã·DMÜ☵~Ì‚C*âV˜?fü›l±XúW{E“ð_2Θµ‰ªƒÐDzo[ÝŒ“¡>Àl>xçÈZñVÌÍÀ}PsjéB¢ YlOß?m!ö@˜j$zóqĹàˆN>”.æË/óhªX`hMH•I=FǤµæ$ÂSå(u‹Êg„ª×/` cÒÈõÖ7)JðYó„Þ½ûÄÆÆÖÈζ݈³.ÈÑ WêI(<,{3¼Wάå12\<ÈÊÊ*q»óóó#=’’’œNgÇN {še𽜂eù„n*/-Ë7`’ö!CüqâqœÈúGâø~¿”bazŽ WP¤!±J)Ò° «¼¢·±J'«”"¡€Ʀ†Wþؽ2*Û¢[ôJõžHf„Fü\ž—4ù9©º Âi??A<°¶¼—µ§¶‡ÇpÑ ++ #èÝ»W]žtãÆM“'_oØmÇŽÇŽíØÑ€ÄM1¸h&ç—´×T„N¸A8éÑ’°mgâø¾k=8 Mâ#ž?ä¬$V›2\hF^‡Dˤ·0|bUNÈ4QôJiBcÝ…áUÓt<ñPeZ ']Y@½¢WZ•i…?:DØx©™ÏIMÁßs°uã¡ÏÊV´ñÑL À5³ÃÅ·{Ô¨‘‘…6RSS7nÜdØÍ”~û=Au[ `*TïpÊø`¿r=‡dµ#q¼ ÔaÉ ð ªÀš4ò¦sƒn mZaRm9  Ö¦AˆÕÚ4Ö1©¡`þ’‚&$†ROW™4£AÉ[ϤŠvjký:ï†,Ê*999%%ÅÌ礦àï1$(y©Þ²n€ª¨À§Õåh."%žPsÈËË3<”)ßÏùU4­`jMBç¸(jéÐX³5ŽÞš8«ˆ[¤0}ë™ÑH½Þ*ö cÝ@¨†I3Š1â0Æœ$µƒCÚ $ê©ê\šï†n ”i†1©Î" „ba;`@jm§+èÒZ¢Œ)[dvyOîȺ-Cea’ÁÍÊ”Š²ŸóÉKó ) §¥t'v hÿ;r±[Ç/XO–ZUjÓÆÅÃxRjÓÆÅÕ«¦…)(ÕXô¡„_ÖG¬èm å ñØð«¦É$3«¦‰²’¤è•lA5^BIX§"8€ÅJÚtãï>Uë' ¥Œ }¸¬}¾Ë¯­ÍñÕdddDz ƒ×QFleQT䀄g^kŠÁ31‘ˆàR¾æ!&¥€ŠÓq¯@¸r²Ý¸øßšŒW¸‘h³''©Òg¼Ð Ö%VYEÀ0& mšg7bc k­š¦I¬!ö$Òbâá¤|­¥u¥|É»a,åKÞ )!V«µoß¾•ø@Õ{s‡v‡—¼äC¡Í=X›C«_¸Ú½ ÿˆ5·aLÒí¦)ñ¼råÛê•:T:×à¡ôLëãë4\Rÿº¨ÈµpñR˜=kFH܃ŸÀA-î£FŠ/€^Äþà}- ?&Œ¼¦h³*ë«l5¬"V{šuÒ Pò¦FVŒ1ÊaL±È¡Èã+ز»ôàqon!õû¹øØ˜”– ©=cÚ¶Œ°ÄI'0Uò¦fJ¢©lE!sF¹jZØ”DIT+Èjräß QŽ7µ!MþiÙ¾£Gþýñ…6–fô¹ý%åžsy…{øåéåkÇË‹æ˜3 „4ôzI24IGaR¿'x¥^Ã$\²4ªx7dR>’LÅšjxûjN½ õne3|àSÙ5? ß–—®¿É bÜ“Áü¶°ÈµP op¹\ —,+,rQ¡ƒûàEˆº€b$V탦ÌÒ=`53ŽËlÍ8Ý^¼Ý\^³,ýN©M«¼NAÜÐÍÌÝR _ØsXå±JÓï,Z«¦•ìÊ<ýù÷â!޳ÄEû\Áz®=‡}ÅïžÂY,$èá>¿Q ½¾–WM3òyú÷¯£©˜ ÝCk­ñÐÁÕ&ä.FÅEÔ‘ <(-^óì¬7þðB[|³Ž—\9ëŽé›²ÄC *N¬ûâ¿Ë~Û}¦ŒØºß5ÿõ[‰n®ïØòGnûýã«·olnìû†¥Ý¿o…%;;;Á©ÜÆ žÅ©:Ttìù/ðIåoÑ Ñ’©ÙK½ÒÞâCGêœâ ÃËÄ l¸0¼Þªi|î9–“¿j¥j5{ÊÖ/–š…î3‹â/Äšßê†ñΡ@QɹŸÓ 2ö@Ù霜µ[ÛL©ü™ ’¸<×;¬”¯ž²FÊ—ÊJ&§Ðª˜-Z´hÙ²¥ÉÛW³ M›SK4ò”‡'k=+>è©bpKÏ»>zJ‹@é…ƒ?Ïû÷+6ÿì¹+š°JX <È…_^}`‘íÖ§?|¹W’ (•dax2—½òKYs{ LNæU”¾}z‡±š„ GˆÂ‡ w‹{t˜=ÅhE®µ·."äô” IDAT<áÞmrŽ OµœœXåP¢0aŒA•ºê¼IBâšž8:My¿n£>?Ø›5éüè-Ö˜hJÀ ñíošÛ¢Ù©ï€¼­»[ÌEÛ9AI§@@ ž¸$krÕ4ãê¢Ê¯6)Wé¹hÙ©<M8’¿sé?ÿßÞ<T‹“î¹R÷x´äЪþ»bû9oLËÔ«/õYÑ_ìd­\|lôãŸNêÅ/1&ùô—ïýø?›{ß;)çÙµÕ?O%ÚÆòYD„é(ø ÂƒààCÜCqð¥*ýõ¦¨”¹q½õºÁ:hâ®Õ ݼ"Ì'™+L’6²¼qH›eå`:´2×›“çz5t„‹ÿ rM»Û'Ùâb‚Ç„1F€’/»Ôѵ=¿ßuè¸E‘ Ž1ˆC•ÈõcÒ,z> \z.1 .éß¿²·¯AZ¦ˆÒ¶BéVêàb¡Î9þàÔ“·÷‡ušôë߆rfÕ«o¤%ß:oùŠ¯Þ¼Ž¬zuÞöR å;>}uQÁÈ}õݹ‹·o/©ÁïC}Éùk§«câ‘÷ï5íï“n¾÷?«³Ê€º3>|gçÐGîéU3‘JM=LÀ˜Á DF>B| Jr'2r¯ƒÀ­Ñí®Ž¼IxSy ‰&žAÎÎRöTLnT„þ09”ó&¨¡c¨ðú ‹ ªe³¸v­„a€1æ4Ô¶*Îå‚Ï<5Ò#VíÊ´j“ª€¢FeZÝŠâÏÆ`·Û{ôèQ…ÛWS -Rd­æq}*G…:Gõüüž+¯úûŸýï¿z<þú¢œÚ¼öH·IÓ$YÀÒ|ÄÕƒa[ÚÁ€ÿpúvßð®í‡À’8`ò•½ÍÖbh¨ ¹ç/¸wo/ºüߟ/ÿnñ³ÃNÏòÓ}^ iÿ}ûè¸gf÷¨©¬¬:ÑS4HÊ"BrŠÖNÉy[“*F‰îé\NóÊŽH#o«Ô• ÎÁ$?¬2aÀD'ýA¨X E'ý‚sp4ŠŠ&E?ì¨æI jÓR==ºi"ß'àñŠÉˆü˜¡4˜`Ž8 ²h$Ï©’ds¤6©ß2)ÓÀ)€V ”C„*àãž={ÚlÆyDµÚ¼M0¡tþvê¹CPƒ[zÜöÁûSZäüïÙ¬8­@ ó ½»çÝ5ãþÕ>/Xî'åE¥ í“‚`äHJ´2åb!4~øÍ7hf°v|í% –ýuæüù?ÊŸòÚc­þš9O þ›3fðBõ el®¹3ø‚DÓaL5ŽíVA‹ËOðsdø4mПaˆ€Jeki Ò"„¡H0I¡<±†r½ðÄMÁT;–B­ÑÁYKgsÅ@«\I§åçrù>ÖØà‰…òÐAH0§aÄC?Z3B5¤|!ªk’JùšPq*f¿K.©ò½«„¤ƒ‹Ðûì+tp]çZ^yËÕ?=÷ÑcßœÔ ;›$Ä ™¹ð‰QÒÉgþ¿œ±ÅùEü\6 åî?SQ.rà­[zwæ•RH@ðûˆÕš÷ëÊgNî¼wò'@}%åží·Þ¸ýžyÿù{³ª³¥°gï>—«Xaq:zNM˜ñÁ…TBHþ9¦ZO6OªÞgþ©¸žJVVœ$Âô1ÃD9IGH#‘š¤ÊBUNº,FÊ_:Å¡„Z·äPñø8.ÆÞ¬‰'·°âB~ñcΞdÇ'„½°-8G<®MsNÈV½xÀ€‚xjÄQ‰'®5#T·º@ˆëMTP¼]H˜Š‰1îÛ7‹¾Ó„&Ê„Be]‹¾Š"ÀÚåÆÙCî|ûóõ£žŸ2r|»'—‘Ñeö –Q´ìü±ܾc³nÃ.ů}óӵݯídsí[õóô¬Ú•04࣯í¿â‹y/yhT²{×¢•ûÛ¼³ÿ” ?N~½=›_¼ym¿·ÿ=¹]“ê¤òIJ۔śW‡Ö¹t8œ³¦ßT™T³:¸VôRÔ„1…GR5|p@sã{_moe‘LŸQ¬&ÃI¤[sŠ8§4É…*L©´cÉñ-¢6-‰‘gîhBùã']”¹ñ½?ß…‚5­€:ùÃ÷‰3ÀÙmI=:‰¯Âò¢WÒãcA7*zÅICFPQIW— Å01Æ-[¶lÖ¬Yuî]õA›$ÉB” \*‚+¤ð |#?xÆŒN{,ÞQ‚ÛN~æñQE+™yÃÕ×N½å__l=ˆ¾ôÎ'§Å¬rÆ“fÿ뻘±W¤°Äñ‹¸Ùħæ^ëY~Ïß'Œ»ùí}ziZK”#1)1‰4‰³!KlBGTµ˜T:œñ3§Ou8üN‡Ã1súT‡3^ eš9”±^BA•÷-K8q0)¬Õ ÀkŽK<Ådƒç¼zÑ¡~SÈ-µ¨œt|ONå¤ËçÓK³5ÒÀ-8¨§ƒÌIç«M¡vaãþÒro‘{÷‹ó:Üpe“^¬ÑÑ%§s²ØP”¬wÚvìP{L %äNº$32èï#Bq˜†Ïõã¤ëVÐÉV ¥cŒûö‹°TSE6'—híuLxù› ¡§É×¼òå5|;±ß´'ßž¦è×ã†gÞ¿A|~ÃDÃ134t gŸsçÏÐ3Gýϯckà4‚›ítÄÏœ6uÉò/`æ´©NG¼ÉÆ î‘2¸&#«i]@¼NUÂJ¼åè?ǵc«7W«1¡(ž¸ C€¤4ÆHF0 )§Kºùøž¦v,„þˆ §Ey©):ÁÑåî3ß[Bý@¹çÈ¢ï’ÞÄž;ümÃÐ’8€Z02!,ÖN¡B´S‡Ô2iG;õ¡Ò4pBHŸ>¨f¥w(ª7þ%åžšP½Ä5T°éé_j ͹Ak,jX!ei‡Ã1㦩|CºßäL c÷6øYÐw´­5ûÁ€>p¦ÞUôÇ._¡˜|"úÂ…[ªZ5Í"1I¤g$ 9r€@é ¢y°Ü'xHO|piÚ¯[ŸÇoÏúüÛò¡.»ð¾!Œ[ÔùÚq# ˆ„ý+€PaƦfuÕdQíêÊÚZP‘¾£££»téR3w® V«®nô¹B^_M§>¢Þ–Ke…BâpÆ«wRsîo%}ððP9ãöšðÁy`@ó.½£(cŸÏ%Ÿa¨]jDO3”º§[D±jš†“.ÉVÄr/žÖ9!¤I·_~°`Wfþ_ËÏç<^[|lBçv-.íÔ$ø'€s¢"f+òAÔPŒ4$q36åKKÂU@ú&‘Ä¥J÷=,–zül³‡SQ£¢±øà fr½k,ÜC±Ùÿ±*gÜ Ô,û›èã„A³ 3ŽøÝaJ­J*zK—¾ ©DÈ;‰I¿èUhýb©IšëmJD'Ýbi–Ú+9µ"0¡”f°„’4,B‰ÚÄg˜k¾ÉÊÏr‹i-ÁÔÉŒMåäF~§Êd‘l1æø>ÒbR:PpBføEæ$Ãà˜d£•œcÜ«W½¨…OmvðKW«Ì1œÁœNç®]»êþ¼£ðBɾýûœNãPa‘+|$Bª\ Ÿg…š†‡’é…é9 ôptN€PàÛüÔDBù$g> šß"BÅWƒŸÂß!ü¡ÄWpá\„ïLáÉ;à`K΂„Á‡vòÝxYF<µ8€àåP¥Iºå¨Ù†ÞÐ…c@@(‡ùm‹-žzú™Z¸i•! &|m`\T™ElŽ9R\\©%õ˜˜èt&têÜɰ§±Šbä©j@ÒK!ª¦"Û^ÒdØ´‚ô|ðh®š’†œ¨/K'd kNòª4¶88í3(¡ ̤¼¸h’J(|ÛÒÜA›–éõXPu„™ôqÈž ÙZ¤r‹üø dÔqÎãcŒY0DzȸkêõXøUÐ[ÚXá‰óI/Zþ»ìEáƒwëÖ½ï•1p~‘q›UIléá30ÔLøàôZÛ7—xågê–Á ›ÕñbÂ%œŠX%¡¿6-ë å³S°Ü$I#°3–j,“<Ï$Hëõäià  „ÊÕmU 2HâšKË/³Ðˆ‰‰iÓ¦MÜ"³@gr$Ü­Iܺ¾9MLŒôðêfTPŠ'ú²IÈ+§(>YÕ•Ž«ƒ>Ö„gœ½±Œ"ƒ^§‚¿@R¢Tä(¾V­±¨¡œà8‹òˆ,•[­§K†¡ÌVTPp“t a=“Ú~e‚nݺ‰{ê ðÉîÖ$ny6!óÁŒgÕ·Bâ¬f•C­TÊ÷œôG†Ú’qô|»ø`p‘{Éâ;bEo~Z9,’Š€b­W‹PÌ_õX¬.³ÎHŠÍ µƒSíA˜ ZÜ'x+#×á:pD²´1_×Û‚µ+zËÊ ó%P„†Šõ‹U3éÅÁùô]»v‹È |ò€è(憉¥z´;V-ko` ²²²JÜîúV%))ÉétvìÔɰ§1ƒ·ÃÔË]*¸[g1û“uÉT`¸½™7>ð‘û0φÒ×°¤Ô*Æ$É/m̳§E^BD¬è-”+!H0ý…á…³<³Ë†G V” ·jš%¸’œXÑÛhÕ4¡˜¸þÒÆ²jà@)í\–tPgŸàt¸Û€ÙI»ú¥1ÔOdeea½{×i1Î7Mž|½a·;v;v´cG7Ãà4Ä×:L­a%å€.”Œksr½>ÆDµðQ² ä¨tñ ñ Ä*.z€ƒÞ1V½R°'„dàÇYF¬Xâ‰+Š^©MÁbâ Ÿâ ™Îy•sN¾H…tÕ4NÃW½R.¨†1nÕºuLLLDî‘ðù|Tá“«|Rî6pÉI»Öµ:<†‹%n÷¨Q##= m¤¦¦nܸɰ›±œ€h´"֕àBŸó,n'wW`¤ØV8¼¢g;Id:€†'<«ˆrtYž7]8cŸ½ÖÛºfÏ×fœj½íc/ÞP¾Åa¶c+3/ô¦ùÓ¶ðkÉí3[Ùº!^îÊc4ñGlòGñp· ^T,•5&3sõO<\Ù)"&8€ÄR·ÜÙú »O’³tùJF£Ñh–._™S$ ¼Vp‹ƒß-lì Ù…Gb z g ¾7RŒ ©ÞT.>û@yǵuË0|oÚ>—·mÒ+Y´O4(:£wá€L§I¯ ­vÛù‹XÞŒ.ÎS~ ’™®šøs§ðE!Tµü,é`ƒ=›Œô±L¦{A·i©Sþ¾“(œvfçh–®X¥ÑXW*Öh4KW¬ÊÎÑØsŽÞà•‹RU‚å"æ@‚KÿÄ~›¤c›(,Þõ§tA¯)k.Ð\¹d̶û Ѐ¶9 \ãdq&Àn¡€£û$…‚°„a±Ý4Ä2È^ÈÈðVïd­Ý°¯ÃÉ0˜ ®v›×$X“a­îŠp…L®©p‰Nı–·Q)>^®Pøúm"IºdSdà}Μ½»‘RxQHq5wÅàú»Gׯ޼ïÔµ{ÙV1¡ñ€·ßî_.‚ Jy@k×ìÏ¿Û_ãÓm“ž–àËFŒZ|ÕÌ;BÚ|ò晽$×þúuéš}gïhp`\ã~o½7¦y¸·–1!’’Ò¨pYÚ”””PUÖªõJÁ%j±–³zÞ§œ8m`§ b½=žÏ¾Qn9#€7U5çå\N6i±m ÃÜhV Ã` Œ£pŽºNÙY~­·½Ü>§Ð›Æ„eâ<~Çú]Â3åù2YÇ&çl§›&_"„ð‡bV«VÍ×oˆ6±L¦Aǵ€uù¤¿ºúƒ‰²Ç¼7{b(¹!+õVr¦2šÊ7…Ãtg÷÷ÞªR­P‹™j×ý=Ôæjà´­GíjÑT‰Œ7.^AÏ~üË”ºaÆë›¦›úcâÚÉí¼›—ž3IÔ¯ç¦ÕK¼Rp¨/Ág à…d;s,×Ûg)@ãBkÏɹ”bʵFÊÀSà Ÿm(&#ÈC2¼&þHzk¤ Ö‘8À¤cŠé\aÂòËH …›×dê0ªS˜ÅŽ"nÏv²¶Ù„"^Mpöx2€ÄI¬CoÁG€¥¾kßÛòãú¼NSþ7¶>7~IU¹ATe0›5z[Oš]øé×C÷뽻싎̋ç¯>r3Ÿ Mh?æ‘mb%$÷Ò–?m:q_/¨ÓãÕ7‡7V#ó•…¯/Býš?زý̃<Q¿ï[ï k¨,wÙaŠgXyHÝ—¿{+~ï¸ãwí;‘m9/Sò†u7Ÿ~íó  Ä>¼Åí•&t~¶Ö›ïdcö* /ÁÌ ·Q …Yèz;ç3ùÎ8ÏhDÉå£"Åè½Ð:q’ »'.X©l‰J.•(¨%gyMöÛøÉF»×,ô¦¹2pÇ18P膻›GÐÕªi¬XbBÆÑŽG¶…<•*UDDd_y°Wï0©9NÆ7ßõvãŒ3æ–âq ¬ÓÇnTèÔ½®‹á§æ³Ë]¨÷ö¢ßWLj˜ÿïâOËj÷ùâ¿/ü¨ÎÅ936¥` Yfñ'ê7mͺ _ß?}ÞÎ `NÞ¼]ßûë_6nXöMûܵ?l¾V.\CJQa¢Zvk's!±$ûÀê?™îƒŸ|=\<-¼N½¯Uޝþ¼é±—ÏØBa)’j;$<-°G[¾Âp`­ÍØóŒÃøÇ<¤uõÖ>¦QÂV®v…ŸÌD¶•æs¤¶¥ë ObXd/>tÀ.ëvávÊ:É·C"9~9q"^N-”½glzÍÏOºQsA7·p©àX“£…ð5÷ß§?øíð>ýõé?dÜš›V½­÷Â[Ýj„È%†Ó{³í_ìQ5¡ Z=:&Þ<š”Š³íþ7ºë°Ö±2Ć6îÞ>üü¡3ù@Úèù~ Ã$€[5©˜~?»êÅo±ÜÚ°êL½j8ŠÎ84çû3MÞö”ÔÛ3•õˆH”áp†dZõÛÉ£…‚Z÷äH^2zù\e†1†Õ›™}> `MýY-(¬òfƶ $Ï]±À8$BütѩՊáÄ·°Ö»ð±öi¡»bÏF0"ö‹µI`¡úéÀ+glvJÕ*å® ¤»OÛ¼o¾ñÍw½])$"'¸É‡CNv oñÚw‹F›ŽÏó='à(¼b…@ë“äedêRM¸‡»Lt9;3Çx}í;ƒ7p'´Ù: SXã2†µ&‹)$ïèÚ ÚöS:FðpœqäÛñ?f÷ÿjz›0ï}³tQ¼UpÐ\nÙÎ9ÚîUÛ¾A oÿÉ‘è0 ðÑWn"fBXý™Yç4`D`8gõ>cSO^"”ÓMdY‡é®Ã>­#šËŸÓÊyÔ%²6 ¡¬ãtW¼I¯¬MÄQ¾¹H¼R|¹»ˆtFÉ‘«,ÏûfmiLѦƒš››××£“PDý§b—þý÷­þëIÉ•á‘`RÊ /|( UTðÍC+ó~¥’ŒK*Y½?OïÎs¦Ãc)%øþ–•‡cúýØ„Wºe~ð÷´ë~óMÏxY‘ÎFœ;A£Ñ ZT*¥« §(E°§[š=X(ØÑBá5Ìp@SN3þ2Ä| ®ÌHÓ]Ù+¾Y×ÃgÀ¶jš}ƱI0Ý*œ;…a…UÞÂ9­øƒt¼X5áy,Â&Á(¨T©’Têõ¯¾²Bò÷y0`žmÂ7¾í#w$¼a‚¶¸¹ewgg«öÓA·þ«©«]ËЙ 1åefå‹FŠÆŸÉÛ±lËU€5)ÿÝÍ%(üéŽS6/ÞŸ’‡ˆ!óÆõºr”PJÝéu¿ßm>´Gœ]1·w|þÞbýÀ©ŸtŒ4ët:½ÞäíO/Î厯æÜ…ƒ‡ÿ±ÿ9w!¾R|Qlp¯cphl1OœÂíÂŽMëÒ¤]ÃøE•åb'¨ë›yNÇXX°.ÅN&`°Ý<±)¬-:æÏèÍf-I$@DFÒéÂ)Å#qV¬‰¸ŠÄ‘‹&~!w[¹J__ud¿±‰µýgëø¹0R0˜Û>åöô(´Åß}¹uéªß>Ys/KOdªèÊ [Õ u dPHó×¾õÛ³Þ\’¦Ã²Ðª­†O|'.$¢Ã„)ºŸ}9b~¶äá‰Þ˜\-¶Ã`z IDATÜ}RJœ¾såyY­ +ŒL'Wý´çv6ž6z÷4n[yøÿÖ¾^Ë›@•¥*dØ+V­Ñjµ T*‡ ¨T…¢¸,(;Gãí« PëBHº 9H3x¶P¸= ÿ=“–ߘ%›ge3 ˜ L€áüLë6±nclõ@€s™1„ Á˜D0F€ Œ9ëÃvBÂU2œ³Ákr¼ÅܶX“õÁI@®šgÌbŒíC† -7Uú€´:e·Þèø‘|¼œ›¬$2Dsu)0O‘””DçEñ~^ç™­öìÞÝ·oŸ2~×6nÜÔµësö»vÅêµ0lð@•ªpVd„Ðöí;:uîìþlEˆÁ‚Ík3¤.Âmnû¶`Sšdx¬Éûg,c‚É{êús³Î™AèMÛ#e¹…˶¦(±59iÄuÉ"Û¼€?]â°ÄCÎæã®Ö›7 Óe8ßþƇ††–7ùé¦Hoá%0E#qç&àsSǦO”|s|üW9š°©x|¼s—x7?GùŒâÃwH”JåÐA¹ þ~/3+E+òë¤4¯M—ˆù$à:r² Ç_sWVž”Œô°úße]€ÂA˜ŽÓÏÚ¦ýsv?XÞŒ€¬}T'&ܰ{RXFâÐd/#±¯àƒ —ÝáW˜G]r•3nšøŠ]Ä€a˜øøÊ>¾ÐbÈVµI³+ù¶/Ó#¢ìæNʾϾ¥ÜN—JqÀ'QªBœwçu‰Å(B&Ú+Í;}óó™±mÛÆ±lö¶®hÏXö„²²·Õuùk5ð–ÝA ÃpK=0¶á9' D¼&A8@áº?à”µ''Ek½Y·Müóóo¹ÊUÊ‚3)’¤N¿„‘ضXbLúúEP(^Q‚õàEÓÓp)ih–š¸n¾Ê[`3¬½ëyŸpVþzXm7²Žëa€§› oø b 'Œe± ËòpVÖ~ËÚFN:ÏLkñÂó3¶E¢M¢ß%—J¥±±|se]#[“ñ¤Ù•|³Ž“Z›ÌÍjuˆ¯_ÅÏ÷Í b&jµçî9"în*nÑ·}²YÛεwü@Á JðrX-[7¯7‹ÙË íêÉui¯;´º¶[ûô°‚ÃÁ:±¸»jEA$î¦I4w®#¬'‘”»!²²µ'œ”Ú}$î å¦>OûúPü•Juúôé²^Ä ÷˜à /¨Tž|(B- Ç]SÿX0€ ¿ÛyÛÉßÝ&¿©Ú?¦¸mÊ[™“Œ0a°­ì„«0áÊ<À©J„±Uª¸©0- qnâÝÁ9Ÿð›ø'ánÇâûm‹-k×q[7]æHŽß î2×ÓGÇݶöâ÷¸¢ºŒºKyŒ¸~íšV«õÕ’Ç®P«Õ*UhBb‚Ç#‹‹ÅÉq³ˉ ˜"¾ì¦¬©ZWÔçõ ñÒ઄õšP8£wa6Ò6h¾pÔ%`Â-¡ÉMö-˜7¬)M"ºjFonJqþÌ´ÃGÒÛFü;d;ù3Óã4ž>®R%__W!²åÇm1µ Eé&¥Y¸mnQ‹Ê7¥x$$&úº DqòŠ}#M. o+÷>8ç¨ü~[ú@ç7U_ÕdÊ>Ê*|oš?§•Ýzæ<ÁLXöìÃ2¹9­Dlk«Ç"b¡xòXXW‹=oÉ¿ )_~1s_#[{Úæ‡ð}7æ ÊiêÛÜ×/‚Bñ ÅQðÞQfq½&Nz-ðÁ- Føþ²¼Ä_IéQCÚ-$Þ¹ŒD›,PÐ$Và­ÃÉðšìyÎB»œ§¶nVMsZ(Nd$=ˆ‰x\Ewë×øù÷ÀhqÊ^ŠÊ7zÆÔ«©¯_…⊣àä¸]¨ wº±ÈƲdi†ÞoÂp¨£ë'ªžMž”#§p[ÐŒp‰N{"”µ>Ösµ"÷":¥88‰xŸò¥à(=OöÛI±ì¥¨|‹„äæöup…r7:‰B)Š£à0"ÎT$çD°¡3¢.m2/ŸÓ ¼upl¡,òV=æ«§c$ΟmÊi¾*±Æ» ûwI‘ÊÀe2YTT”/.žK Ž ½ÙÑa½vT2ŒlëëA¡øŒb*x÷hS8K£˜ .g`pœIÜ ÷FÄ-k@ /úYÍ£›FÚdrF6$ãhóݧRnÄI,²éÇ&÷«¦‰6˜|ÛcðŠåÌ—ÿtåYx-:œÇY¾ [ƒŸY¹«m§PÊŒb*8Œˆ7Ч.EE\Õ$Xx^–oò³0ZÅÔUO»|[½i‡3Å¡¬“»N‰PçUÓD›ÝpñØ åh(&Ê7Éžpt½UÛ}FÐ<”'šâ+xõÜ&Üì!uiqÚÃ3ij Ð/ücˆ¦€gƒ+ÔR„ G]:yÓ…‰J‡¨C<Îob„&B ÅM“èw ÿ6,,,0ÐÅ¿¾@¶è$Ê6:FÖuÜÁE1·­…«—/[ŸB)cНàðvu£C¬-Vv"ªÝvqŸó¯<­ÀÿÂphR1Q*(xÓü%xA:ØÒ¡¨Ðiq‰‹%B]Fâ΄ÜmLl¬o®”ÌÃ|Åœ$'ÿÄ½Ž ]ÃÛ|ý:(óH Þ1Ö\S‰=Ö:l8Nj¨Õ¡É‡žŸ©\Ò^WE¦ä²‘Ü8ÖV ÂØ4ë,†À7ÇIxµÞà$Üömgáæ79W+²¼¼¥à¶\Íf¥˜|iMŽz͸ÕqaªÓR»‚©c _¿ ÅÇd~8!{§…ñ;ã@—ÐÊ;²oå˜ \¼ìͪiLá@ŒuV,¯WM³¯àã¤;/¨ÆÝ‰)/&¸|ÁYöJŽÍ ±ÇÝ®Âpþ~°7ÞhEå›òèäåæ¶iÓÚ×½§I“&ôxX Ľ/×4EÊl£{<:à.î~{P~?×?ƒpP×°**‰Ü>w ?™é4³° ÚåÖ™­œkKœk½&½rÈŽòoíQÑå¢fƒ¹—¯˜yŠgj;»ÞîÝp€H”ÒøJK_¿Ê〯Ì/×èÉÈÈðxªÍ@ y¯ÁÛ¦ÛZóõè“þ4Ý•P×Ð*Á¬Ì^h_ÁÜÕzÛ’™¼Zo~‹Ce‹cI¢s“«2p•*T./é•ì(Ð|5œ),Jѿߚøe*…ÂQ‚«¬•ÌOÑÑ5óNËS ˆÓ ®]ÇÖ?/Iwÿgê\ÃÿRš,B]êl˺i3„p¶†Íâ°à´~1cy9.m,\àØiica“ {ÉØ–6ŽŽ‰öñ¥é®»Ò­wÄüAÒÒ•‹ÂlÕÄ—/£<‘””äë.øåvaèœ „†z^‘Ç™’Qp…&42Œ?¨ðœ·Þµí$ÞÚp輨¯¾|Ê!,bº©«î̺i —ÕäÛÖ« 3˜Kcð+L€'߈ï§3 \“žßDÄ䛋ÄËÃlVÌC]à[G0ŽÂ-°¿=È76Lh ê€òMnwÛOW·nš¼H1NeÝø»ÿ‡\WÛ­_Pôžÿy·‡ì÷í;Ň_çäh–._ £†-†ˆ—˜õ<¬–±j™Å…m"q €Ò4èå5Ø_@‚˜.êªrÄ:Í#È÷@3z;7‰×z»j²ût¾•Ëå*U¨.† L_þ¥œ ¾ý-pQDFfâªjÃ0:Åï±û$ÙÙ9K—¯Ôh4féò•ÙÙ9E²P \ÆÂ—Ïèŧ²Um‹“²c‡®IfîñcC¤ˆé¬®"G,oâYnм͛v˜ÑÛa$=€pf+Á€L“^¹Š‰|]7­˜qQr(ƒ§ÚávNfЬgt_w[ 4›5ø¥¥×ücñVŠÿÃM(•£Yºb•Fc­çÖh4KW¬ÊÎÑÛÞP’?H»W3·3H‘¸¬ëµÂšfí–?SÕÒ&Ñ_ q1l{uå}Y·0 8Òº< ¥p…L–«;äé°+d²Ä©Zlkx‚ÓXžÈÈHß^ ÉtŬ+ŽÎ‰GEÄ7·‹7uó<ÀÁD»}òðYÿZƒV¡ŠMhöÜÐWûÕ¥ƒ(<ô·vÍþü»ý5>Ý6éiÇÙSM7Vózã÷¹/F3úÛ‡–ÿúûŽofê°"¦Áó¯¿?¶U”·ñ!’’Ò¨A}AKJJJ¨J¸Ó %©à`Z}ëåÁØ£÷ .D°`xeYÀ¡ò¢”~ì§(I{u•¿3S0Xìê "K3‚<'gšsaµh¸  Œ‘-o)ðÁÃ#"|xPš!è•`±Ï,(nÑ”¦Ø]馷-‰A˜’Ú¯ü4¿,˜óœÛ0ã«é +-þ¨5Ö)¦;»¿Ÿ¸ðV•jáÎî„áʪi; ¢åAÜ]R º#¿ŸÐ8.Àxg×·o~5?aÍ]U^}D9“¤AýznZ½¤Ä\Ž:xT}£¸÷íÑ çݦå W—å…”GI[u¼„a¹‰SDTÇ9­œ<g'ÝaÖf¡€˜‘¢T©¤RßÞzùJ39ú'¢.г ÎðïÆÔ·Ô.ɯ"$ ªÐ¨K›*†‡©yüO™åê’‘/ÎM²þü#÷×ï9åoɽ´yú¸Ñ/ô¿Á|~áð6¤äªuycb—*^gً䓸§TÀ¾µMk/Hw]•<¢ˆ[,ðê¢õ»äÙš~œÕ¥DÞ4´Â©œû¢ÝŒ§2p^2“SvÖ›2p‰Dì“×+9”ôêE°0¶µu,b‰Jg\D¾M]+™ú>ZÓ±kµÇ,˜ß?“öö±ÅÓ&~¤›1w€Ëywmÿh8;3Çx}í;ƒ7p÷-F¶†Nà›ËK)Kpú¾oÊìÿÍ„D)€£Iê¿¶zçkؘ}óèê¯Ç¿Ÿ5çÇWjz¥¨%øó­T!˜ÝUßòFP¾yH]‚7èaÈÜ€¿&Ô÷ïZ¯P©¢‘*ö¬&•7§oÒ+@ávÌv²¢3Ó ¢òÍ¥4ÃÃÃ|#²çò‚†œqTmW’íN¾I«›ýl©¼$UV~¦çӫƼ¤éÏWp†),ÆÅ¹Ú\ À¨BU²z=~žÞÝ+Ï…òø€ïíZàÞíS¯÷[Ä”§3ýâñ±?ÎìÉ}²YXBë~]ÖnÙ.ó¥šÑ^9)„À¹ó4­ E¥RºÊpŠRZYø8%þ¼½áÃm /ëOpLræ þ3w~–_%ÊÙƒò'Âdõ•ѵEd =À: ¡X“¨|s1x˜/&gnêƒû_D¹ndZôD½ý”f¸bPéôÔ’÷èÖD6«¢ä‰2m:~þš¾emÑœÙ~ø® (üéŽWý¾xÝ7ÚUF†Ì›w±ÕbÒ]”Ǧb¿[»š­ßé†C_ŽØÕpîý*«îŸ:œÓ°fLˆ î]¿íZdÓ7Ô^á\ˆ_)~ù¡5ZmáüÞJ¥jøAE²XJ±Žê¥æÆm—%_“Ïçߦe£¦êßé£py`meT²68×z;ˆ¸ãÌ´.š¸|¥¨ˆ³,VƯ¥™‚û^Bif[4 ^È·s=¸UÓÍí£ /Õ*é>Z}p„T¨×fÜÔµ%P˜hAê¶/¿tnÖôר"B•ŸnÓ$ð6Šè0aŠîçE_Ž˜Ÿmyxb§7&W‹ (éÞQÊŒBY˜…ÑË$(4L© oÿ=oÆ·ÿ¥é #SUª×éï^­çmÝJUȰ!W¬Z£Õj@©T2P© !EqYu…÷¤æ¢g¾ÎÎG.‡AeËÖ©!þ-âðPŸ{37‹`l]À¶†±¯Áݺi[Ì» ®S·¿Å”k î~‰=Ÿg+…r_‡nßo jiî‘î8¦-Í\IJJ¢ó¢x?/ŠóÌV{vïîÛ·O¿k7nêÚõ9û]F»bõZ6x J¥´ïGmß¾£SçÎîÏVºcbBȼ¾ºáË‹]Žbý÷'Î]g‡L XÿYÜÏçV„·ó²Àq@¦`f+Ç Ý9Û‰Al1î6,¬l-t=¯·Ñàhó³—î qÀó[Rùö†C¶ùº øxç®â>`aöð±€ï“(•Ê¡ƒrüý^_+õÑh=ëšG67þvTæÎøvukáÅs€Àá ’þŸ®š¬ ôïH<& |?_cuɧgÙ—»$Ž3Óڲ‘ô¢C1U¡e7›ÊÅAƒnJþÉ·Usƒ˜ˆ{oˆcã¨DS¸2ë¿ÿRn§K¥¸Gà“(U!Î;‰w|¯KÐiÏjDañàZt8…7h“'ß@Ìpøœ¤ÇGiÙ~ŸDª¨Š T Æ[:¯IïjN+äbÃ02™,0°ŒX”fî~Ý&ßöñ8ö:BÆë[ë(K­PÝ´FeÓy Å'”à e¡à2²bTA°}%67R.mï$ßÜÆùkl×÷‚nÞ/‹Î—*ƒB£Bܬšæfq7C1Ë,‡ÉÜ4…tIaÏ›yz]<·O‚eùË[’ÀÒ˜€Bî«!oĉZí¹{e$‚Õ£ðCuEË^ºonçÍ{L×qAç¯ùý¿z\pX„"˜eXäzA5p ÒåE\¥*ÎbE…=g ~îs‹“o‰˜ˆK¼ñÂ!õ ›àê!eÐy T*ÕéÓ§ËþyƒÜÿa‚/\¼àÍ?réÖ¢˜ºYþÝNù£Ë·½ºAHV~­{ö)¿ÏuÜÕfå øu&câP‹‚@ö&çâû-!¤~ƒ†œš—ì!}ÐT”kÀÈúÞX\¼yØõ4fÀ¿«¿šþ³/¤PÜqýÚ5­Vë«%]¡V«UªÐ„DÏ£‘ËTÁ-ÌÜIR4ùæ+j…œ…Ÿ?Óõjçßs§Àmf®A/(ä„Û&ß…MĵˆU«V‚ÃÐElÖ¼–Žô{•¨"Žy{D²Øæöê¼õMõûô…R–”©•Ì2ðë+ºš1ø‘äÛñHƒÆLøæ¹¿OE[I"“ógŽël…œEîÃF (C”®Ÿä‘! û&7pL&ÒCl%û[°m/×Î.k©’¿´•o ¥¨”u2PH~WÅ ;zdùæ¶-&˜ñ³¼ïi™þ-•TAR9vY¾p{\P» Q––‚£4Ø;KþM±€£ÁÍqgáÝ.¼ÅÑŠüu‰Š.³@¡”sćã5ïHœDÜKùì´Ý8&i=0øàqÿ‚¸Ðˆ‰Ô¶z+6¥¸x!w+•ÉäòR™T=` hÅ4q±¶M¯‘}Ã&âL‘Dœ°ùkâJ%5y,…òdᛂ¼FU,‹ßÐ!1µ;ùÆN;ygHKC/¼8};* .,B!‘£ JÉBÁ ¦S¼Ë<žd:'N"îu$ŽPÁ’º–F´ø„B)&>+©îÖÈüÝ»¼—7;-ÂÌ\ ï=20-Ý_¨bh¸”•µ œa˜ àž±=$ŠÞ²™FÞZ—Î"ÎðEÜ‹èÛº]0¯†©›ÏÖ  P|9(fD{Ó´zwe ®ôÝYÓ›“´í¼çouTBÂ"$,k]GÍÉB±ßòï"„‚Jt(&»ËÐZÏÂNñµHÐ-꫸qÝ7UãK°·Êˆ/^ïfœ8Ààmô-&ÖÂã1 ˆ@zúJà˜7¤úø5„PlX7„GÔB§<(8•P8º²áfÙ@¤8©³xÐ-ê«ˆŠ¸~R%ÃØØé*…ò$ã{uû Ÿa\o£ç@[,{ ¢æV™!¶í”¶îô¿…2³úAE«#™B÷03(°$C0ûÈšYØ?²%'ÀµE}p7"nx'VÿË…Í(Š÷ø^Á‚)Ãõïô1Y¾ÅbvDÕ¥ MûFÑ¥[ð±$ÿ‚Ï ŽbÝVrAªàÌa$}–‘N!¨ÀZt.æn qpÒkp#â†wbtS*‚¿&)(”òE™ŽÉt!0{­üëårÑ—.³—Žw¶ÅŠÄaƒÓ woÓäÉúˆH?+UÁggeBDsànY–­W©øÏ‘’Iv=!È–…°´t½ïMrjåï$X?9J?>ÒWò½pÉ2ß<1…R\^3ÂýåEÁ9~Ü$›ø£Âúÿî<Š ÊÐé.ƒ­q7C6ø‚® &¯¿e>ÊèW3ŒcŒ³231¶€˜|cŒƒCB¼™ÉL„|Ä,’Jæ0 %Èú•Èß°^}ÞÿQ½Æáæ¶uÓ£ ¯û`éN;¡ªÒ­J¡”49Në ;S¾–m—¾;7€X\T¤¸q«^‹Åà‚`œ!ª"#ÇG¼b QúŽ[,–ì¬LW1xDd¤BQÄusúIÆ.”¡l¾.; 7?ÖÆüóœÔÜúpaô°îû(㈲[t‚ByB(w ÛŽH^š¨78EâbÎ wy§Ý‚¨\L4Ž|ͨŽð·XÌÙYYÎòM©P1y¹.IG°@ŽKQbH¬íM»±P0¸ÉIè–D›º•Ò’óÊMyTp8u…üI`ZrÃ=ÙßÎJíJ»ù;ä…a¦Ño£b±¯_·gÌfsN¶PÄеwsÕ“ûŒù{Y&E:d_ «R ,‹-²öh¡v«ˆ“(T°6ÚÒ¨TúS(”rªàp;•0>𿛌øäÒ¼|ÿÄ£vóE¸Òe ¹zô3õj¬ßÌâë—î³É”““Íq¥Rå±Årœ5-—YÖJ£5¯k—o. wa¡ˆ{)N².’Õ´Ô’èÖEáJþWD¡ø åWÁ@“‡FO ØLâFÄ=ú'# @|5Ü­¿©û Sl|ù ÉM&£&'Ç.â‘QÑ,+.”–ÛŒ~µÔø»”\gìzÍ×nOa¸è†sô-4Ä-í¥º¥áDåûrU å1¦\+8X,ðõBùÜ%rûÛ…â¥v/·>kÛÏ"hÐÜÒm°±C_s`HytÉFƒV£ÁK$ux„ 碂’‚Õ2KË`qÉv†;Çãn½¡!ndœ4ø¦PJ™ò®à[÷K^Ÿ—"îÊ?ñ˜Ét‰Ûu(àÙn¦Ž/š·³ÈÊ—” ú\­VlÞèPþßlþïRÝv)Ò;¬ªàF¾ÂpçL&?¥é®…ÃÂs:[,…Rø‡‚@ò-fø{W¯1vGD¨ÚÞd2½ ÀíŽ _å hð´¹igs“Žæ¸šåÅ`ÑëõR‰Ä|]¦Ý+)Ø-)8*aôV9–ð”šqzóuœ Ã7ÜEߤ£[BªÓØ›B)#üFÁ @‡&Í/ý]Æ/,¶ˆ»±Â­‚ö» €:†Ôin®ÙÒR³¹¥jC +-ëKM–ÍMb ’ؼã’Šø-q”lûK(n.’ÒtVsóh©ñë@R’s#R(ø“‚süµW2nb@NUm¾½P IDATâ1QáæY(öVÏò5Q¡€J5-ñuq|=K\]\¡–E]òf‹á!Ê»Âæ]dò/°º‹LþU–‹µÝwÏcôí: M`Š{)D ÆrK÷2ÿ£PžxüOÁ 5 ½ùaÀÁÃ’b‹¸ wo¡ˆFµe´ë ‘ñ$"‡ÇcuENÕ88œ©‰\ Œ”HäÀÊ+ÀF°‘ÅØ„LZ0d!C&2f1¦L¤»‡t·ÝmÆp mû3ІÛÞ)®Ãp‘‚BW^ n ?ÊH ­9¡P|€_*8` KWʾüV®ËGEqp€»²PDc[Öµˆo7‡¹:@àÚ; ŒWòí" w6U Âæ)óKl9˜à’B)&ÉÉÉy¹¹™™™¾îˆááá*•ªZB‚Ç#ýUÁ9î?`>üT±oŸ‰i·—‘¸=we¡xz{©³%µGp×ûèÛ½ îEn•uÜL³YRÑ·ï?…òH$''3âããËòI8Ø¯ß ;yò$òժyq]‡Œ£B,^¾¨`ËVégSYVgl{Àéƶ“qlµß2¼[ç»àö.rq@‘°Ûꀻ‹lÛàx0¶ãEO‚ml `±m`ëƒ"q&ƒûò^…âŸäåæ¶iÓÚ×½§I“&ôx˜ßÿFz?oú{wÞÈáF µÛzŒMÄÞ†½©ðTöÜ1¼[¾ ÛaÄvz”lºÇ—Z>¢w‰ë„·ó6øM®6¸ß'¶þÚ®ƒÌ¯€þ8Â/Pù¦<øÊ|»[bÉ¿¼iÁÜÕÇnæY˜ªí†{§g‚·Ó)))Ô´¤¤¤„ª„;Ýðø+8‡L½šz½h:º_²üÙ‰Öîlˆ l’]"扗¸RsÁ‚ânÑZàÆ´5Ëß6²ÍOD®Rwzû?A5”G¶Þài:…éÎîï'.¼U¥Zxá?;νvæa•¡Ó?h'Ëü÷‡ Ÿ}±¶ÖÒQUÉ«§þ’ÙgÁÊUyWVŒgÖºú?Œ¬ìUÌÆ™$ ê×sÓê%OŠ‚s Ït0?ÓÁ|+™Ù²\öש&ñËÀußEòRÊWÉLp½t¹# 'Š!&ù#[½¼L–[úœÃ;NTîþõ3G'í8’ݲS˜Ã›GrwO•ToLȱU‡S4 nÐã•÷G4°~Ò.øøÏ£)Ùyü³Ã?|«c¼ÀpmÓÜŸ·\|“o”Å==z›ÏU¢3|ù/¬<¤îËß½¿wÜñ»¶}Œºõ«ïZ‡ýD6êØ,ü¯»©f¨Êè t•jÆ"€*5+)èMÞ*o ºq³î†*Õñ¸/ôžÏýz‰®y{38y&àÖK½jî]roLgwÛÕ¶è]ÅÚÎåÞ²öfÕR]ØåÜÀ/õO’|‡{w^køÜ³ÕÛtj˜¼k_ªÈåÌÿgÇ¥Æ,ùý÷?æPìùvö® î ó¥#Éußùyåê ?¿záâùdáµ;™ñ˲ ëþ7¶ÂéŸV4”í ¢”(LTËnmãd.%§¿ ­]?Q ©×wLâѯ&.ÙqdïÂOÞìøê€ÖÅÜàJf<þyÁ“ƒ É¡cSÇ>¦ôûÌ-’ý¥—“X°Í.¼pÜYŒï@þùqt‘} {ÿDÞÂÔרËÌVx’T›‡åæÞé-Ç6Fòf]›/Y¸ûfŸÕWž‰kÛç™9ˆk?¸óï9›÷\`*´y¡m¬„7}¦6Y~?‹@Ba5›„@xÓ&UM{2óÈËðGYll,W™ˆpU€˜Ô‡­Å‚@)ÌTGFFrÕ„˜+ ´ê¥gdÚŠ!Äú}†sÕ{\Ý! „h49˜S!°VrÇ„„(í &€`LP^~A„Wïh­&$peˆ\i !Ö>èt@„«äê#¹HeR{OìA@Ìf !öžXÓ€˜„ @à¥zDuÕŒÕ0hN÷H$[êºsò†g[²¥ÍÞy©N˜×ï{‘|÷<Ñ n'²î?ÖØ¬1ýsp³äà&é'XÑAöÎwÝì,Aœm;‚BÿA`3KHSpo³¤â*Ü6Œvì½™®™:ô  ¦‚Õ® ƒÆ6tÌg2!ÊëÉ„G¨Ém@0£ µîG Ã`Œ €9íÔú•[Ž\Ï63 ÑÞ3G5¥å*)ºÿ~ÿüã½ ŸÌT]  ;»ðÍ/ï¾0geÿDöî¡_§|4>ó›^­í•‡V‚ªàDVÄýÞ0ö{èÍB§÷INÛ+Ѥ#g…CôK·dÕÜmâ<6Çn…K#‰²£YÙÉÜÁ̪©ª@þÉm‡‚Ïœñ| °¤ü>i7|ÆAÂqNf6†pFZ&Rª‚¹äôv“´­³¦í¬ôÑ·s›EHIΎφí+‹×A)kHþ…åŸ~v¸ÖĹ/7³~›¯þ}ÐÐvRßêA R›—_=:è»C7_ª]ëÓ„À¹ó4­ E¥RºÊpŠB\¥š´íojÛß„1Ü:Ïž?ÀþwLò_›Ÿ‰ÀI£Ýä3å÷´¨µ"€sHÃIH KHK³²­% ¾=¡9—dÞy¢BÇêFFZßuÏêqÛd=ÝŽ˜åþÁ º~Ð>–ÜݳjwNÃQ ƒ䉞çk´$:±z¸ˆîö¾CÉf(§ã¶)ŇhO-š8ådÃI_ ­+7耕H¢ãb4[É®Ý4Œ5¥ØwÖ?:ÚËÿ9ÎD‰¯¿üЭ¶p~o¥R5|È "Y,TÁ=À0P­¡¥ZC Œ3©×™ä$6ù˜äÎyæÁÖ¢Ÿ°Px’">©›¸Û* ¤–%¤>Vµ4+[XèÔ%îØ»ãr.oÇ^"&¾cÇjëví{Ð6Žw˜´Î3 gfùñ¶Ô {Nx¿S8rõ«—­Ò}T÷ó‹?xykˆ"¸JÇÖ­ã—îK ”=8uçO+Ï?0«Ï ë.Y«/¶NëÖk¤ÔysÆ È!$‘zþQG•—ÿ(U!Æ \±jV«¥R9lÈ@¥*„Åeñï| ¶@Ú æÞ%öþEæáe&󓕘´yZÇÍNA+§\I‚+ã *XY+ëâà:–Àj5JqÉÝ=uðÎÆK¾íåß…IIIAÞg2Ã##J&“©Ïd‡('=ןëÛçÛ×xÌd*žÉÄ@̱L&g+Ú.‡!uœg¶Ú³{wß¾}Êò-€7uíúœý®F£]±z- }ºìŸ1Èý&øÂÅ *•çh- …Byr¹~íšV«õÕ’Ç®P«Õ*UhBb‚Ç#©‚S(Š¿B] …BñW¨‚S(Š¿BœB¡Püªà …â¯P§P(…*8…B¡ø+TÁ) Å_¡ N¡P(þ Up …BñWèÌV”'……K–ùº JÑxmÌ÷ÐQõ”'…PÞ(Jù'Çidgh NyRðæÿBñ/¨N¡P(þ Up …BñW¨‚S(Š¿BœB¡Püªà …â¯P§P(…*8…B¡ø+TÁ) Å_¡ N¡P(þ “I¡ø1×’¯iµÚ¬¬L_w„R’¨ÕáªPeBB¢Ç#é¼(Š¿r-ù®\¹²¯;B)yRRRB ‰ÕÝFcp Å_ÑjµmÛ¶öu/(¥‚Z­>pàÇèN¡ø+ÔÛœlÀ™©éP»mÛJrÄ(kuh«I¹­Á¦¤YC÷»ô¼þü¯é;`ø¸5·0]zZ^TÓõU,’WlÛº.¹{ëÅMg(ÞàyDORRRôƒB)YZ´hQÄGènì\<õ‘›ùLhBû1ïŒlyo퇟ìjê÷#ªËIÞ‰yïÎÒûar»äù\eŒùüÂá6?0èuX6¦ëJc é²}Ô/ó^¬”úç¬?B_ú¡YÈoöÃqÊÍ;$þ¹¸´#‹7¥6R7!ªàÔ­LÜ<›µ}únójlÆÁ9|6-ªÖâ 9‡f¼¿ µççK§7Žfr.î» ©ÝëÅúŸÚ³u÷J† »“²kwlÁ0->X¹úý‡Þz´ë¢™}¬×+ìÙznXµçLVõF÷÷¼¤nùqM €ÅUghté ^ÉÜ«½ë¼3$$XôàÜÜ<Ñýôxz|™ßQ'z°kHþ¿‹?ý-ëůÏ©‚¯,ÿô“›*ÏéßÿýÁÿ~0e‹™ýµKæ¬õö÷mË¡|€¤þk«·Ù1iô¡Î¿}YcëkãÓß\ñÖSœºiÎzÙ°9mCѹÂÉN§G ¤ü³ykЬK#…‚è tаç0ë1Ñ­z´Ttý–â¢ù篿åÝŒj-€°ºÏqA%›vn°{Á .³HbÚ¾5§oe7²‹Bkth§œöA¿•&€àšC§NoŒÜt†â tT=å‰Âòßò÷ú¯³ë 6äZNï9̶ŸÒ£j¨Õ£câû’RûUŽë1~ÔÉwfyAÿ°ÑÛsZ…•Kýæ0^ú÷JÕfã´ÇÎܯӣ¦pÚŽ¿™û-x.’3ïP Aòô„-Û,É?éQ@@ïZ²pí¾Ëiz `ÊË0´4ìŒ,ÕRëOÍŸ0çBÛ©›44ÞØòÍÄ·¦.ûªs¤¸Šã{¾š°!èÍ…›û&Ê2NüúÑ”~žõãØºŒ«ÎP¼*8剂Mè?å«ÑV%&©›?| H^F¦.õØÔ{¸ld¢è0Óá…V+'n ñne9ÕoÓ‰o‡MÛ£)Ðè˜#_˜—¯5H/õé»ãÍEŸÅ\¼tÿø¡>Ïε:­c—gÿõIͪ•àÄÍ3Ô“ènßH¬\5œÁ6LŸ~0qÊü•Í¢åÈ|vA¿²…E¨QÚƒT |uÆiW/gǵíÑ:ÑòÛ™/V+7âžÝ»ûöíãë^PJ‹7uêÜÙý1å2  PJ¤ìöõÝø{˜Šƒæý1ÈzGQ¥ãk3:¾ÆosÑrÛ¦4qÈœ?†”A/)”"à•‚‹†?~‹ÑãŸØã)”'šÉ¤P(…*8…B¡ø+TÁ)E­÷u(¥ˆ7ï/Up Å_Q…*OŸ>íë^PJ…S§N©BU£µ(Š¿’xýZò‡è’Çju¸*T•àñHªàŠ“XÝ×] øê¢P(Š¿âU .ZŠë/uÁôø'ñxe¨èÁÊcÁ) Å_¡ N¡P(þ Up …BñW¨‚S(Š¿BœB¡Püªà …â¯xµÂCÙt…B)ADVx P;<+8…B¡PÊ'ÔE¡P(…*8…B¡ø+TÁ) Å_¡ N¡P(þ Up …BñW¼š›ðÚµk¹ÚÜÌÌŒÒî P©”Õ¼˜R݇Ð7‚^zèà㹚ðÚµkHãÆK¨oå—S§N „ÄD_wDúFÐ+@¯½<Çà¹ZmÛ¶m!%Ô±òK£F8èë^¸„¾ô Ð+@¯€Ï ž™™ù$\/ŽÌÌò»Þ }#è W€^4“I¡P(þŠW™ÌGÿÒ»{íÌí ‡žîý&Bô;£ø”Rôñ÷Õiú› Y@ uãZÑ Jã)JŠ''þr½ô ðñv­úG¼h)W’bã«0åùâ#äëxA‰_Àç7çI“ãbªæÓ6\þéµ ©ê È~Ž"âþ(Ï¡’‚^¹†ôô3NȽrçç3ÁÁ¬\XµêS3fÊ#}ü ÷/åÈûˆ˜û/O“nФ†Wª÷(')“?¿ $_òƒìû©WÍØ”’}éZêU‹ _¼{Î×ï‚Ç7¢´ž÷^êË×jsó|ýòËâ ÜͼóÝ–¹Ú¯_ii]Ë—moô”>3#ª]»Ä1cŒhÕªàþý¿=ucù2_¿ºG¿V¼RpòèòóÎÛ¬Ž}”ó” ^^5_Q²/öÌõ3 |}z¦6+/ß”™­KŒªåæ!–”õo ˜º3‹5Ýwø’ëæ’è[Ù\>·î<è:ê‹äI—!ksóK¤T¯À͇7ÛÏj“pµÕ—­´Ú9'ãá¯ûYôß#~å \_¶ìÔ„ñ•ŒlôÔÝÇOΛwñ矲ϟQ7¨_áù'ƽ}}Ù²GëÝ#`º8È€éÇMôF¼óÁ½ÿFpc|áÔÁÌë'"!‘“ÍÖ_üú˜ ’饄 »;²y$[¬§ãa¾uðï¼Æëûƒ3â5Å~#œº~fé•RÊz˜š#@yz£F«k×):4–€õ}™vÜ‚be!±Õ›õ|éաÙè–#߬YU)öV#~(:¥tò{©i/¼þÍ‹ƒz7xª¶ÁlñÎŒ ‹§ÚÍ©ÇÖ.\±óØÕÔ\‹<¢JƒvýG½Ü­z0â®ÒÍM-T 9'¾{oö._Î\= :ÉñèWànæÝî ºN42®r –Å Ø>a¯Ýtvþè·µœ·â­§dÔÉRz³<žVŸž~|âÄøÝ Rœ;üOãwÞ«6`€ááËCg!GWŒêÚåøÄ‰±]»* í¢¹¼í×ß¶ü}6%C‚"âŸê;nʺ¥ô>Þí#â‹BH1þ ¹G7/Ƚu47ß@²µÄd²îOMÍü÷ßÂ#ARïÍåÿؽoãÿ&·Ómœòý®,\¼g,ü3\ØðÓÖ‹Ú¢?°œóˆ—… äò­+#¿Ù¿Å€°8y•Æ•/JÑÍ÷SµÝ«|±ÅþûR÷õßíß¹o -³×|úýî, ² ÍÚÔ@®¯^IôÐÝñÈg^´|cƒ®oMúú'ûž©éý^ùºS—¶Ñ1áSÓB¬Ál¶µâ̳ޘº_ÒùýEë6ïýó×9/Õ¹ûëï-ûÏXØO„¼‹K&κÔjÒô‰åæ ü¸ý W™ðÛö=÷3ïõü¾ë»½{yäûYÑJ¾ÀáQùÿþy0¸¦òð–ãùÔyß]£}©bYÉÕŽô?v¼î¸qŒDråq’Fõ¥!šwLFS@dèÑ>²¿Ë¹ÿþøÆ{ËïÔ>kŦ¿w®_öõK}›TR”Èûèò¥=ÂàQŠ.Ê‘¿³–<†©Iš›š¨öéGÏ7¨¨”ËÔUŸà%Ûç½7ªgçŸ4~ξ»Fwû­ñ·îÄÜ>ýgÕYO­KšÝû…YGtÄKŠ}2/_–„«ïœ=ÙèÍ·úôôSýû×Iäê.î?zõ2šyù²õ–[ëüzúÕˆgÂd¬$ *±i‹êÁ@ðÃÃ?eDŸ>}»ôýþ¯§²±õU¿·t×ÿ>|©wÏç;÷}íÓ?®ZM7œweËÜ7‡½Ð¡Snƒ&¯O±‚5þ˜:vh›qAVeIDAT·ž/ôýÙâ™Û+{”+ÀÇ;/ú_ò¥“™·uù`(ÀØŒõ†£qßç“O~5E¤$fœùïqþï,`ѧŸÝ¸ó¼ºQãx–à»ë¾œ~ ú•_6lØ8¿^÷å¼£y8\k2uÙ_þ±ñ§G?[I$÷øÂgvøjÙÖM¿N®{~ÆWÜ”Ôùõè&Š£æ¯øcÕ”^1¨„s¾£Dò#õ«5øöÍo³´ª›Þº‘£Ç¸r¥F«5½ˆ!çö‘U[Ï(L¿{ûþžûVÍ{¿n­îxKúùÓâ[?S‘á$°Ñ3MØ‹'¯˜­]5ßß1íó?Ôcg¾ÙT…Jæ=*‘+°ôä’·;u:y7³U­Zé’óï-}ÿùY=Æôjže"Úüt%Ò~³rÝ–wÿjXõ©ÂGáÔ]Û’ŸêÖºzÛ.O]ݱëMŒÁtòÏ£qoÿ°ië†ßÞŽ;ñíôÕ7±Ûýò§ºw <ò×±\ @ à߽Ǥí:7Q”úÐܼi’²ºÌŒÄÁƒõ'ûôVUŒ€K7H^Ö…O÷š5²³ܹ¥¹yÓö.Ÿ9q;®C—šrá©Ph¥æ&.ø}ãf¶×®ýeËë«>±a_蘹ü¹é÷É oüüÓÖTB€äü³à£_ÓžþhÑöíë—ÍÛ¾"cÉÜÿͧ›Ñ€™·ü¾dlÄž/çlK'¼®b^>¥â¢õIÛ~+0³Y¹Fmv–szVþÍ”˜Œôh¹yš»9Y5>üÄöKÁ|éç—:têÚ®ÛÐOOÖ4ûµ¦ ‚SìH®5`Xã–H£Z÷z†9tÑ,‹‰xxäÏ}ç$¡ñ‰Ñr ú“;²õªÀ ÀÚÏw®~ãÈÑØv…Jî‡[9ᑾL²2³kÆÖ^òÙoÍë7ËLÑÞ»—S5¶ªØ¥àÞ—ÝGLüåZÍwgŒm@ìß:¼7¥îà—ZU d¤AQñQˆ €L·Ö}>ýXæ ©ø3³ä¯À3O%œ>u>íAZA¡zíºÇÎŽ¯Q),4ÆdÂf]Á}/™ùÎSuª^®\m(CCŸ)UÁ­Ö„à”usžÎÑŒè‘ß’½íâ;lúçXtˆîìÃûÍëTÌ•^þ|½‡æ|YSM)ŸñëÆõïohTõ)þC,7vmK{úù–ÁLpóO?ܶãºÅÚÄ„µz¾G•†°Q-†ôM¼u8év·€`zt«øïöÃY˜@Þ¿»“”ºÔ‘–þ0Ü>}çå32Nôzeܶ:a¼ýèÙ‹ÝçÿPñùç°Å’e¶Šhs´¡9³´Rƒæ•ƒ%«5}*"'=Ó„Aªgú¼P#˜!HUÿ™Æª‡wSÍ@t§öU<7|`Ý0)+¯T!ŒÁÙÿì<Ý}dÛX0aMzt ?wàT±_Ÿb_^ŽèñòlVŽmýE†tÁIF–¦ ÀdÔ¸AëÌõkäó RINDг+6°Šbý¢‘Ôyå§ÿ½ûpóÇ/oµ¨ÔRBÀœ•‘e83oÔÀ› ¤™Þ,iþêÜ/¶¯Y=kìR»û˯mS!7#S—zäÓ¾;¹¯"üÿöÎ4ª‰«ãwf²‘=ÄF! R@Ey­k\8ÖZ±k«¥­ëÒj—ãR·Z-tDAÔÚ-¶}{´Zµ«´Uy‹Õ"È"ŠK°‡„,„„Ì}?°…% ôÜßÉáùÏ}æÿÌ}fæÞ;ƒ·÷ÖÓìwßÜþô5] (ê”ÿÈÊDbÁL§Yg3~´aR$tÏðiaͶÇűí"ßÖ:„ I!W²ìÄ6˜iEHÙÙÔãdã_6 ŠøT`ÏæÕò­qæK]=©48Î}(Š:¼®ì^Áí£±»ý½Ý;Ø·å°A}BžÉ”xS½BMç°©œi“_ÕÄoØuÚ5ö‰¥oXôˈ^³!uýÕ¬¿'Œú­ä–¯ûè"õ½FÁ“5fWüå´­?ø8ûv4¥Ï9—þ ª~Ç‹РÕð~ÎyyÝ$€°Ù Àx"!®RªH(î¡!>:p¾{Zú¯åsçæ_¹a˜äB ü¬èU†³3x˜‹cÄÍ—bª v°)×T äÀ¡±aá÷SRlȤ`Ðٹŋc •µŠŽQ@MÑ/ß¿˜#k8ÐUU‘3šgèÆðñ棆C½@R-WEÞ"ÛnŸIyMþ~ÚÚÐÿ6›3êñ Z-ÙÚ‰¬ÒA,\‹¡¥7õànÖù’»YbB¡„=‡ª#1ÅÙÓ.²Z5ÂTiÙFÝ­½‘þ»#q ´çà±è̶ýg¿sù<æÔ•'¶Íê0 oBÈšÝ!•×ôq4Ë)q!ŸËp ‹=¼ÂÉôij!ø&ð¾¢s]ëêÒr™H$qùyù‹ƒ—,^Òl¶›Ý[þvаuOˆq¸l̓š²±öcÏØ”üüýíìKõøì-/¦ÕW DfcÞ[ý~tvQ–›G •Æ'(MCqÁ¬#±ø{t2މ<½Ž^Í,]6VÒ¶>J“}í¦ÑcõΗ8rìF½·¥`í®½ÇžŽ{Ã1÷z¥O $¬J\—²öFÆ-Ÿ¹¬kõò̶g|üÍÛ¾÷‘út¶£¹qæ7öòOã€|”¶9îì•ÞÓh@…\nÀÚÊ’ãÆn~Ö7SÞâ*NnòWßd°òs¥sW?eWúzU€íæF>ÌÕ«ôz›*NãPÕÇƆ…5TWU§$ZœI0ÝÜZ.=b/‡#WŠ—E¸RMì²nM.éÓ˜]RÞ”—¸2ÆÐÚ4†“û„‹ÃÁk«kI l=í1ŸK›¸ðhìB¡iOhªië\ÃÚ£(%ù™9çpˆiTj¶ A' “E§à©Qa‚¬)~™ãšÆ]ÉÈMLh­Zž)(ã–½1µìÄáK5$>fÆ<§ÛÇfÊHÚŠ¢âJh”Ý-¬Ò!  ¤Nbj“¾ ÒýæMל?vºPÑ!lT<.,©'! °¹´Êûê!$!iG×a‚åÒå§V©ËdeB¡€ÏáåÞ)ðòòè­Jk\: $ÆLå˜sò«¬  õŠÇkŒ€Ù \—¥¾.º¸÷Àµ¬)Ú~‡b·ºKœÿ&vÓú×/$Gíœ>Å«›qé’צ՞ˆŠ;w§Bm0êÿwrÏgˆÃ–Ïæ¶öA¶“"v†ÓNE¥ü©ðJ*«*´:‰cã—® qô¬Ð;!.ïë­ßúI}»ìIÊ?Ÿ5:p¡§X,ŠEB±Ï¢@a湫r•×<[¬!¡¾òê7§ï;Ϙl‡ÃÊÛüd„LW^N9Uà6–" GGË)<­©LKˆé?ëÉi;÷Ø=óLÑþý9!Ïåe€O«¤ò‚££[£ìúÚ3Êï"?ú6ëa­V¯SËKî–i J…ÆVâ6š‰Ã&ù­+YÕ$0ÍÛü„Ò}gù«/?]To„ƆÊGe*(œä÷èTÊ¥Gj#¤®¦øžLKšTé¯&Xs¥²¤øŸœô¢‡ž®OéÔ:µ¾q”ˆ­3’šÖÑ.Wì¸dÝ&­R}=:ÆS©¤ÙÛCØrS×’(fðê ×µ©ÇþšºiòÒí[ )_¾¾¯¾ gÚ»½°q§”UùûÁ/~,Va4ÓaÒ+Å0lÊš˜×%í[“ZÕi<çi+·ozŠMñ ]ñtÔço<?neläRÉ¿äc,‡µ3$i,-•‰ÄB.‡“sÇß߯;âÒÁ7×å;ßÕ%Y©‚,éó›Vy´n%C6m¼ýNlìEçç;ZUû~+Љ£ñ»^Y»í÷Ë_U”–$îÙ1{š9A0þŒwèß>ñ雉*’!ë9{åÞˆ¹®Th’À!€€æòÒæu÷}æypç»A{¡ \“¼:qÕ¥/³sókíøÎWÚÝÁÂò_ÎL˜·Ñ¾}ø —I¿½˜.›-„ËtÒ¤ /Ü«5°'ÌsèB#4[Þ~òP=æÁŸ~ðÚ2‹Y%v½*ÀŠfEE]^ÿ–›#Ê 3Y„üóÈ;‰û)ke\jA­aÎþ(†PÔjÌ|/ú]jÚõ_V¨ ¦Ø9hÍîSÂVý³j­­-Cìäw«¶-»¶uölŒñfnˆ¬=”´+"Y®§Š§¼³máèÀ-{úèåxy#`ˆÆ¯ßá2ŠÒVÅ jôþ.¥§/X0Ÿ´ 5­²úö/©„² Ç! `#lâÙPT:#×ÎIUE<½`1KèHP骒’êìl—E‹¬à¾UÁ1ìÂ…Ÿƒ‚ƒ‡Ú‘î±<]QÔ)ÕjX,ÌÉÉõó÷Åña}I3ˆ(Ð᱓?¹—øyXÅ  .çüêdï,µ—ö½ª!ó“WRÄÑG"\‹Ê;ÕÎKzs¯v}ê“û0¾4pþNKKÿðC)¨w¤a"€Ñ0L@‰Þxr‚£¢|–-³Ü™!ÁÂtdñ¼‹’1˜ÜqÿY\õ [¯¬iÒ+J•Fƒãtš`¬Ï³óh [ lj„#‘Xçd]þ¥Ÿ¶Òëõ¥¥2F]^.óóóÁ1l8ŠoÊù°@DøB+´&ƒ Àœ‰sú[·ùÙŠìR×\¹) ŧŽ_b.ˆ›Dï[ÓVÀ'<||PÐOÛ·ßÌËÓ”–âÁtt»»¯‹Œd‰DÃ1è°,Ys#¨Ç |צÆF¡®+WT˸¶,ªPJ³á€îdŸ¼ [Sé,q̺ ÿ˜öo ¡ °@ÂÛ{"N#ä0{Øô$ý7w~63xgé(`¾3žæ¦Þzœ’kÌŒ_ñÉz»)¯o •}sÛ* 0…¢—&÷j|Xe¡6,>“¨NÆŒÀq¼¢¢³´—þG¥RbTç`¦X¼SƒÅ;5X¼SÀóNvÞ+LŠ œ9uɡڪ³yoüË{OmVó’l=³zÅñF¢ï˜ñQñj_Ÿ5?7÷ž%ZªD«Ãƒ|ü¦OÙ\|¯ƒ|§™ÉοKÓcCƒ¦M [³ã\ƒ€h.(rÎý5?j í¿/l€ó¶w¢én­íØOíþ¯ÚÖÑc¹}Æ uEÛ/è­_F¶\رåêˆø‚ß.ÊÃN¤äþù.æM÷‹S ”SÒÅÏŸ>™êÙ˜Q"%ˆæ&Å`÷1|:¢Ñ­\1þ¼^!=µ>"r^üñºÇ¥ëF†¥U4ýž™vQCèkî¬ü8.Øí…[²ýFE ?hñÃèˆÁ Xľvþ¦€PTX1sÖ,¿Qß’ô^ dgݙ̸ðÙ“}§ÌßP"%H½NÏ⺻°`¶|w.£»«[]upöóÍÊ [CB"wVû_G¿ñº’1ÞÜLqÐÝìe…eï h¯ÚjLÜÍÇÈöë¹Y’‰ yc›R^„2i‹ÏÚ{ã°q©á¹ÉWÀáMÛ¸ðs7ÛîúŸ¾‰Ï?íŸÍCmW÷&h·ÙëÁj—+‘ FsŽ&mýÞfy0OZ*nô[/´ÇGí`ê#SLI§Öûp{ ÀÛ}†ÔÜo  ÜX`l|Ðâ*Ñ;Jª®æìiðOŽö`ô Õ뻬™tôâY[Ó»t]$ÝuÜ7; –Ðk¼ƒZ¡$ºn^¼ÆøjÉ‚Op:aÏsÆМ'…Os¬+ËËÌ?åÏ=ùðê©2^Ï^™qM«|ÖÉØ}ɤ}®Bw¢"E“ÖŠBÕ»(ç¥% ­^o0“É0tt¿ìè¤ÁÐÍt``dg}yáÑòÛr„ôÍ ÂH :Tj“Ãx‡¾bõwòã·ÈæîÏ’Uù1i½2-'ÖÃ\Ü¿ònå½êЉ’¯S ßå-ves”dfqÂgV@<ÇWÈŸHâBD@;ô†KBo¬ÌýAÀí*“* O' €xöH ®_:õÔˆöËîËÜ&´Ázj÷,ØÒ ˜ ‡)J†¾œ®§þÊŸäàQ6€;yYlUxVeãR‘TH €7úŒI&mqqŽ™ädÃGºÒ0çôs¿;\tìp‘(Ö‹á¾xO~JàP¶·¿·¬ìXU‹‘4È//kñòódõhÔ¶|W LÊ[—«&`zNñn/?z²^kB×Ü(ë@Ž.Nm’ÊÛjÕ—ï˜\Ý?à Ì[ô}{­R9‡ÏµCãc=Ï“Ó[óÃÕ×õƒéˆfÃbÇÀ€á›òdûîå)]ÖNž¡©‰~„&FÄUdlŽZjkËæ9kšWu+§¬Ý©ÊÍJŽÈi5X9N\•±iNPbòó}»cækH4‡ñ³7%ù±|¸_Jo‚JJNÏ¡: ó¢´ô´ùTöÀÂâ,Þ©Áâ0·§:³Çí16Ç®¦¦†êL̉DÂæ°‘ZÓÖððA[[»åÇ‚~ÇíÙ¶@ ø"ë›~RåIEND®B`‚Qt-Color-Widgets-v2.2.0/gallery/ColorLineEdit_with_color.png000066400000000000000000000025701366475014400240550ustar00rootroot00000000000000‰PNG  IHDR}Ä pHYsÄÄ•+*IDAThíš}leÇÏ]¯wíuï]éÚ²vce 7pÀ`c F†B‚QŒ‰F ˈN¸4,"Db|œɢ Lb “ÁÜVØeÝØKÛuëËݵw 64άýüy÷»<ßûä{O.—COÖTœýb€ ùüå!CiX’eÔ"àìǒȤhÐÊ*"àÝÞ`O¿B p1ÖT¹ÃD”F=rÃAD·—GOÈç'äΡD½ËCÔ»/RÛ6×KÃî°Òq©9Ͳ}.×Ùµ¿%öÅܮˣãá¦&¯©`Μxª°H_»¯¯ù¹¤|š¿t¼½¦Åç ˆX÷̪iÏ[)€¹‘ºÚ›µÍ#‘dµ¼ýªãEU²FO€Â4YM7I‚Ï}ø°ý¬G«ÿC•´¡Ìš;a ?îfWÍ÷ÚÕmy3{a°{[5Þ¸)ÕDà€§ºfhÖê™Y®¶;ã8èt‘F½r´“„–5J7Î7PÆ,ã¦Å &•ÔqªiÛñÞÂ’T# 5|o;â3•–ÍȠ÷‡AO ý³ù³öJÆü´>xªÎ?ÿÙ4K¬2íµL~g«¸fÞúŒ \vøû>ƒ}þ[;™P¯ß­c'žÅBÃQ»cvæªÔ{ê‡%N ê®DÐ”È @2Mjˆ4O‹Oá‡0€0tÞF.ZjÊŒ!H¥Ò¨U’dRÒŠ<ºãBç5ݽzýfåÄ6}?c}=«n\ö ¹û£1Ày‘wËή¼âÜå#öo† [W³?v!"¥äa€%>D&*s¾s§çìÁ B ðƒX‹pP–”ÅÝ»°Øz¼i¼Üh&‚—~nûp¿Pö–e‚·|œ1ïdºҼeçš>M­(¢ë]¶ÌÙ`%@ Ý3Ø×?ôÞö[€ÃaNð”½ïY[’™š,Öõ x*ƒ$—¿Ty‰øê Û¡AÓ¶×³Ì ;í%_c@** ®a€1õ¢¯¾Eš·Ö`a@5w¹¥±ÂÞpÛœ‘"ƒ9¸ï=÷ö úé !ƒLªŽ ˜¥ó‰w&ø–ë¥ ±ï¾b0ÆPüìÄê“ÝWr¦Ìbù‹u·Ý™é94¶ùÂ줃@Z=.)@_>p²'­!‘û•ŽÖ'„Ï´x½æø8Brµ ´Šêâ„HiûýÞ±à¤L:¡ÀŸ¼*G3zÑj%}w„W@*bc(=3cSû—»/ìÕX²:9Á¬ÅiõGÚ¶T*X%S ›Ñ& eAqöÐÑ›•txBH;}Ê;/§½0uàûÖ!Œ€Œ‹[²ÎZȈ ås³äŽY¸[£ßgä!ê]¢Þå!ê]JÃÊ!â 4,A²Œ¿»Wî$„ÏÑ«`…Ú  öôÜpD,xPVÁ2*ƒî/ H ”XÉIEND®B`‚Qt-Color-Widgets-v2.2.0/gallery/ColorListWidget.png000066400000000000000000000137171366475014400222130ustar00rootroot00000000000000‰PNG  IHDRàc#/ pHYsÄÄ•+IDATxœí{xÕÝÇçÌÌnvsÛdÃ-‚@®˜pK¸”ˆ\”‹Ð‚P´¢ØG -Ö·iµµ¾úêÓ‹ÕV[kk_-új½ÐZoˆÜ´rG@ä’X„!Ü„l6»›½Íœóþ1É&’Ì,›y2¿ÏsÝŒgæwvæ|çüæÌÙ¯dÝú € VE4ºLŸv]MÍ1_Àïið$'bVvVFzzÞСPYYÕØè­«;ŸœÐ}úôÍÎv•””ZeÓuø(p¦ãéééÈçóuºëÇQ K2x°¢ÈÅÅÅîÕC|~äˆ(JÁæfYŽ–••'3ô¾}ûl6‰s0*tii©úç¦>¤É tŠ?à/**âÉ¥¨°Ðçkjll,++àÉ,ååeO£¡ÛŸ|LŒÇãiäœÇ±ã¡C‡`ĈqÇmôxâ }™ÔÕÕ€¡c Lçº{ùs窫kEÉÎv0@oDBHkhq9‡kô†×âœgœ3Wš´yùíz£Çº‡@˜Ι®Þ‡÷ìÙ]XXÀ9ß¶mëœ9sRRRtÆ$í¢k݇q~úË Ko*%„¨úÛ?vëíÆ¤-²ŽÐ ¡}h€)Póríõ÷ìÙ“šš*Š"¸\®-[¶Ì˜1#Îд†æÀ•Hs("„¨ƒˆ jß½•ÖÁGOèq±P¦€é@uuu}CÃСCÑç¼o¿~•••‡*+c“ZøÊý_»ö8W"A¯×¹9þÛ¸®Ð=C‹:¡3Õta¯­Ÿšœi€×ë­}ºó»ß#óçkÛ€)`œ3 }a×®]>¿РA c±yœp$ÒÜÜ ‡½MM;vîœ8q¢¦­á8ðnqWšÝÛx!op¿ôôT‡ÓI› J„RÆ”É×”ûýþóçê¾8v¼¢¼HWN¯%4ì½÷ž¼Ù³3-J$UâÌéôø|_64,»;uþ<íqÛƒ0œqÎºé µµ'>ìv»ƒÍͲ$ ‚@)eŒ1Æ8c’(¦§¥Ø¿ÐÀAƒ ê>bkÏÓ’‡Ü4kÜÚvlÛóqhÍigÄÉ»Ây0òx¢uçëΞ¾uîÄÙSÇèœTÕ”Ee9PWgFQ¤œSEYfÞ}ûü~°Ù¢²w*…0Zº‚×Ûʵµ'eYVeòäÉê,¢(••UêAã555Ô1öIK"òÇ—L]pw}}CZV.•2¤¡„ˆa…‹Þ† ÝÒo~~‡î'Zm¡K|pÿO*E"%?v€>)’düñ¸¦Q¦€qƺ{()-)(,P¥òÌ3ÏH6I’$BH4•yÉ’%j5Q»=€¾þ®Œ´¿þvÙÍKï/>ÆãNOsRJƒÍ!&GÎÖì{û¥ß¥:=Óÿ¡àŽïÜñn(S %I”Ôv›M Ô&I”Rœ‹Bë¥ÔöRYW ¤2qüÈ;oýÆû«Š–>ÔÇ-Šbƒ§qÝë«—-¹aTiAIˆfp1œ)à\•€Ö"I6΀‚¨~еûW_;¨7bMåþ{¾ß75zpû{QYVåÀö÷¤E~|çmÚÀ[֥鞹[nNQ›k¾¼·Ög-wm÷BQ#ÑG‘H„é\I½‚Õ¼¯MŸ{ú÷ÓgÍwõÏ£”î^÷ÂGß(Ñ—‚˜i-¦@¦€sMïbØíöƒ¨S@Š¢‚ kwà<¶N_'Ì:ä‘_>øß¿ú-gìÉÇxÅq¤þñ…¾|:†C˜¦0¦á Æ‚72ÖÖã !ºv-»Ç‘ˆ/ºå¦-Ûw ‚xÓ‚yñ¥þq‡¾L:†COFFãœÒ¾Ow !ä¢7¾ºz¥”qž‘‘!PqF¨ŽÐ*Ï>ýĵ”RÊ8s»s ¾ÐqÓ>t €ñddfœ>}:77W 4 ÷C¢®j>sÆ•™™b·UUU•””Ž …{ÆØgUUnw67.t]! gú´ëŽ­ñù¼MM?='œŒŒtW¦+??*++ëë/$'´Ûãvg—––ZeÓâ` "áP°9ÔèI’+„$JŽ”Pë_„Òä͆SJÛÝñ ÝÚuØuý̤µiÏ„õú÷ëgAkC£+„¹°¦5ºB -ÔÕÕÅ7øÔëû ÈËŽ;.èœ>J†‡Ž0qt…­Ï®Üô™j*/̾¦lhrBst…@z]á‚7ô?Ëw.üÆ0¦È÷<¾zí3ÿåv¥é ßr„Þç Ϧ€h_ÑÅ8ðù2RW†½0¯ï½­Ð¿2,žÐ¼Õ" C¡P(¤ºB$'t"ÊÅ Ìž‹øêú#U5gGgû¼&o ldÞ¡£'ÿþú¦8;ƒÎ½TW¯××äõy½¾Wˆ¤„î ` d ´¯ŠùωÆ?¿ñÉuåY᥄(²ríÔq>󯄲ÂaÝÿ2îÐè ô Ï#Ë~ÿæ•Ù‚Ý&†#\ý1Œ¢€dsŒ5ü®ûŸzÅc)v[ÂC£+Ò³¨Ãs·Õzúí _6i\D T ãÐä ×Õ5Ö{yÍé†_ÿé¥ßÞ¿4á¡ÑéY´$k·ZýæûùÅÃÎ_:œ¢ÝN©À…G£ s[JjzŸÜ¼å¯¼5cRù”«u¼^EWÄhÈNž> z*·½µ?ØÀ#þïüò_v›PˆD¢k_ÿ+)2SäwÖm™RQ–ØÐ€®H¢¥'ܹpÚÍ_¯` ãœåHKu:JI0ކCÇ>^„GŠ]WgИˆ£+ÒƒhL2Óê[Æv»-=-U’DJý@¨Óao´„‡t…@z}³Ùbzj·Ù ¢Þùph{úÔ±W¯u…@ŒGϽPLíë÷7SJ›„€ÏàLÑĵ ]!Ac6#=3{劘æÑ :íbùw|¡ÑI<ºÿ1«–e¥e_à’(èöj­®ˆÁ¸Ý9zý$I¤¯ºBèyuùÖ è $ ·;Ë’Ö ¦p…hÀô†0ŽÒÒÒÊÊÊO÷í7ÊšÁ‚¡cà4¨I°¦5ƒy\!V¢+„1L¸]!’]!Ì…5­Ði]!’: À +„Q Ì‚®Î€®ñ®&…h_Ñ…®—Q.`ô\Dt…H 02è a(SÐùðÜt…@WˆÞ‰:Ф +DÒC·Ñò›`Ä@¦O»®²²²¡¡Ñ(k †VÁß›kZ3˜ÆbÖÎ;“Ö¤=ë*žCWˆ$‡FWsaMkt…@Z@Wˆä‡Ž0è a(³ «3 +D| +„IáÚWt¡+Äe”‹A˜=]!(LLºB Àt>9§Ãf³BdYV˜Òài˜7ož ZŽ ¯ÿ£+„ÐxîW )Jî€Üá¥Ã««–——;Ji0¬=qbô¨Ñ9îísAzS `4=ÆèÔBW¼Ø+Q®á!8ƸñãOœ8Q[{²°°s8yò”(ÙF—•i?¶Êú¾õåÓñ§7(Ó §%ЂƒŽÛ0¥tæõ׿¶rejZ*!¤ººúÖE‹@ï˜Ó¾Ó'y@Ws¢1Ž‘PWˆîß´'33còäI›7o€©×^›žž¦w-ç±ÅpÉîÿáLÞl8®LaLç«ÜâaW?QK)-**Ö»/`±6$ù c8€ñè ‘š–Ê8'D·5ÃÌ™3!®õÌ”RÆyFF†@t…@ u…°¥ØOŸ>››+Pš„[1Qÿ7{gθ23Sì63¸B´`Ýò«“Ó¤#¥¥¥•••ŸîÛoˆ?‘£5§Nljò%'tFFº+Ó•ŸŸ~ë"LŸv]rZ€\ŠáǺ¨0ߨÐ~ëø{ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@, ±4(ÄÒ Kƒ@,›>øÐèf ˆ1O£×è6 ˆa` „XbiPˆ¥A –€Xª««}M¾úú F7A’„Û“™™‘—ŸOöìý„///7ºI’TöíÛ@D_SÓ”)“9çF·A’JYYÙæÍ[Äúúzìýˆ5©¯¯Ç‡`ÄÒˆ€#bYDõ_(.xóøÊ>ÿ£Óf¿oä£cÝSŒn’ˆ pIÞ<¶rQÑ%´²fùX÷d£›ƒ$ ±³ .Ø{n÷Ì¢Iv›Xå9pY'*ºíá^ú¿Ï.Σš¶#=Ž¥ËeŠ/Üìø#ŠÒeÍèþ§¿=éæ¿~IDÐÊgoœ:ç®×NDc£?2ï/Ÿ`†Ÿ^S %âº@VXS$H€De¥«Õ¼÷Ý-iÅ™ÛÞÙ½xôDg'x뙿è n眦ێ¿úÔ?+žXx¥ÐZ :Ù¹ 0ê„·jÞz¡ê…-g>² ¢M$6GC”°ò^‘C’6i\߉×çÞTž9µu'îÙòÞÇCæ<>iû}k¶ÖWÌÌ&ÜxõŸþ²b×éHjî¸y_‹H¤åt_b{¬ œ0ûÎ’ÏýéŠ'æ e¶®¥Z°æýçž|uë1?uNÿþ½K&5¾xÛž¾ö‹I)Àj_[ºø•Ô»_~j^ʽk¸ãíÑÏ<»0¬ŽˆÐn8@T–mX¶`øÜ‚œosJ$ž~I ™1x6¥¢ÒêÞ/Î6¼Øü»²1S[öa_nX{tô7^8&uôßßÞpvÆÂ\Üý·ß¼Ø0÷É׳{ö<ÿÀ}>(à—ÜÞàQáªÅË®ÿѯþ°fü“óZº¯:Røw/ÿÅ ·>þÊ_†ðÃ/Ýÿ³Gþ9øÉò2ñ/ûŽÊ׌ÎìüØ?äŠó»>i¼aVVø³O÷ûÝ~¯rgP€ÖKk‘eùXýµg¾ Ô"ÍpÀò¾@4pÎwvãñuÿ®ýðXSM(‰í¢Û°ö|ÅÜ i4mü7*έ]W£p‘Ã[wE'-œ?,@Ìû­¯ºØþ• +Ì1â{?^÷÷§ß=£´ô_·>Y¿E˜vË C”8¯š;£ðØŽõÃÆØŠ)çvì87êæ†}¾k¯ÉG÷J=öJjøY5ciMÔÏH ]ýð}›¥QA©M& ¾*ÕfÛQ»;Eí¢˜ž&:ìÍ7üIëy‹|oã±óM}ë#À£Í׺ƒ‹~8š<×б¥Z†;["À³Kloÿ þ“ƒcäí?›v÷Ã^?þ—9„pàÌw¡>øåއ¾¹^X„ö°Stúß•fðí§†Ï¯˜Ð¸aÅŽOµ‡B#o/ñwŽš©7¤…¥eK—–-ýé~>“Ržb#²¢ì½ùTûš-ç-°çÍé·ýñóPv|å/þðîž;F}--3µéBƒÂó(ð Ï'sœÓKlow8ðÖ[“cÔâOÿÁ£Om\âç$5+3eÈÂ'þïö!íÓzæ,òüþíۃLJO/OËöO¸â•]ÛwŸ?W:«Ä†ýÿ` Ô}Q‹*QJ ÊXgXÖµ»¯˜6gxŸ>9î>9î>}Ën˜æÞùÞ¶Z|ÍxºuÕ»ÕQÏÁÕkD8áÛ¿R íÒ8F,Y6åä‹+v‡Õÿdsý5µ/½u¸Q朇O>ÙÄ8í;ªÜýù¿Þù¢äš²T}ÇÍÙ¿êíê‚q£œÄèshÒÒòÀèf˜¼(Œ÷{Ïú¼²Â:©ÀÎnXûŸâ“ûµI:hÚô¼ƒë7žI·ôEÎM?[xãœo?ø/çôYWRàÀ¹ãÛ/º:mŸ£n¿çZ©ÎÏÕ! mü]-é·ý÷wÍ3ö-Ë~·æ¨§CÆŒTŽŸÏŸXžÈ€qãSNÎ-+waÿï¼YµjõìÙ³ÇòRð‘ÿÜ ¦ÚÒœ²ãÓÛ?3º=Hb „¼ÿþºÖµ@(€Kó“·=z`EQfÉ‚Üùx¢z¤m-^Ö®X<üÑÅÃU?ã‰ê5¨—g‹¢öyu-¾$D¬‡:dee3Æ!Œ1£[„ I‚RÊËÊÊ&{÷~Ž„KJJˆú ±œóϪªìvñ4z«õz›<ž£[… I"++Ûåråäÿ?N½ð_íiÐIEND®B`‚Qt-Color-Widgets-v2.2.0/gallery/ColorPaletteWidget.png000066400000000000000000000161161366475014400226720ustar00rootroot00000000000000‰PNG  IHDRãºÓmm$ pHYsÄÄ•+IDATxœí›{xå½Çï;³³×ìfsƒ.\å" %R•‹ŠÔb= •ã…jú´JÅj¨¼biâZ©ž "‚‚  Âr²Ùd“l²»3ï{þ˜ÝÍd7 ÉS˜ö÷yöÙgwv~ß™ùì;ïÌìK¼5µ¥¥¥u¾:§ ƒœœâr9ûee]êùÇAöí'À‡~©×éÅÅÅ$+;;þ£‹iz´¿Ë*‡üýïŸwŽä’³cÇÃ⚘ÒÒR<~zÇ)..&@8Àe•#z<ιîäâñxâ'Öù|ãÆ]±O‡¶cÇpY刺ë‘Ë“˜¦GQ”O?ý”1¦ÇétŽ1Âb±´ÑœšššÃ‡·5óǵï–w÷Kéwºæômýn[˜»°­œêêê={ö´Õ2BF””ÔêúˆÚ •çL&“$ÙÉl¶¹\&‹Åž”$Y­¶ÔT“ÝnïÖMr8léé&§ÓÞ³§Éå2gd´õKBt‡.{ãë>þ¯Ã¿3ÃÙÊÊ_\ùôÓË:˜sèС¼¼<Æ9¥”RJ4¬ÿáíòöëÓ®_>pùÓ‡ž|ëÜ[„“¹ ZÍùꫯ¦M›ÖÎ7oÞ|Ë-·´ú‘ÉjÛÿ>úkÝÒÞ§ê>ùîûÓrs ±±‘RJdYö76–?þì³Ï^;ãá´+~$˜D`¼OzâòùCÃÉq9€µ±—_=üªœ(ï>ñ \~²â#ê_üîÅr´žÃ9œ¯ª û•xkí­ú©Ø2 †˜@€À`pX’¬)6;€¹e-ò£}U9ÔÕž‰¥€B©(¥¥¥cÆŒùão~ö“µý'ÌͶýû‹€‰“˜à\h$€B¢íj¥·Ò?˯ÎûîÄC`[c WÅç€ ”Ò:Ÿ¯¸¸8¼V`6›8 I’:mäÈ‘‰‰‰ÑœðÑ¿…ʪ©v)òœy685ÏvKl硣ȇþcnaý£ï=1ûÊ]Lt‡úª+‰#ADhX5AƒÁ $8Ý¿]öÀÌů»q^Ei1籇ÝhçœRª†D›CUÖî}º‹o’aûæò‘bé=ûÅ(¡ÍR*ˆï Lž<9úzË–-“&Mо¥À[>:½]¢^ûñã“óÇÝpÍøÇNš1sÑò·Š=J\~̲ÚþT>ñÅgßÕóð[vv÷¶çY{i1å»Ö>8õæ%­c-1Ø£Í=ÂÃ9ÐX[_§ýˆ"‚Y’À™˜Ø»_öžÿ|釯ÿ 4E«¢šißÕÎBäÅÏüŒ'Ðrà¾ãtÉ€%må¨SA(U[Ê*ÇëõÖÖÖÖÕÕÕ744øÃ€¢0m•Øœád"˜L`·$Ý’ ê³Ì8­`6ƒl³‚@AÔ®ˆƒzcí鬡ò›óìÏ_I{»p²»µãˆÚV“<øÁš-/^?Ø œÜ¶î½à㇦´{Рê¾ZûËUû»å¦Ò`;‹ø'EÝ¿ üM2¨ZsN ¡¥„L)(ضm› “(~°úß{ŒžÍãäæðHÿFÚÔèyÕ‚^ €Âª²UöÍv·=ã圧îK¿?&J“ÃÕA(!i_…艥$®J¥•£¿jªÃ’ 6Là´ƒE— ,&ÚÀ*˜Áj‹‚©œ‡Ÿ[÷«n›|åÛoýpVá.ñ»«Öl;ZQë—íY7ý䉟ŽM¥š*ßþ‡W×mûÞË™cg?¾è¦~´dÃÒ¶”yMßý¾”sïcþ~åOG+áñ»þÛœ~Ëó«fe{‹Þ|å÷›¿=/[ÒGÝñðâÛ$´0Ødí;mù½C=»{gLßæò¦¶Ö÷æ;ïù|>íD§Ó9÷žÙ.—³£)‘¦G kê‚ 6¥”rgÊÏ×øê8g)Ýz)LVBJH–«j|ç*Zù=G›0ÎU±(!4Ò¶B¤‡¹°×Â…½ÀÎ;GwÝ~DtWkÃͳ õ[©€°©íJ.¼Yâ^sàšÓû?ØòóÊõ8±w2eIÁÓ9nvfsáÂ×þ<>ÿ¡+›g~ó+_÷ë7Ÿ$þóÏ—,ÛÐ{ýÍ}nþ¡Û· ÿíËw¦(xäØm«Ý+Þ¸?O`g6ýrùŽœ'_ÿ`„Ëó÷ç~úËW3Ö=y£ù[çÉ€{Æ­áeŽÓåœsÏì·4²:Î9÷ÌvºœÿѦÇßÔè=wîìÙóågÏSBÊÎzþ§"”9è \½{&œ­‚ÏŠöýuÿ±›†÷i5‡Gº¹Ñ£¿ª”öâš¼øª‘RÛ—ˆIS £¯[9úo‡L Lp˜Áì§ÌIhk*$ÙÁÚ ’`óƒÓ XLŽGùкû¯ÿ=mI}_÷è ÷^måÀIúàéÀ…ŒC{­;êaÀ9„oû´:ÿÑÛ'€ÞS †¼þú®Ò ä‘̈ÑÑ·ìw|r,ïŽ_ O8¤ýÑ5¿fg‰œ?Ê·…Â…ÆiSÀåL˜s÷¬·ÞÝèóùœN眻g¹œ ú ÑýyõØ~ú“{>?ãå<¡É©YÉüØq¯RÔ¾» Þ0›ý;6¿9yÍ3­æpDíª¾Œy -Lm}5[6©-\Ôªß~šØÎ:¾]"¯@¸`Ík3{Pí§ÓÛß{ᅧNù¥²÷¤Ü¿Y?\®®òÖíyþÞ=°·Mô³Ø~¬¶W.WWU¾yuÞ¿S+äÙ$sˆ½ˆÀÃ=#C‰ àt:ï=ëã¿üeê”)N§³³ëíáÁ¶ûëÿ ƒêÎWŸrÕ ÍD @¨Ð^ÿR£©öÊ?0Æc ~Ñ$ÆwvcsÔ¥Et$MeY®ªª’$“Õjc@±ÅúˆÚ ÚËT³æ•zqÕ`Q/¨jjµREQJ7þjyÑè•Ï/¹Â%°Sïÿø¡Ò?3ÁåNLžòäúG‡hMã<È¡YTÐ&S—;Ñ–?÷ݧÆY[lÖúG±ßÎ8] wϺ4{·D¶.!ÄlÕ'("@ôJˆf §‚@€ÄnBÍ^"­§N*//·X­¾ùvÆ­ÓÚoT)!²,›L&ˆž¢išÒªªª=z€ßßðö† S§Ní§Æ5ªª©6 À¦±¶Õצ–W#â¶ÌWSgÎÈéç¤Àêÿ÷îJ*ðhߘƒ7i¢mÙ›ï{òŽ¡)&¥®âX•µ_7\ÒÙÒ|¼{pBœ Þ¥9/…’Þc'g.}çÝ9÷]ÝÃÂýgW¾Yiq×e[ýáü ýÆ•žÚ¿ì9È™ýˆðȳQ²ž);×–¨j!‰»-¦(Ê™3gòóó_[·næŒÛDÑÔþÑĈ‘ë×oå:t覛nÒñQ€†††Õ¯­Î}MRRòÿãÑ?*ªvW̸ïÚ•xàþ÷¬‰§Œ»Öu¸yœKç.~{íoÍ*k`¢#cø]KžÍtñÊÛæ xîåû§¾’3wå¯nÏž2wÌòµÞõz÷©¿zuÎíËž­]ÿow½à“©­[ÞôGŸé—ojsã_ŒðLŸîIC®¤È!±SÝÑ· €pÉlýê\ø¿#-OiÔ3ªÖïÞ‹ÅòkÖÜzËT«Õs:Ÿ“””t×]w©“>ûìShÙÙ¡¡¡aÍšßeöé;dÈhšš#†ƒ´j}Óáƒ?X€›£¿;ç”åN 6#ôœ°ä• Íïo¾€sÈûñ†w@ÕÉÔmÌ}ÏŒ¹¯å¶)kÚSoDîbpè>ñg¯LŒ¾K2û©ßÌÖÄ%IâÔ>˜·>ÿ´sY9Ò?‡Ìî Á“CŒ`d "@øŠ%‡. (ƒdEz“$&Gs‰ÒÐàßW\|çí·[­ÖÖ.ÇÆåhןRY–Õ{§R˜ÌÉÖ¿‘•3nÜ8B‰¦5‹ÜMh¹+¿‰Ü÷Þ5M°$iîø‡"3éŸO#ÐÎ_T"GÉk³,{÷oÆç@9S8±ð?Ôs$F€PªŒ¾êŠ§èšœ!W^¹ëË/ã¯@™L¦;fÌ0™L­7q9Z† úÎ;ïȲ¦gBȘük²³³Õ;·19]zôGþ´³Ù£;ôÚQC®5¤ÍùÚÈŒL’Ì#GŽêìš´+*$&º§OŸÑ‘@õm+çþ5ß>ÖÖ:µ†‚¢^Úº&àv'1Î%1ÿžî ”RƙۗUŽzîw*ˆ\þ´±Ë]%%%Œ?UC%%‰‰‰ü²ÊÝî$Æ!:•G. ”RÆÂ-V YÙ٥ǎí/*öz«u$»ÝI‰‰‰YÙYpY墢ý`@·òÈ%s~¨¤Äl¶ª*ü+@¼5µ¥ÇŽÕÖúô)\´-Ö¿Ä[S{©×A. ½ð,r€¦"ÆMEŒšŠ41â×_}©×A.Œ{&Oºà|1¬p8t,oi}ýêôt…‹**Öçåé(œäȦü|…3wïÞZP £°`ëÖÏçÍÓQ8aƽK—ê(µbEɪU: -^|bãF…}gÍ:·s§ŽÂ´±cëOžìlÕ—G¿Ç£?b ÐTÄ ©ˆ1@Sc€¦"ÆMEŒšŠ41h*b ÐTÄ ©ˆ1@Sc€¦"ÆMEŒšŠ41h*b ÐTÄ |²ío—zä|²ío"ÎëteáXñ]ã¨^«_½T×8ªë¡kÕ³G6­Ò5Žjñî­ët£zpëççé(œ0kÃÞ­ºÆQ¬(Ù©kÕØÅ'¾Õ5ŽjȬs'u£Ê[ï=ÙÙª/÷â8*Ä  ©ˆ1@Sc€¦"ÆMEŒšŠ41h*b ÐTÄ ©ˆ1@Sc€¦"ÆMEŒšŠ41h*b ÐTÄ ©ˆ1@Sƒ€#þËŸðˆ¿ñ…®Ü^+ôŒøÛº´þÎÕzFüýqQÅëõŒø{}þ‘Ç6éñ÷òÌÝ…[õŒø+,Øúòçót>6aƽzFü͵â£=#þ¦ Z¼ó„žcûÎ:tNψ¿icÏÕŸìlUñ.ñ‡41h*b ÐTÄ ©ˆ1@Sc€¦"ÆMEŒšŠ41h*b ÐTÄ ©ˆ1@Sc€¦"ÆMEŒšŠ41h*bpÄrùñ…™.-<éX1HÇ"ë—–¤¯­£°bÑž¼õ“t™ÿ·üMwè(Ü=óO[ÔQ¸µ`ݼϟÐQ¸a¯—î]©£pŨÇW•¬×Q¸xÐü'¶ê(œÕ·`ç¹ý: Ǧ]u²¾¬³UGv•àÑ1h*b ÐTÄ ©ˆ1@Sc€¦"ÆMEŒšŠ41h*b ÐTÄ ©ˆ1@Sc€¦"ÆMEŒšŠ41h*b ÐTÄ àˆ?äò':⯰ӥ……Ž+t,²~éÒôÕ«uV,Z”·^Ï ¶#óççoÚ¤£p÷Ì™[õŒ†ÛZP0ïóÏun˜0aéÞ½: WŒµª¤DGáâAƒ6ž8¡£pVß¾;ÏÓQ86-íd}}g«Žìú þˆ1@Sc€¦"ÆMEŒšŠ41h*b ÐTÄ ©ˆ1@Sc€¦"ÆMEŒšŠ41h*b ÐTÄ ©ˆ1@Sc€¦"Gü!—?‘™….=Yè¤kÄ_ÉÒôѺFüíY”7I׈¿¿ÍÏ¿C׈¿?Í,xP׈¿uóžÐ5âï×–®Ô5âïñQ«Öëñ7ÐÆ­ºFüôݹ_׈¿«ÒN–u~ÄßAñ‡41h*b ÐTÄ ©ˆ1@Sc€¦"ÆMEŒšŠ41h*b ÐTÄ ©ˆ1@Sc€¦"ÆMEŒšŠ41ÇQ!†€xkj/õ: È…Á£?b ÐTÄ ©ˆ1@Sc€¦"Æ@€ÒÒÒ:_ÇS¥£>99ÅåröËÊ€²²2£¿V×ÅW¢Ën³÷èÑ£ s‹¤«Äè’²¯h?>løp)*ÅÅňÙj¥ÀûçåéÎ9zô(ç„ï’œŒ ”õ¢(--í18@—äÐ:ŸoذaÀ¹îÇðaÃ|>_£¿!77—3¦û‘›“ã÷×wUŽî킨t•]•#z<Îytýššš*++ã×»áèÑâ§žêÛ­›óAè·lYÆèÑÑO=˜6Gòx<3] !$99Ùb±¨okk}íÏßAÔäbˆCwtÅõx]û)rñ´c؇'7¾~ä%›d^zåó#SÆéÎé8b8K3IVdY‘)8%('䋇NïÝ#ýî»N¼û;%ȳæ<”öÑGŸ-\8c×.ˆzÁ8×®“Âc¬­G}Rcœ·•S__ïp8z÷î_K"Ÿ/ˆ¢˜””d±XAt»“Ž+E1ÚïŒÉQ£…}òɶö7)c-¾Bû3#D»#dYþÁsB”D“Epš&J”z‚‰›üAÿQÏñÚÆF·”i³Æoÿ˜~jH–Ο7‡B‚(RΩ¢€,3€Úââêúz¤,LJ´ÒO%”ÍEP „ˆ¢Ø½{÷´´4ƘÉdª®öÆû ¶lê Y‘ !MMM~¿¿¬¼,333--íÌ™3gÏž É¡´´4Q“S’80tèPµ*z|ˆæ¨¯¦\p›jK.ꊢA+ÆÏ¯yféŽÇC4"˜D* Âè>ì’ôÕ©½“hŇh5ûoëùh¼1ýÔAO/ûæ±GMÁ`Ìqß `1™Ì+VƇ´ÖOmyµ2Jd©¼±©‰PÛIÕütYƒ¢(Š‚`µXv{¢Ë•’œœš’ ÷íÛ×è÷«M²Ãn'„´Ó¦rƘ¢ÀĉM&S¸GK0Æ6mÚÄ9w»Ýœ1lS»­ †-X0lAô£äß»(å‰ÈŠR4óLLU;9=onö¼¹\tÌ”Öú©ö4¾@cccee¥h2}óÝwÇ‹?‹^圱ÿØ£m; ²,—••eföyûý?Μ>£ÕåF¯7Ÿp=ç¼¼¬¬wŸÞjÏA TM"hvNvQQQnn $|)Ú7ä€Â”€¦@S0 ƒMš%2Æ™ÕfõÖ4ߣê‚+"´+˜ÂعúZN˜¬°ˆ¨á{TÚÓ€Ön*om|æô1‡×æyc.ðB Îx4P–eÉ$QJ÷îÝ—=j^vËI’MQMP0$‡ä@S º„P0¤ÈJ(b k%¹XÚºbÏû8Üg¼^oC(‘%·ÕÝjù?ý;EÍ¡À#= õ=å×þ³DVØ·%‡î˜>½µ?fEVG½àyg8àÀgêsS Éf·UTVäææ˜Í’v~m_9:ñæ›oàõ õõ õýóú¾bp]}]ôQë«•¹¼¢Üdãs‹$F íôŠ»-‚%×5ð‘+kû{Ìéà ¾Ÿš–šÚê5vAnw]ëÍUóÙææ;@jjÚÉ'#³D.ËBÉÍÉ¥”jgNZÉq'ºï½wN[›òêQW7—Gû©Mí"Ú>lÏüÜüÁÏ5ÏÖVù…r:ºñýT³ÙÒ«Wï¶çooºö–&J»uïÞÖÒã{7$òÇ«˜œÎBÚþÒ)ºB°.ËÝî$Æ¡¤èµ¥”qæv'ÙvÆ9!“ÃtUr1t•Ð%9¤¨h 8p ¾? sΕ”˜ÍVÉb45õèу’N} 㼬¼Üf±2à]’“Ñ3£“ÕH Ž—–v‰¼Krˆ·¦¶ôرÚZŸ×[­#ÈíNJLLÌÊ΀S§Îøýuõõ :r{‚éêÕU9ÈEÒUbtIÎÿï‚“¶ëxIEND®B`‚Qt-Color-Widgets-v2.2.0/gallery/ColorPaletteWidget_readonly.png000066400000000000000000000057171366475014400245740ustar00rootroot00000000000000‰PNG  IHDRãºÓmm$ pHYsÄÄ•+ IDATxœíÜTÕõÇñ÷÷rï÷þä{bT4 ‹µiygm™(š«<+Ú¦xäØNËÛ¬¬ëFÓfK³@KpÐjý¸%n52”©é)‹k3ÔDäzsC.ßÏþà×1å3¼O¯Çù:Æ}ßû5žÞïíÞz+Í'[êêêNùN55'€!fذáN§6bäHåo{ö*$&Nœ8اп}ûö)ÆS>ßäÉ7 !û|ú7a„;Þ3655!Sâššš ƒ}ÄHD}žS7™Lªjs8T³Ùætš,{D„jµÚ"#Mv»=:Zu8l11&M³_~¹Éé4ÇÆÒÉÃ7ˆ±ã/ÿËõ¯à’R¢îR‰‚rOd"r©D¡D"'‘™(œÈJ4ŒÈJ4œÈFd'2÷ž¸øê¾ú÷zÐQªHíúÚõÕL¤}µYú¾x¸PšßÏwû/½ÖxþÃ7žˆDïc zfEË›K¦¦Nþþõ7ý mʹ+6îkj?ëþû<Ö¹¿¨ï¯ùEç/õ£•å~©ݽõoܹvÁôÛ¿sJ¿ÐCô Î«¿Á/6ÂÈd"»T•ìvRU íøê ³Jš•Ìf ˜É¬Rˆ‘È@ÆîY!ˆŒI÷¿¸vVŒþÕ‘ý¯ýnÙ¯VE½äž®ô¸è õ\OÉg>~õ¹·bsóX;Q{Cùºâ3Kn?¼¿;ëK?þÁÚå{£¯Š4œùš‡>ú¹úw”ê°‘ªR¨Tiv²¨ä´‘ÅDgldU‰Ìd5‘ÅH!!d *UˆÎ¯!¶Ë&͘zõK?;Ú.œ§÷m*x®üPcËé€}ä­,ýYZ¤APÏC·}±ý…ÕëÊ?iޏ´9Kroa¨.Êê­ÃͦçnVGÏ[4a÷ª²CGhÉìwÍ1?|¢ sTóž «žÿó/–˜”™æÝ5&´WÁ&kü+æ%×,«¬èóÚ††–߆—‹}>_ðßÔ4mþÝsœNíìÛ_Ô«׸ ÑzòóŠßÚ¯]=þŠ¡Ø/Kž¶xõÆ×ß(];˼åÙW> ߸­fã+Ž{hÃ+ÞÍËÓ¬¸¨¦UMšÿxÎ$ËUÙϼü§b÷®½ã×?O ½ÝS²©lUæhå_eËW숾oý«¯¾öÌ ½lùêJ¯K¼¢%OMiSôþÎÇP84§–u÷Më‰RÓ´¬»çhNíìS¿Wÿí§’ÉA3™¤YÈAaV²FR„¬Ñ4ÌA¶Ó¤iä0‘…ÈäèuõÔ¬»çæç£-âÛco\øÔ¼ïZ %fì51D$Bb¯źCMº E ‚Ú–ÿåDêÂcC¢+§»’ׯßYwï˜DÑuŸ¢+·®_êÿرåÓ„™N"(*íö럤¢:šbêûgHtu*†§š57s㦟ϧiZÖÜL§z®VÇÕÿ"½Ÿ*ˆÈ˜xßsÏf|ËüÝÖn/.~cÏç>Ý`47¾Ó“Ÿ 8q¼ùÔ®'æí !""½MØn9­÷}Ûq’GàÄñ­ûWgÏúCÇD U\ûŸ€ ¾o""P‡4MÓæÍÉ|óí·§O›¦iÚ×ü¤ŒÔCðM‚ߦr™ƒÞ êxsÕBFdéxC5h68ªníu%­ØsÝÊ's†èŸoþéýuA·"Ä6lÚC… “ƒK⌠žP)øž Îð0[êüM¿œl¥^#}w=çsaÿÜ`hÎй™³¨óYåœ D½Ÿ¯„ O4ž(™(™hQÑ¢¢QDñDWÅEEt¿¡tt]m{Ýwò”9vôÍ@ú©ƒïVÖ·Ç,($aÊ-¶6øe«zÀwøàg't!ÈêTÖ}æBº0„j¡ÍõuMÒuåÊ´©q^~±ò‹ë$ÚOùäïGÛúþ.DÏÆ8˜ýêßjÏ÷ãîüÉ +_¸÷žâPkXâ´É78öÜ@jb–;掠ÏäfþJ7:b'Î^¼,.\1^=#kÌãOß3}Õèù+»kÔ´ùß[±vÁìõ—MluÖ]/m[[ø‹ÙOù[tÂ>2"ò¬ODÏk àN)+{å¶ÛnÕƒ~˜Ú¼ßª&“Ãn3«ªÓa³˜M¡v«YÔlv‹)ÚiwXÔ˜0›f1]awZLf„—AQÞygK×óPðÓÎþ®Ïý»?5 #²E}âßÖu…HE©p))=Ÿû_¤«?À%ÐX?ÿîòÀ¢ÜO;B…Kª#ÎŽwþ oãÀÐÕñœ¡ëº¢(º®öôe0t]PöìÙÛz¦511QQ.ä?Rø¿BÔTW›ÍV¥ùdKݧŸ¶´øš›O öYô6rÔH¥ùdË`Ÿ Àùáÿ¢P*ð€R” < TàÁ¸{÷îÁ>€ó3Ñ®©S:æ&ò8—ï÷¯‰‰‘Ìml,LHÌ©­-MM•̨¬ôº\ƒ.¯w[v¶Ä`zQQU~¾Ä`ŠÇS]P 1˜”—W_R"1Ÿ™y¬¢Bb0*-ÍßÐ0Щ÷}‚«?ð€R” < Tà¥(x@©ÀJP*ð€R” < Tà¥(x@©ÀJP*ð€R” < Tà¥(x@©ÀÄ–ò­ƒ} ç±¥|«‘ˆÜÙžt‘ç©ÍÏú×äKm¦ð4>*µ™bYmiÔfмJï:©Í ¼ÛJ²%Ó3‹ª¼R›)\žê ©Íiyõ¤6S$gkÚL—æonèÔûUØLL Tà¥(x@©ÀJP*ð€R” < Tà¥(x@©ÀJP*ð€R” < Tà¥(x@©ÀJP*ð€R ìP¡¯s‡ÊMîOnw“Ë#³CśFf‡Êsï-”Ù¡²>§vQ©Ì•§3*Ý^™*n—÷émÙƒ‹Ò‹Šªdv¨d§x^¯–Ù¡rGR^E½Ì•´øÌšc2;T£ÒŽù:µo'v¨(x@©ÀJP*ð€R” < Tà¥(x@©ÀJP*ð€R” < Tà¥(x@©ÀJP*ð€R” L`3 }›)È7àQwƒÃ“$ñþüê˜5×I 6æîJ(œ"1X›³5µt¦Ä`eF™Ë»@bÐëZ—½m©Ä`Qú“ùU+%=)K ª %ó’rJ꽃™ñ®Šc{%Ó¢&5øtªvg5®þÀJP*ð€R” < Tà¥(x@©ÀJP*ð€R” < Tà¥(x@©ÀJP*ð€R” < Tà¥(˜Àúºw¨¸<êv;<‰‡ôççǬY#1ؘ››P(³&¤6''µ´Tb°2#Ãå•Ù/âu¹²·m“,JOϯª’ô¤¤TWK æ%%•Ô×K fÆÇW;&1˜Õà÷tªvç¸ú(x@©ÀJP*ð€R” < Tà¥(x@©ÀJP*ð€R” < Tà¥(x@©ÀJP*ð€R” < T`;T`èëÚ¡çðhƒÛ‘$µC¥:?æ:©*»r¦HíPÙš“:Sj‡JY†kÔ•u®ì¥R;TžLÏ_)µCeIJA¡Ô•œ¤¯ÔW|Å^©*“¢|‡ÊÇØ¡L Tà¥(x@©ÀJP*ð€R” < Tà¥(x@©ÀJP*ð€R” < Tà¥(x@©ÀJP*ð `3°ð_l8Ý:jÌIEND®B`‚Qt-Color-Widgets-v2.2.0/gallery/ColorPreview.png000066400000000000000000000003631366475014400215460ustar00rootroot00000000000000‰PNG  IHDR€ U@çr pHYsÄÄ•+¥IDAThíÚA ƒ0@ÑD\õ2õŒ=RÛ{x’t_/7üøo)³|„ š_ïOgL)=ëNãßÒ|^ÊÔ|^ë·Ÿù-¯CsZ·1Ì0À 3l¤pUˆuót~v ¥f˜`€fXø{@Œ}ÿ|Þ7f˜`€f˜`áïQö}¿tÊ0À 3̰ìïé¬Ed5Ùð’.|IEND®B`‚Qt-Color-Widgets-v2.2.0/gallery/ColorWheel.png000066400000000000000000000544071366475014400212010ustar00rootroot00000000000000‰PNG  IHDRÓ?1 pHYsÄÄ•+ IDATxœì}yœUµÿ¹·ªzŸ=ëdÙ²„’’.€( ‹  >EPT„ê{.ˆ"QxÈò|Š¢(²ŠH%Àt2I€ȾïË$3“d–ÞªîýýQ]Õ·ªî­®îém†9Ÿ|:·«kjý~Ïùžsï­BíÇO@¿Î’¨»ïiG{;ðáj£¶nÔGmqÜ–€Å)$JQHh(‰ ‰$ð)Ôç¿Dü ø¡&Hêý´>D|´>@ë‚dH˜Ž “Q •ûû”Éå>€^l*$[¤mð†ƒÒÆv¼» ï9Ž÷v¡c@@r4€Ä4(€qŠâBÌš’}M½¤"dd˜Œ ‘ÑÕÚ”*25¤Çà+÷Åè­†ú#€wK¢ØNéÒÛ¤ ûñ†i+@Š kïpYÓãŸÈ „´ ÕdjD›Z­Í©ÒNÃ4XîKÕk¬ŸYì:ºEnÞ"5o—›÷Hë¨ù¡™»fa™€ >Ti3ªÕ3"Úéu¾B–ûV´õ€c)Hl’›×ʯ­•_;(mD®@̲y '&è˃ڔuI•º$¤ÎÇà/÷¥­8ë'@Ǝძä—Þ–_{_~CCÝyà>W¸‰˜ùg.Ç4QϪV—†Õʤ±Ü»R¬ŸÐн)?¿Ü÷Ì&i• €2aT¸÷œÜCµKP›_¼$”ú¤D‡”ûò—Ù>¼8Ú^Wžy]yö}9Ѐаb¢­ ~Z*%KfÁÙ¡€zf$uI õ)LëË}CÊc: kåè ¾ß½¡ü]…„÷,€¸H*H#+¦sÚ&w;¢±þóR…’ŸSÔ…¨Ü·¨¤ö!"@+jù‡ïÏÏû?€wJ@uKU~®è!»œÿ¼œ#PÈØ@ò:%y¦ƒÊ}»Jd l‘ÖÿÑÿà+Ê3)ÈàžšÈ Iôè=\MÔðr:6JX™ ûR—ú7amz¹o]Ñ­/÷S +ä×ÿà`µü–w„€R@( TʬŸ ÿTÜpÝc+; 縚džyR¬¸aÛØþUÕ”¿$”¿HêÙJâ&¤žÛ‡uQß$€ ê?|OÿÞ÷Ði#ªß=÷@t2€¬4ý“¹Ž½!ekØ,?&èfˆN|si ¢Û¶³E^®Ê˱6'oBÉO÷I´ô5 ¤öOåùÿ übÞtˆc Ø"úMñC@Z7'ãýOrUMîú›%³E$áWr Äo§©O ˜Þ[ÍcÔíF€,SþqqÕG¾ú꼓²ºv‹?¥€HæÝ³A Û Ü_½Wmˆ¢¬ÆmpÚ"ƒè+àRèz9²É/ôàä*Îúšä7?9ÿë¡¶ãm”»Þ ÌWâøÕhgDܰ­¬›;\º÷ƸÃ=§”€U;ØA çW} o–ƒ×(Å¿žÃÉT°õzìÂ;oîsá«6Imnž ”l Âóî6pÛ–Û(ÁuŒ=ñ–9EÛ×ð2û¬ý™£ÇÀÒ°ûõO—L\O† #Èèj:8B¤!L냴!DëdðKÔ'ƒSEh$(¥A‚¢¤ ‰$jO¢ÖjKâÖ$jM #1¼;Ž÷Æñ*¸*"¸³ !.ô³¸Êg‚D›0] ÂíªôU…wŒ•h½¦à}iÃ7‚ßÙ mBé²=E(ûU´;Ž~K‡€Ì+™cAU>HÃ#ÉäaÚÔÚÔF2ySKqŠå´8>ØwuáMÒ†˜´¡oÔe;BÑ¡:‡ÄyUŠ  ’=¢š i’ 0=%?HðŒ‚_bX/ €Úýþ‡ï ܯê‚{+¾-_A9Û)&qn 1ºœðHmòdmþDõŒS´9ƒÈ˜2^œÞÕ)½Ý!¯ì’šÒ&ÄåÈmTñ}‰)þèºÐzÍ‚~£-§ä;RÊ-•ßkVé؇~9ø­fy5æ!^äõs ¶×J€Fi“NS—ÌPÏš ¢Õå¾0ÓЉ.iu§üF§üZJÚ¬óY<6²^cÐo.$,úÓm‚$P<¢ÜÆÍ*šO+/~3øƒtÒ#î ¹AÀl˜¾_¤‚Â4kxŒ¢ŠxÊoE µ~&ü­uÒ&wô럈÷ôתiÍ5É/^‘øb=m(÷yWQt ü ßÃç¸÷Ü×Uü bA¿ÞÖ”Y±!rùgù °YÚuyè[ûñ¡Ìu~jY…(À@«iäºä×%¾¡Uå=åÊ5tù|!z2‹ûw€>›ø±PiD÷§4er™Ï¸¼X.¿smèÎÔe ?qÀ’ˆ„ý¼6ùÅë_©¦5e<Ù^cè8öÝ/á‡t Ó®ø•ƒèO÷ êîÁTCåLÀÊI€§•9ô4÷Nh¢dÀ ú1 ‹Sßûþ€þ‡$çh‘ä;%üjîâ‡xBº r÷àG’Õeë)+÷½tKð>šqí"ð?¬ýÈ„Å~<__–ì†Q“$ÝŠéæL°á››kÞÐo”†º‡ÜŸ¬½®,'X<äöŽÀCÜ{á€%p¢?Lƒ·$¾~Câ¹W÷®TS%ô€L~Žhô¢$˜xAzµØÐŸ&þ£ôçVjP ÷úÿò“À㮸wç@F¡ŒJ£_øXê¼Æÿs(ù°?÷¸°†à€Bn“È‹@¨×8Àäîè ü½ø [PIÏ«” @øÃ}þ¿zÀ½ˆö”€­ŠžBFÞûÏs>”½Z¥1‰¼ª¨ßÆdWö8À]¬ˆLôë_ãƒn7~¯”(i‡Ü½þ¿ÝçÆìiaÆ¥»·oš^z¡~Á1È_O|eyDz~ôÕ4¼4®¬JIß‚í.ĉ¯iÜ… ‡î º·”gTºðÿïw~kœºGßo¶9##Ì…ƒiÃÃÝ÷ž¥.(͉ô`íõ@줵KÂqónîŸ×޼;1ä+%:‘Òìæqß¿îüÞpêàÙ÷›mäðýé…‹Ôùov¼Ðþ‘Ή‡š4y!¿÷·èÁ]ßõµ<^š)žV¢·µráðÐ(ßI|õ¹®ß ê¯ñ—Ãü=¼ ˆ”A?ôýz;´ýë¾£+ÁY]½!o¸,|· )ÇY‚·‹aë(H¢uvÿt±:¯¨ßo^LJ¾‡¬çè§š^µÔµ¹¨_D´ —‡îí@q§p÷ÌûBÒw7<×õ›Aýc9+Ɉ4¸»á…dÕmúl‹¡ŸM*’'Ãë.É#Å;òb %?þå~ÜÜäÕ‘àréaY(ƒü@ìÎÛã7¢Òö•ô›7C‰ê;bõ•{„~Â4(àî}ᵟAZw‘º( @o>ºNÚk4—îypfaÿØu÷UÉã€û­P– _øEÁüÑïø*_zïz ¤\ÜãÿÇKÊ{¸çÊÌÂ:Zó\×}ç«gãhû­°– ]Ð=ä9Àuy¢Ÿ8¾RPŽü#°ýžbmá ðª¼þg—¬pw¢?«þɬÓHý³óWó´i?Ô~+’©Áù#þI¤Æ|Ð/ D`ËO•#¯üP L€]øØ ¡ßÓô–Ý#6Ã! 'Q¯týz"]Øãì·b›æ›Ü9ú5M™˜3úy(¡¡w®Ç]» {œ…$@ ¥® =zÂ^ö‘\#€[0G›òrç}ÃH?W¯4"ë»L ÎÉ ýbQ„'ÂÍW#-VÀƒ,$¾øëé°è"ôK<2dÚ稳_èúi]ÿüÝÞlTªë<åE5rNèF Rûúà;ß(àŒO+kŸô½Ã<^Ðïôý“žè¾3Hý…:¼~+—Qìûg-äˆ.ŸÎ¡Ì(xß®?ûö>]¨Ã+ÌPˆ}øøÂȽ'Q7€Ñ˜9|à"waúòL /wþ¸ŽFz~`ýV^;qâÄÊ•+›Þz+Dw]¸LêÞšý"€@æ+Uª;>º’„†÷ü 0cPò¥à_N¢6ŽToèá…0_]¦?Iý3]ßëGïµ¶ö¶•ÍÍÑhSSSÓÆ ˆ¦!@wÝõÓ®ÉÏEÖ-Á‰ƒÙ} wæ+Jœ Eoì\òw@=}ÿ@p¿ÿÍ•ònÄ’qÈN2dG­~¦ëÿ #ýÃz™km]±jeS4º¢yņ 0 JD)•°D9ï¼óˆoX×´g"ë>Š´v®_wqùίòáh`ýýñéßìá‘÷T­“.üFͨ6ðÊbÇg*ÏuÝ6O›ÐÃSê·ÒX˱£Ñæ•ÑUÍM+¢[·mM#>ó ”PýsìØ±«V¯ÑÿJ>Ñ^ûI¤Å<áÄ_äŽÿ[kèÑ»˜zR }=øœ `ä¯Yõˆ|¿ÊÿußÔþ ·Ã-G¢«›£«š›V7oÛ¶ èˆ K” cJ¨„±Ñ&ã%K—š[PkæwOû]xÝgª9§Š`#ƒzó«¿8ÿwòõˆú›?Ž0è·¬@·©£Ì'闱ϟ¯ÎìÉÁô[‘ìà‘ÃÑ5«šV7GW5ïØ³ Mã>ƒrêĽÁ‰²”!¤\Ð=åþÐû_JsãØ—K­ø?x01ã–¼Ï. ´·Yõ›¤˜c¬‹ÖòÄÇo_”÷9ô[Ámߡѷ×4­i޾½j÷Þ½€Ãß[ŽMùØõO0Ü´y‹ßo¯h¶ý$°õç¹JËW @¥@Çe+HMžOùÎ3 7_J¤ý:×åC6ߟ^¸XüÝø…ùF¿Ê(¥{î¾³&úÎꦷWí;p@_ŽE#B#®Â1=½Hÿ,Z´È‰~ˆ¿Cnm–[ÞÌYú[—£d<´üë¿h ¡ÏÍò$À¾÷£ò>fÔ¾ å­ò“^y­}´û ýãûËb”Ò]ö5½»&úîšè;«9 „‚tøPýþa„î³ëŸ%K– öºg>Vµ|!еäÉ£!hòmüCrʵy\„|$Ð ”8­ê‘VÔÅ?7ÎZ~•=Ýõ•³ÔþÄ·tF)ݾoOtÝ;Mﮉ®{ûpËÈàÞUÞ€!„¼ëXÙ¼jøpa•ܲ<ýhZ@–å48àäµk©/ç×׿îñ¯lMxžþqÈüõÖÄÒ~ô—À(¥[÷÷NÓº·£ëÞiikBŒ„%»ÊS!BÀ¸—Yõϸqã]Ðê ³ãn ¬ÿ9@®% Ku 4ÿ<¶øÇ¹^œœ °·?ì_ç ôà@æë"uìmñ rÝ{¿y4BÉæ=»¢ï¿ÛôÞ;+Þ_{¬½ Ò¸pàžðpo—7¦2˜ G>ØõϹKÎÍz¨ñ)·ËGVȇ›rèFâ5ük“˜þyR—[6œ3î ¾ÅþÁô Bÿ ~¬ûjÜ/ý j„’ »vDׯ~°vÅkÛNž`<=âù{O‰¬þ‰XÜëq Ó6XaðA߯øœ³ÏÉ~ÜwŸñ¿U/-DÝG½:~>RÁ×ÿ_×§žÌé¢å–ü[Þ{iøYã@8‡à% þÖõù³Õq9h¿qM#dýîíMë×Eׯ]¹ñ½ã'O@÷FÛ(br…{F²»Ëz@ÌÖxŸ–}…ÃáµëÞSO½Tò¡×#¯} 4’«ø±5:/Nãuæ~½¯J€þ eÔ8<=xI¾žXØþž˜ªiïïÞÝø^Ó†uÍß;ÙÝ•Á:ãé9Š%]Êtóô"ýƒx[sDƒô¯@(ÂhÑ¢EÑêÐsâSo ¼÷ß^Å“@ øú÷:F¿ Èë8ÿðwe×z©Ý¡jL¬{JÆ’ÚÛâñ¾Ó~Ó-¥©ïíÚÖ´éýè¦÷›7¯ïìî0|<@VÜç]ÈÏAÿX÷E9ç#¹ÝèøŒïúv<‹Oìò¬y8 éÐÊ–S“¼ö«z•@Ð3«žÚ‚[ƒòv8V# Ou]yn¿û÷fIU]»kktóûÑ-4oÙЈ;µSç¸h’RêhŠ®<8·¡*û^ ÿórË ð@ë:ZÃäŽ/E{)í5<«ìÜ‚;ôxK‚Óõ‰ÔÄ~ô»[BM½»kkÓ–¢[>XµmC<™`==ö¢sœš¤ôúgâÄI¹¢R#–¦F~BÙõw~‡@ÖZ6ù6<›œ~™—=z"€ äîÀ»<ÙÒ€t#Lý?Ÿïew6‹§RoïÚݶ¾iËkvmM$â èMË÷åÑ?ç䉲[ø3y÷¿Ú Kl]9ðú]É©ŸœÞžð”oçÜÉ |úwiào' #9wÔõU‹%«wonßдmý;;·&5ÕÖ9eƒ»É½ò€E Ÿ‹û,Ìu²²Ë¶/ŒñYgŸ•ß•!‘añ¹·›~Sîk“C¸e‡ïý§’3¯Ìº»ì9Xya³ÔæiÏÕ6‘44u\+ô!½Îº’ñU»·FwlŒnßðîÞí©” À‘òÎ6+µC@¬Å˜Û@N}îÖDûÒ8‰¬XÙ,IùÎW$jÕgJG7ç–l‚5<¥ã¦€²ô5eÿ–n–N8?Ô?§„îûáDg"Þ¼gKtǦ¦]›ÖíÝ¡MT²t¶=:r ˆe®•_ÿ,^¼8ô–cçÜùë'ô7Rä}}¡th£¼íßê„,]ÑÙ ðkÿ&Ð![œi\–šp¦:"ëŽúŒŒÇš÷nmÚµ)ºsó{‡vkªîéù%K¸·FÎ"`L>ØZJý³hqžúÇ4uøÂäÄË|žÊúæÂÀ¿êÌF€,èéøâÈËÙdèè(„©ônÇ5ƒh(ûI÷f;ï^¹wkt÷–¦=›?8¸›Pjxz7mÃÓ9n’#cÈY2ýC)]þÆ›õõõ=¼¤¸óHÕóP²+è;€Ùñ¨ÖèöTÙ,àÿfë°ׂ€nLÎè«èo‹u­Ø·5ºwktÏ–õGöS¢ 5‡ßdõ÷=LdEÆ1S0d-kU4Wý3}ú©=G?ÈàÄìÑûò¾Þö/ÿu÷U»ìÅ-(þŒr0âÝhPM_OÌòtº½ÄŽvw¬Ø¿=ºoktß¶-û /.(wǽ§âzŽÆu gf§9pMH*”áúgÑ¢B]íÄü›ý«Cñ5PÞBßÛ‹]ø#Z5H´ 7üÉ·×ø Ù’`~füå䩵½ÿñ†-ÝÑÛ›öo‹îÛº¥í°÷,Ölë0óÀ=ó™SV.‰¬ugû¿!‹/.Ô•§ÁºÄé_ ¼þóüÜ?PMõ­úSb‰pÖ¼0 @çV½ºw¹nÞí j©ï½ŽË«©ÏóùVî:=¸=z`GÓþ­ÛÚ[ ÕN³«y³m>5„Õâ^J–Î_óÐýŽ=æ&èsüs „ºººW^} ã‚UüPüdõ}ÓQ×qîŸ×&Æžüþ»¢z¨04É­;q\àã=“SzútÚ=°½éÐŽíG˜ÒͲøûô|(¾Ï¡¨Rýã=æè' àíÏÓúgÁ‚D?Ð@ubÞ—ÿþY>îà#;åmMê¾0à÷¾½ÖÑ àÚ¶gŠoHLÎáDËd{;Û£‡wFïŠܾ»£Í!o@GØò²ª,¸/‹§ÄGbnͨ«¦?ÝõÏÂÂ%¦%æßè_~?Òây¸½í{ëw¹  ¥^TŽÏ1ç:~gÛ²ðŠÔØ4ß Õ(Ð=íMGvEïŠÙµ¯CŸ+èR¤p€žFžTP,®þ“K!ßyìL6zÜX>¤ë?²,ÏŸFáoYx@jæg|Í¿ÈÙýëmß;/Ä>ÓF#œÚŸÏ*‡’ÂꧨA?髉)9dQÝÙÙmÙÕÔ²;zd×Áî“ÙÞxã€RâRcÞúÇ‹EÔ?ÂÎcû¾°q×1ÆÓ§O¯®.Êp¯ø¢›|+ÿ”äáþ$“¾5Ï&Îù¢sË"´0úÇ{ÐÛøüTã8Ræ7»P€í­MÇöDîn:ºûH·^J3Ô‹'Ü 9€„»O^©±ØX,†þñs0Æ„X° X¯ñ$ƒÆ§&_ |ðRúÖzç€ñUYýŒWƉr»Cÿ€Õñsó`0Òßñ¹žaAŒlé8mÝmÝ=º§%!œ+˜S›÷–¡ !êMT¤/ òŒÅèŸ<2dÕ?Ü}ƒgžYÄ÷Ø&Þ¨¼ÿRv |JÈ›£øøaR;ĶYž—[¨ú"gN 4šÏV…ý7BéæÎcMíû¢­{W´í;ï`=}ApO…½Bix0æ5jçCQôON…ü|cÕÑ?pà qã‹èøÔ‰çÚQ¸uOÎ(ý•*«ŸOœ÷%Ûf9xÖwLPÜ/èÚä˜Ë¨„·.”þÌ­Ï{…þQeΜ9…ºï"#5CRÓ.PÞ}À£ì±UÞy9±ô ì63X¹råÅ]¨ÔVÁÒ™ð±9pÁi0¤Î3ÒíO§†õð$S”¼×}´éäÁ¦ŽƒÍ'ui){ÉÒ´p ¿§£¹¤ªÖº}¼9ðŸ=XqúçÔSg„ÃáÞz/–œ÷iå½âÞ¦ˆäw_àÕW^€Ôñxê-xê-ÀfƒÎÍyg—@aŠÎSäsV”¬í>ÚÔy(ÚqpUבn5û£xsƳpÀ<Üg ônúG¼êŸbgàZEèŸ3¾ÿ‹kêŒó¨B‰îìÒŸ÷U~9¨I3#t2¨©©8bØÑ}é7#¡ðö6x{üèÏ0 .˜= Î? ªDL8_ ^'Â%¨öNìX´ëPS×áÕ]GâDtNyv𦉟žàÑ}æ¬X0qâ@þ„û2®{AröPÿ`ŒçŸ>ßã}ï¡Q%¨žz¾Òü,@–”×þ• x·¼©Y¾ØÜ e4è÷û~½­^Zÿ\ Ñ  ÏÚfMÂpúDøØ\øè˜5Öx¸mú@ïžraj ËÑÇ©¶&~,Ú}$Ú}xMìhBó:+Üû¼*çHLÈVxrÒÌ:¥șטSû:Òû¿øÄŸþ\ìiÊêÂ÷_î3Ë $.¹9ö¹š[³`Adó&©+ýåD¼ö.¼´ ^^[92´>-–΂ê`˜JÛOÎ8f¾Ç¨¶*q,;·¼;š¤$4{_Ó9Ù¼s D[ö§£AƒŠ)LîûêÑŒDöSßZîý²èè'„\xáE_¿ùfBŠdÉxÍ—Ç¢î.9tÌÖ IDATæ±Þº‚6jjǯW˜Ëà(R'T¯çl€RX·-VmU³"ÙS&ŸÖoÏùì¤I“ ‹ª«’­M‰–hüèÚd[Jcf…çŒ{OpÁ½È…{Ÿ ¹¦wp  1Çë‘8·æñÏs9T :þë‡?š?¿DH·ð/>«¬y‘ïìy ·5Nüa;­MK• ^TN\ÚÍÿ scm'à•·á¥Õ°l ´·”$E–ÎýÂ#¿X¡¶®K´©@{†uOð‚û¬Ž¼ðú‡Å"-õD/ŽÜe#¹êŒñÓÏ<”tä¯ïµß…~s3Gá¤M a Ðõý'Rg|Bÿ–Q,ÍR ` ½È„0Ô×ÁçÂã·Ã¡§aÕðŸ×¼I€À€êî_Þø«Äö·Smj:AÃþµ`mcÐ'^HÂOɶaŒF8ÝFú'8JÌŸK`Y™óç¼_Ó뀄øã~¨Rûâüšu_Fm߈çC•Ìë?sÖ¬£Ô™Kh€¨@ î#Ó¶ŒuäõÍæ¦2X%Ç2@9 °ó¦Á>«þ?=ôwß»tѹ?{O–±H- q‡rŽ~.\ìµ á„ža1}0(·Ceèšîõ_{áïËÆïWŸsçÎͽ02`¸6t"‹é¬ gÿIˆ!úž”à{ý¬dXéW>öØÿ^þÅ+êÏÅår»µÙo°ùk®02}¤q™²Ð& Q‡ ü˜ã•À^Ø%:ó”³Ð†ùœ7o^È-œ©3—dpïzÂ@ßXMÞ´éCiÌ[ü®K¥‘-zš ²s³ÔôèÿñRÕuç €rñêÝ}z×?YYanͤ„GýcÇb.q ï˜ãEÿx‰9Mêè6lxccOûþó3õÔ³Ò€v½I Ûj©”´ù]};i¼-%”‹¼¾i2`æióȦÉ5¯Ôž•¸¸Ï]¡:o­W÷é\'«lÈ‹(û¡–RÿØŽÄ»,4#Àœ¹Eÿ#2uÊ験îçqCÚ¸FßNš¤¤Õås%?8LÒBÕé:{Úæ(õÏ×.ðÊä!ÐCiõ%‘u…¬‰OXDÙõ;‹§<ÊBÖæÎ)C  ×hÃ'¥ï.xAÚ¾QߎA¬: n“@”`¾ÆµHød 3>$ î³;¼òê/ûÂÌ53‚!½ÄC(¯þqÙJ_KÀû|¾©ÓÜ»YlS§Ì· Þ£"HÛô./ÀºM"<ý“•2€|†Êôçù¾!¿­ž—†»i9â¾ÒôwQKrÀ"÷×bèö“MgΜåó•ó¹OÚÔ38ˆw—@ÆÊÒî­ ¦@'Àv)•pègâËçÃiZPtˆ—ø‡=P50B†*0$ddƒ§@_™úGt$úÖ0F:$FFËiÿ·„¤0•Ç·wÁ~60ê‘"…jò!«ÃƒÜ°hs¨E‰9Xü«Ë¾Ì³ÅÒ뇛Ȯ`öì2€ M}!¡þqJ › Úºô{±QÒ ³Xwº| Ö1™dïübpì…§‰ï^ddãCÁô‹Ð?ØõH¼ì‹=_óÏË¢Œýæ FŽ9hPé}À7„ÈèÉBýã"¼Ã À¬YAoýbJLÑ<©À¯…Æ};4Ñ»O²á#oý|,Zn-žõ‹{Yp$c¤iZG—ÖÑY÷’9¤¯jáê-ú§ìî_7mÌTpç‚öï}BÌLÍr3hH—¯ÔºGbûiª7Àw“b ý¦{G³C ã&{<©Ê˜ù¡Ï¶ÁÌÜlŸÂ9bìKæ QÕŽw·´G×Åö¤¬È‘‰£œ9+L€¢t@ q¨Ì…¶u$P#Á‹!€ûªf%(y)qУþñ4½•)­B:2äôzgpsŸK`­ËVÄ÷„ÑÀ%ó‡œ&’%D¨Öß÷×eÇßÛíë6×M_;}<²D}¿šƒ,d5R‰õÏÌY¡€ HN?)Èþ›õ«s|`/Þ $ãø ‚9Ñ€ úWŠ¢ašÑå“‹!€«gÄ78ÛCK!_”ªr=˜+^öé^èÐã€ãø‡ª¯Ž4rìßé±%—Ÿ×xáÙØ§è{QB±×]Ü0oºþë‘7ßÎÔC™#ÁK€r4jD›,,nýcdivy4j~zÈiÕHyêŸ3föä¦ÜÈÀÁ.J  nkÇ­àM™ô`HÒ`‡É€žª=ó)bÕývýãôI(#!„úDzæ¯iº˜¶èœìq@ÿôצçuï=Äêæ Q×ÞCú:þªHZ«dæ?‚¥hÑ&“3äªB¡Ð¸SNéáM/¬ÑÚ7/âƒ@µ¶â6NÑÓ&BÈ IƒÖ£ ›ágëŽB¼[+ôI’Cÿ`«:âá>{vˆ9®‰²sãCÞ{ëÝdë ÙúJ'¶îêØ}”p08x6¸ý#;ØuÐh®9¹¬{Ì¢N=õTlv+ÄhmƒÙÏ—@m¸Þ](„¶Ôgú{d$=_·h0ÈŒëä´¤˜ ù²@˜Ù—ÌÀšM‹Áćƒ6ìCƒÂc†€–HîxôiíD'ÂH2ÄX÷¡£ÛÿðwýLΙ&a„˜CÕóöÄÙ}ñâ@ž‰¬sûaÏW ¦ŸzjAîxÖ5ð=}VJ@mmø„³@Ê'G Õ÷,`-ˆ¤ê×cŸýÙâ0râÞ]TÈémZ¢­”RAhô§/„ s×þ÷øÐáe+:w8±aÇîçþõÞÝ%Ov€ ŽZ²g|Zï0À„]‰&8â›qkXLŸ>½Pw¼PFjëùʇK +1PÛq9AÁÐÀÞŒé,«Ëé³Yɯ_ü±Ö7º°*êÿ²"À¸JœyK`íÀ’}FˆóhË`!`úݤô¸ \=i̘«>¾ëOÿJSÝ»ŸyÕvv’O™zÃå¾ÚjÇ¡¦X ™w c DÆ’1îˆb„ »·\Æw¸woe4·ßé6zô˜ªª¢¼²'Fkë,Ãø+ñ£d'ˆUÿ%'.øóª‘ò÷úÅ!$IXâV<…KkÈòÙR½3‘µ”\„UG0´–äÐH aKΘz˵Á¡œÇ׌uÚm7ÖMÔ°ôIB['O:k¬Ö| XúG”ß[€§ü7å#Ö?@b 9… ž…" VO¬ûž«_|QÛ›I Èm¨¦Å¥±qÀ9d"®š¶g~¥¦ÃÓÏaK´ÉìËy$lD¢„6œ:¡vÊØ®íûÚ7íL´À²l¨­Ÿ<®jØ ý9e‚Œo…t° Éùéç‚ÁsYž~®NŸVqú¨¢dC‰ª>yôd¾ûÞK|Ezð!-vIÛ[Ð\Ÿk>6ƒåA–iÛ5? ûÀP¦Ö3ÆLuÈì+¦ð•õPÙºP)õÏ´iÓ*ý>…£yÜ•OF%q**ñÏWÐ$Øf#¥ðëÎÐï€5:Œ’¢[ÉÒù«‰ZgoZz0dª«Î>³óXTcu2AÿDb,b ëcæŠTÿaÁüœ6µœO@q1êógºàŠ'°Ýýçô¯ÈvŠùߺÓe«æVEY¤/v¿ÁæäÛ^ ‡m¸† %¶ûûLyÔÙ±e<#ˆq®fõÝ•6²ãtô8Гþ¯lCq-Ÿ¡ÉS&ë6ÀpÞÿ°bïñÍá_²X (cSäšjç¸èV“8±èÔ$ØqûÍ_%02£d‡`×ë¤;Œ£ÚI`–T€òÔ?‚À¿,úçØ±cC¡R¼2CÉDÞè§¾ ö;Çüxþ—*‰&œ©Ôý¢f¶U™d4‰mÈÈû:±hÈèäP8¦:Â̘S£›Ùöe@ÇíHd&æ`fXت«ê¦O”þáé®,úgÊԩź»=·d ÒSÿx|Ø~?ö{ ”(~Ðít_êOÕ‘¡“NbÔ«[€wkeîy½&²Í7SªG îÍÞjر/ç "ÙáÈ%ñl·€dã9Xz ]F(¢þ€©S*˜‰¤â"bÿü¬ÏY¯ÃJt[ìt{ÕTL†§L"îE·ÓÙÿ%Yt?¶± 3êÈVÀq)ªpËÈ3,e4UæHL•… ¥”ö ¦Åq 0ú§¶¶¶qXyžîÅPÊ"ÃÖŸÀbQbÕ‰T‰?ËÙkp)Úžþ Û„ ‹xç dxï!±§Ïè x¤Dô옶p$îÁÐ?ØšUÛ†¬ÙÜ<[ÞSš˜Ÿ.uO3ÈdõôBVdÕøúç”q½@ÿ¥xÓËÏN 2e<èת¢ ?eï\G…®ÚUIi€i!$ß]?;„$ùÚ=´3ÓuÖDeM¯2ìb«ub 'ç¶° ô›Æ«õDÿ€UMYãGÿȲæñG EÑÆ>ãõ<Ø){¸/à6é¡h°2V¡€ìûqý,°‰TÝܧì@*æõ*†îð'²ˆ×Å4 .ªf=T/úÇúç”SŠ{W dRóF°{}.œiFƒ"ƒY™˜ªhžO9Ñ ¹³¢½E=öÿ°~¦ì(±ƒ5Çu`9£«p°Õ¹²…[ÌÁŒþqî‹×Û`´u`8Vðª¬q€£`l/!€¼rƒØës%«ÒIŽAYsý΀ÀpcsŸ,÷¨8w(¾W?“ûF‘§=ÖJ²ê{n¦kƒšsÜ]µˆöÜÃe g®ú‡©ÿrp`ÀÀ555%¸)=4t¢KÚr@ìõ¹(ÃmJšäiÌ hÄóܼ½ÄäD…Õ]•«‚t*o«›nzhçôH^>`“ùâJ³WÉ2Ù…M÷;õ(÷9r—˜£ß?ã“îþ1º,ô0`áÀØ1c‹}/ bòªM@ÀÕës%Pz5mnz¢sš³ýD¡nnÞž[×y££¢Un#äð-µSm9 ǽ*j«iš˜¹y°m™¨Ö$ê‰ãLdáM°š0 J®ú1§Ær  €ù÷ ¬s½¾‹’Añi³Ó}Ò":ç AŸ¯ï€±JÕÔLžðMhdseÌ›Ìöû²½¶(Èvæ"V¸ääÊl¤ÎÎj’©°ƒ~¿¿’Äšü¯µ ÖÝ%½¤ÎœD~};ØÜâé¬ òzv-Ýø@Eöˆ9m’¯æ†ê €Ò ¥]6¸Ok4?¿Tï¬YÑï–ªŠ•X–œ\yÙC*6>˜Q¢dú' 2¤4¼'†âIyÙû¡,[ÏT{¸pwKRœfߦí{£œÑ„¸çf(‘Òà‰}•þ0‘!€Ë«ÇNðÕà4.2“ÈœÂÝé\EóT°µšäìõ”Lÿ 80 –ä÷È|O4OÁ»0A?™4Úgúsdß% )!îy²ÇÖ~|w¯TAº!€ÏÔŒ­Dp¦¤cN°‹p/ä§%µã™Ò6>è 47K.™þ9²¸ð=¾‚çì¹É'¤.9ݹM.”BYqo›Ƭ³»/oée¬!@WÖŽk”Ãf>|0ÙK7˜£Ž22˜ò( VÈ<^ÌÏl9 ®F”èâöÀä×·à=LjÁÝN]<ϹY†øè‚ÇÈP"¦„ƒlï­*H7 蚺ñCä 0YÜë?¢a&4Ù1rr_ãåÏsÒ?@`À€%½¾y™ÿ‘(ƒlñ.êß"‡Ô3'‘!µÎÍr— Jå${l|Xv@ÞÞÁßro1 èšÚ ¥€³þãÌœ“¬e‹šÒË£Nàr' ã`À¨®zÉ €ONþçðá#zÁ3зU–mbÐï.8rˆ«@H€!)»n›á!ðàæÞ@B蚺 µ’ÏY¸tæÜúMÿp‡I³ï„dÕØs ŒL* þ6¼L<ð&à¡ß)xmŸ’¼dwË|Ô+ôƒR¹¹ëÂ'wúŽÅ+ݯd5ákë&†±"î¬ðRÀñÒyÌqçÖ´!oýƒjl¬t £Ê_lÃ?]$§¼è4ZÏç'*×Hyrÿ6 ã)xtK¯  |]ýÄ–œrŸ<`”q,Èfõ/+°èž#”wÄ_Að9pÐ ¿ß_²‹™Ÿù[…âÄŠþÜ‚@òºE¢ °°^ ^¿Óý§SᾓÉ^À¤ÏÕOò!‰£I„y°­Œ#edc…SÄ»ÅÎS yÕ$7ýSùîÿdÂÿðjú½2vºPø¤G!0‚kF¦òsÿzãx =¸¡/)¬6ý¡IDAT éÚú‰2¼| ƒE–Þë?¶¬À¥Ÿ•¶˜&¨üÀþV ã Æç× â,_H¸jDRFnÉ®‹û׿yßw¼wŽŒpZËW×OÀâwcÍQL> ¬ÿèÑøˆáÞ-æ ̹Åú¡†B¡ººº¢_¸jùZãpíîAÀJYN^ɯÿèæF€Aú©FG¯0—÷¯7N&ЯÖõ‘ ¬\Y?Á‡9¸·`ÑYá±½R;=Ð?Üœñ¿nC‡-Õ•ËÓü¿jFI‡›wý“¼ì4:¨Êen€¯Oæª|lG>ðµt÷‘ Õ’ïòúqÈŽ~>Eý¾ì¯Ný#zxh®úGß‹Hü`Œ‡m,éµËÑð‘Nÿ#k|‹hÀýÕÐ?_;'Ë^Üž^«5Hå ÜôÓ“èÎh p—¥üV+ù/­yã ÒXä>ÈÍe C‘ô¨Zá3`w¾ºT¾½Ð ½P={‚6-K”ËB¸iB2èSÎOÛ¤4íïÅ£ƒœV/.ª Ž \æ'ΨÀ¼<˜;Ì¡'ú‡;xŽ«Ì¨¢Tî°Eù­ý¾¿m£ßé…ñ›Îʺ£ìøH£:¹ŠØE¿ú¶'¦ Tƒoý; ’B\˜Š±AJðcµ£ S÷Ì`Ñì÷• 3«Æöö;›:2cEÞúrÔ?C*Ùý«$ø­¯jwA¿ ´ÉCÔdÏMv €›¦&„I°úÎ…--øÁ·ûN6¬Û%|nÍH€ôˆ‹¸söŽ™Od>â ¬`ÈÊÍ€ý¬“¶`;|$n^ìRý4-;àòÑ©Sªˆú.ˆçqàž&ÿ^>BÎiÃ}‘³ª‡™Ews¤óñXÎ~³ÿˬ“B©ôO8®®®.í¥òjø@gàçkÄèw¯„¦i@Æ J^vª§ÝyYIÆðÝ aé“Ûpp +‰n¥Ò{Ýó°QþêU¬¬OC œKdqo}Õçµ­EÒ?ƒ.ñUònÁÛ¢¨› \¾ý|Ä¿{Èž°íÕ%_265±†x,}rÈ xq‹ò¯í}*Öml fnd0bÞ¿ÍBV Øü¼ 8¯í(–þ<¸BåÕ}Ê?ö˜a9Võ?ipòSS³ï ¼@Bpûì„°*¨ÿd8@4 |çå@BÍ÷òT°ÖÍ ‡«ÆNà#œêHÔ«PXý#ËrÀ¥½<Þ,¡¿Ó ”‹~ô¢$8݈ßqŽîM¼X¢üÂ1©iõZöÜ—KãëÎcøgËû €‰¡úi¡lqávWÍ©"a¼g9éŸúú†Ê| dàgïá] ¸%WÐcGCÀÚôÁ©OLð¾Ó€ü׉Ü~õ¦ÿõ¾(„`JxÀ„P½²îO3mȱþ#å¨ T𫑓ɝ ürå"ÐóÓ€ØÏõîþ!'ÀGF¨çR=%bh*|ù¯Á–޾3>‚µSÃÇk{2¬ÁÁËŸ{×?ã+Žøp,|ã (ú]Ò€RŒWÏÛ®s=Ö/Œ+ÈC@쎟ýÚr]ÿ§ ¡¹î¼wØÌÈ ‘jÑ{øxÂF”ÈšïÀs2!Oý …Âápi¯G6#4týJt4™ ýîi€ŠûÉÙ¹îl9Ù7“0§¦±A :ß´ç®Àú¢ÑÓ2ÎÞ’6¸¡c\Wo6` ‰‡o|4ÄC¿$&GÅ~°€Vç3Ö&ÀÕÓR G¨^?r åºáÿ‚´&`^mc­°>Pˆ£Ìîa‘þñþDÓœhhhÀ8Ï;^x#4týZÔ’ò€~n=4à uÑðäÕSò;ЇŒ­ÉûHz¿zzbú Mèø²ÇùI Üò»à²u}6!Æ^7<()Ü|À‹§÷¨Ü  ò tååc¡[6[‡<8k>Ü…öP :0ñÕé=9˜@‘à×Çe$½3ýå¡_ÿTUøüƒÁÕÛ¤žO%Fh^Ýp?–=ò  x @EÔäæ¡Ïo< »~E ËÝ¿^èqÔ§ÈzšÍªÝ~vB˜ï:˜±ºâÞÐæ“¥Ú$„æÕS°TýÃ} ¢ *¡þ#mî _±ŨUՈП%ˆß1K›ÑSQW´Ý¼(qÆH¯s¸¢_Ìöté]¡­}˜xnýpážëký’$•} ÞŸ _² ×\¿HðØ“uÁøÍ^Ç<»UÏ7!axøÓ±jõ¤‚²qà`+þÔ]¡öξÙ92³ë‡IJ£êêêÊ[EmjøS›ñ¡”{‘×wE™¯´Ú×ýÈ ’Â\”µä¿/qt‰:D Ÿ¶îÅŸþI(Ö'ž+Ê5K³ê‡aÄ} F.Ø%½ãáÞ|JÐ_׿Ó`!kåÆÖ˜äÑkcȽGÌ™ óЯÿÛºŸwshËž>Ë ¬Lª’Ó8МõO9is"²t·´5%ƽ x”@¨û±9dL'3XK§ª·}4á=å壟i<Š?zsxõú>ÛG’}ãjÒ*pýGQ”ÒÏ€‘›ãá öáƒZ6Üg<,%âß”ZZøÉ Eñ¬ßþXâc§ªÙ#€ ú­äi?>ykhÙŠ>;V"¢øÇÔ ÐoFaë?UUÕ%~ ¤ürwè’Cè8Ð4¸óà€©û”bmQ€\U ;õOÖ§_éŸáHÝ?~] ,ê–¢*ãòM»áÞ bwI^S¢¸Kßýîí¥ÙÓÜ šŒá­õrÎèw/¤RèîBO¿ $“púMî[ÝeAŸ_#š¦i@ABQŠÂB@)BˆŠ?øýEHT¹Kõ3 ]’]ÿf¾âµ)e²¡;ÝŽß9,ñõÒ½½¦D@·[/K|óÒDÎè7ã88 û ”ÀýùŸù÷ò¾ ê«jBþ€ýcû ¡Xz…æ§äÿÖôçxZ}?0BÈæïMã.Ìøþø­Cã·–ôÝM%%BpçU‰;¯JäŒ~Fús8`\õÝ{ñÕ_ }ñË¡ƒ‡Jz^ŶúêÚ€ß/墀$2¢໚ø>CÐ.ă;°d`8þkW!”ÞTü{Cãßk´P£øVj  ·~&q× ñ|Ðïà2ÿWRxy™|ö¹áÿyȯö¡7qÔW×ú|>/Oÿ4‡@lß*H¿D¾¹¿F™\} 1Ä Ï-EíÇO”~¯ðøËÊ-÷iÖÑ¢OÍ}ÌpÀü:a<ùñâóç÷´oO¥R@×ϡà ’à·°ô-Œ·PdÜÄܤ߉tC´·6¢Ý¿’¼¦èOþ –e¯pí©Go‹ÉYã8°ŽßöUolߊ¯úLè7µô‘:i]mO–³êI’zŽ~tÉ7(òE Þ‚!íòín<,t- ɸû±aåB?”1èöÆ»ò5ß vt¡,îß1«Fwÿ\ǯÅL|ˆéµ_H^ÿ•dM Í~L•n´½½]SU—ŽDzô v„¥HȨ‹.ŸÍhp}?a‚µ¶9¾ŸV£î? QÏ*çãºÊLؼ_þíÐþÃ8»øÑ,èçb]ÄL¡*B¯»!ùù/%#U½›”Òãímš¦‰8PßÐ åU:‰àŸôw€åÄ@0WQ‡{!È{j°6©Ì¯O/? ¥]ñÐÚMRvéO«Úq`ýêäFM5½ú‹É+¿¬oèÅ4 ”¶·µÂç@ã°áÎŽá,<†è£>x؇#)-Plºß vßÏ#—h³”Ø“ƒÈàò÷ÚT ;Žnø~ð¥7ä¬àŠïL!è‡O\–¼ö+ÉÑãH¹O=O£”¶·µBlè÷ùý ô¾² køè_|(˜yæÀÝ\“`Q@ Dûx öh UDbV)Bà¿õßý¨Ÿj©ô.âÇý+æ5$ ‹—¨Ÿ¾>9ÿì^Y)¢”¶µµR+"‘ªH•§9êëròY&K$ zÛ‹‘[`’!!„hòöHâ[Uå+¾Ø­‚ Û«Mò wOœ@èkôsAïžv4…‘£ÈEŸM]xU²aH/ÓE„ö¶VJ©ÉºÏ ‡Qü¾äº;A/NßÏ’Á‹"´Õ¨K+ë]Gص_óà†-ö”@$~¼—ƒœqQ£bGA‘aáyêy—§Î¯x?^$Ü¿dmHBazÆyêG.QO?¯w0­­µüþ@•õ!¸$ݯ(±gåø2º‘ èïbgƒ@–lXTU¯ô%ÿ;B+âåv«Pèöô?”oþgàäIÄ?^¢»û‰Úã ‚p˜žv¶6w©:w©:`XE§Ë𦵷µV×Ôø|~HÀ¯Ê]¯Êñåt!¸±7ô‹ƒ7æ!Z Éûê¥e®uºXEöÄ_úV°ùm‰ëò½H ®ûwê³a“²þÁè‰dö¹êŒ³Ô‰§káŠìPK×âküËåŽÉ©-Ó4ÐÙa ¢n¢-’èðЍöˆ¬Ò š¿zÄÿ³_ùµ”›ã÷XÃë  J¸ŽSÆ0b"™|†:i¾6n®6p4)ísw£Û;×H'›¥Î•rr âväæ?—Ä×5p{6 @‘LSw(©›e¨8Ío·^@ÝÞß ÝòÝÀ†RN9¼¾»ûÏ ›û”!:b21…Œ˜ª5N!G“ÚaáÆS bp÷nܵwnbq×&l“õÎØ%"³s} äV²!2¦ÉŒŠ©tºZ¯!¤Rð›ßúïý¥?™È-!æºgúëÔ?.`b9`C•"C}#©IŽ¢ÕCH¤†ëi¸†êi°Ž*À •ý ù¨ä IÐ’HKI!-‰v”jCñV”lCÉV”8Œ»÷ ø^œ8ˆõê Êì¸{z$¢· Î êí þ‡½çñe½‰ºíÜ¿s{ ¹YöØ'®îÄúÇ]ÙàâÄ¢{›](Zž÷]â˜óŸˆ‚€%& iê~L‹òüÂ"ZïˆS¬MžúS÷=?‹54PÜuc¦—XeͶW„mÓ°©}ýk‘ýCýò¨1qÿXÔº²¨Áþ•m9sÁÒ~Æz€R¿FÉ¿÷>ôCo$ W~:õÖòÎoH* ô``73¿b%lXw6°à«Ë hèm m îró'ؾ:®.k7Aâ]¢]ãð ½Äz%t«ª¢ÿïÎø+¯v.Y’ÉãîþÍu̶6„ çrsûN+,¸5W.èEnž8ì:.^ß%ÒdsJý‘e~ýd¬@·1cÈ£¿íþýŸº§LѲº‘J/£Ÿ]‡mØVs!C~ÆÕE\÷ïüÚñ#úš¾ŠÓIêÙ¤úç$=¥ûCr²^OÝ.RŸûgׯ‰Ÿ@²ºµ\ýƒÄ ó-Û´~å^Ó\/´‹×7MäþEZ¬âÇ\˜Uü˜d “ˆú‡Xê=GËád*Øúc8ÿc©ç_ë¼çÁØè1÷Þ„¸F[ÙpŸ·ãÏÉë»Sžmx?ãy,¦E;é…jBM/,ƒz1U…—žUþïAÿÎM€_ýdËÿ¢²`NGîƒÌ¸¿ºÿmN[f‹žlÁWTþÇx2‘nN ËRÐמ9ÐW  ¥°b¹üøÿøV¿!cëœ~€|1”µQ ˆ{ß»¸³çeûåUúZRúˆÚK+<^¬/À´-ë¥'ò½üŒ©Œû·0AŒ÷aYqNÈu5—FÖÓ±AŸÝ)–ÁwYÊÿµ$žÖG„¾‹}( [k úÇ_”÷íÛ‰Ù^‚Gnä§‹ åã]tšG$%Áë’¾+SxP¯/ïx´t£ÞÊ/ü^yã%•ꑊè94{1Ü"aÃ=˾|¸8¾.¥œÙ—Õ×>t0íDzýYåõgå÷¢2Ð,úXäY½è¢‚H Üùg‡ x¦¾D ^’Âõ—o³/Lk;ŒÞx^Yþ¬²±YùH®C-*”ó†{Ö4çkÕ—¤Â§¤Þö€‚[?2vì ^õOù×äuoHj7rwŸYEHQQî¾kd…»þOÑÈYZõR5|*7VôôÎRZ?8–JÀ¦UòÚ×䵯Éû7bgà %€;÷oM܇¦š%jõ5<_E•;5·lÖO€,vâ(ÚºZÚ¼RÞ¶JÚ³N"©Ü€˜+zŽ{YÈL­f¾V5_ÌÓ”v‘ãnýÈÁRqØñ®´s´£t`=>¼U‚Ta˜ÐÜK D&hÕÓHxŠV3W«š­áÞð(— ±~äojZvàë¥ññ=¸mnß‹»Ž¢B€»f` ­I£Hh©™Bª¦i¡q÷ž)ˆ•fý(°%»Qû^Ô¾w´ XеáX+е¡xJG$ $Bÿ¿Ý:¶†øŽíX)‘(aÿƒD>KPrSÜ;ÀQ𠢨F5H¥DÑvzÒ“qPsz²ì÷Œ‹[ü¥ùÒ0P ÐÆoâÉIEND®B`‚Qt-Color-Widgets-v2.2.0/gallery/GradientEditor.png000066400000000000000000000003461366475014400220330ustar00rootroot00000000000000‰PNG  IHDRTõ@¢ pHYsÄÄ•+˜IDATH‰cܱsÃH, înÎÇÙõÙˆ…‹þ°3807Bôný?õ/Û¶¿(ˆý/ºÕ0rAô¶øÏü‹Š~2 Ø¿˜1°üBñÎf„h¸_ýäúÑïV­ÙÜ;åË@i«‘íת…–-BåîlXq £×Ùlht*ÑZ¤Ý{y¼à–œr¯Œ%Sv.iý®ì;åU5¨p{ïãU‘1æÄ†lµÝ5Ï¥æøê°ó‹¸¼”¬;Z££dÌÒÉŽÝ@xt*.úHþ}/>}ÑŠ(_{kne$lÚwî¶ž·éå4wÉÜ1=Ÿü¸4ª0èÀ7S”µ137h÷o›ëÄ@mþÚxåڤŮíXf—C¯7ìÚ³Ï`04=Éq\dx˜\ε.Ï@ƒS!µ,ó µÀ?/¿œ~âªJãÕ_‚@¾3Wn9žvpýÛ†Ÿ’ßšFÀªÓéùƒ£“ÓÒ3v,ì_°-áL•€Æâ¼{#V¦¤¥I˜£ø-66³œ4ä~¿b§nÂÚÝ™©ÉÑ.—â¾Øy“ïí¥éu«èj- òsþìçX“—ÿ0–]a=}Þ`«T»jpr."<ŒãÇÇqáaœœk]êTˆNõ2(¦¥™u×çŸ0å­ÀY« †Å|»ÐÇQêàî;À–Eèîäãi§+×òMl éûVÈÄ~6¥v~c]áQéSD‰ƒÿŒÑöRDiÏÑ!“ì/gU Ï NåØL îhàDåîWqüä tÔh¬Š oÑPý»ËŒ`ò¼óe<_Ztõ/w¯a,¶¼mºtÈ9YĬPq\q1+TÎÉÚ.L×TfHs-X×ñ[ƒû<ùå³ùGy¹ZŠ€Õ·NìÛsòÊÃ`Èó²2a,6³5`”jÏFBAŠ‘)d ç*t¡ºBW§vW7tÍÚÙË ¥zAêã3üùÎË •¹×úD”&˯ð‡K‡ ·~ýîNÎÍžz$ãØô©A¢Gµu*ó£¥}‚¢Þm9ô@@4^Jþ<þ·%ë·mNÜ "Í„ÃúñEZ6‚(è*t‚xž¯(¯$œ\Fz¨”Ò§OD+C@cy™^¡Vìæî3äñ催œkFûª»{Œz77;¯°d ¯§Œ´9Iwõs²ðÐàv=ªájÓ5•ÙÑæš ¥ƒBæ*Ý›tJ‹F½®ÚÖap¿xmÑéüršײZ|åKO§ž~ø ¡öÑÙý§žzŒñìN¬¼§ø×ýºÿðÝê*®Ø›¯ ?HÄÖSãT’™ZÜwÌ;Bl½ý\n¤§_ë©ñ²'&_ç˜m}úgŽ4õœz­d~á.‹·ï¸0jqð‚³›ÖÍÿPfkm§ šè] …ëçK¨—¸þ ¡dúN ñ¸´>rË==¨Ü§­X>IÍ ôð^;?y㚨íF©ëäe«ç f‘Q{xÙ'îî6ydO…÷›ý7Æ—½ïé@ξÿIMý90(°éëÀâè&EnR¬^þ© oÊ’y,“:•ùAµ°p^ný0m”F¨– !/}BaNP-, ?¨¥³£Aµ°\DíD§B:;šT Ë:•Bµ°\êå« ý'ËÚ¬@$üe²ðàEÇ*ÿûZ!flÕyýv¼àÚÚSHG•¥"Ž#V©T¡€ aî¥P:Ã0( R©"/Ô¾¨uuuÿ†B¡t D¼^\leeC*uú’Û·õzCee…©³¢P,¥R¥P(œ]œÿˆð,£ßòK·IEND®B`‚Qt-Color-Widgets-v2.2.0/gallery/GradientListModel_view.png000066400000000000000000000102101366475014400235220ustar00rootroot00000000000000‰PNG  IHDRÀzF‚ pHYsÄÄ•+:IDATxœíÝy\TåÛÇñ뜙dd@D1÷Hr#7 5MC1÷ÔJ3´TÜ3Ë-qÅ%s)­ÔrE4Ò\Ò\À\R”•}dfÎùýšÈŒ^=O*ä÷ýâ¥,737Ì|æÌápn„è}1O¢$¢ŽÚ?ïiTj~ŽU>ü¶øé,IIOñEPH¤|:/ ‰”$‰¢Žžâ‹$‰¤{z/ÒÔ)Ïë®O$>ï T H€©° ¤À‚TXÊIɱ¹o…®¾¤7:@Îß3)`ôÖÛÒ3œÔ…òÉCà9’óv„õžõ›–QijU㥖݇ìc¯0<Ú´QQï˜9ãñïiÀwµòS6{ïÛGcÝ5½}ɶi £³e##ÛF~­]Í…Ç_ž@O† •ªBPY:zwlªKIN—ˆ¤ôÃ+>Ò=(¨C·ÐqkÎäÊD¤=2ûõ~Q z’ó÷Lê2í»óÇõêþêk}‡ÌÙ{­ôþ%I·öÍ}·Wº‡~u"£ìɘ\tyǼ‘}ƒÛu ´ìðm-I7¾ýê‡{²e"’³vNôóº:Q""ºûÛÌ ‘Œ?Ñû/B*U†T’¿5úœg+‘¨vñ}sêòwîØ¹ Cþ·+¼þèþGþ/?o8~ÃO»öoí|jɲƒùe#ÝùcɯLݼcÇÞÕCÔ"fïÎHÎ?¶67ð³Mb¶o_?nΔµ—ôN-=/Å+!’óIªS÷αßR%"Ý•¸³JŸFžþG!•ÊOway¨_@ÇÖûN>ÝtÚ—cZU#"2qnáëj­$ÁÜ­•‡}NzÖ£©(juéìl.’Ê¡u@º•šU–ŠÂ¹Ý~5LˆLýC:;ÄŽ+”KNÅ­öÚ€àz")«·x+´MÖžè?åz^žfçO%èä‚S¿þÙ OH‹Œã¿§IRJÜE/{5U=ëoÄó…ÝúÊOÙdÔÚÕýoo ô“^­QÉE—÷nX·7>õŽ ŠÓÒ¥ztF°µ³½·S"(¢$Ie#kµZx0DMù¹ú¢ì­¦…æþ>ŒÊÁ^—’+©¼}𝉻Q}ô\=ï°66§—î:ž œNmؼÚ3øÒ+lUª Ñ)hDOyû—ÛS$¢Ò¸UaK›¿nÍò¯V|Ø©º¡ÛQ î¾Ë9Ù9÷²’²3rÈFm¥°´«®Ê¸q¿6mzz®­ÆV$ÓÞoÆŸŠ=z®®¿¯…GÛ&‰Ç?yµž§õ‹ö³¤Ru¨ÜŒh“²~žLI—›SdU·‘³…Húì3±¿¥ÿƒ=l}JìæØ›%2•Þ<¸1:ÃÓÏÓR0mÕ­.fãöÄ"‰tÙg¿]Ì.°SC% Vž-Ý®ìÞr®–ÿ+Q°òn]ÿÂÖÎ9´låðÂÝs^¸/¸*¬[RÿìòÕ'õ¾!£žý$tè ácçœiعU5öc¼àôúÓ³ûuïþÚð¯ó§NîªI°ô½`”ClxH§ÀàÏ/5Ÿ8kh#‰öž^ö7’Õ­ÛÖ‰µ·¯KÊu¥§× xìFˆÞóà,HœÚ…S»À ?Ǿxÿ'H€©° ¤À‚TXÊýb‹4y*‰O) §~:‘L¤'‘‚Èôé]ËÓºœmUÉa«ÀRn«¢T*…‡QÙ+eïEñኢXZZZq° æææ ‚PXXXq° ¶¶¶ ‚]q09::>2˜ˆDQ¼uë–ÁùÔ©SÇà|’““ ÎÇÍÍÍà|®\¹bp>Mš4©8X„ .T,‚‡‡GÅÁ‚ 6ìYÞöð`«À‚TX R`A*,H€©TQÖ1úGŸ²&ñÅZ’èßSPÞƒŸúëõúÿ>|ˆÀÌÌÌàñ„ââb2t<ÁÚÚÚàñ„œœœŠƒAÐh4‹¢˜––Vq0ÕªUËà|RRR ÎÇÕÕÕà|®^½jp>îîîçsñâÅŠƒAhÖ¬™Áã9ñññ Ï„—óv„õŽ8¡AT˜©êûvü^ÿÏ¥ÿÿ’Ò~‹Iu ô´g\ø}S:ÍÊú躃×rÉÎ#xÌäa>ö"ÑÝËß¶ô‡³©9E¥¦ÎmG†ïR6œœ:R±eѶx“žQë‡7Ì9¹vÁŠmñéz3'ï7ÇNèÛØÚðµ7Èßÿù‡Qñé¥W{ÿnjÙîã¯ßó¨¸mD*U‡T’q6ú—[ ¼4"=´Ç!X:ytÿ¨ÇÔ¶rʶðÁ‘ßwh=æeáÚÆðˆX÷°eÛÛ:Ê™·Š¬Ìï— ÏEMœ—Ð~ÆÂÞ®~ëSQ¯ç§ã‚"«/X?¼‘‚ˆîþ±"|ÞåŽó6|Ö̺øòÖˆ>Zf÷Õ>OZîBŸ¸iÑ/>\º§¡ÊLI:ß7§¾ååjUzyý»cVþØqùÛ.D¤ýýû> "w6´È?½ì‰Ëvú-êW#}÷’uy]VíìUSY’™x“œDºCTxhÇÙ ¶Lp”oì›96bv͵ ‚ìE•}“.ï|ÔÐA•}`Ö¨¹ëNtœÞÖ„Hs÷‚Æ/Øò…½©©pã»éLùz‡·:óÀÌÑ3Õ^;µ©ákœžxñüw·~ìmì d•Ý`¾@î­.ùŠçî~Ö |¯§Ë#·šX³¹·»­J “Zޞι™2II¿Æ$70ÜßÙBabYåƽ5¿]Òæðˆc-&}ÚèqË€ëþŒù¹Ào@ßfj‰–î=C;‹¿ì:}÷É“•µõz¾âQâš™‰`t L›¶oôih%’¨~¹­—:-å¶D¢Ugó«¿ì:x)Go¦©_OSö(®pnß÷Õš¦‚`æÜéí®vq‡ÏÊDbõÆÞÌDRh||Ü´YYeK˜é5Ç i[Ǫš™ %ÜШߠVöJR9·‘º 3ví ØªT~e«K:‰²6/éȲiãß-^¼j@í¿?^r=vã†í'’ód…B›õ—¾és³r-­Aó§ëõ%.^Vf߯ÎWIJJ28cç«$$$œ±óUΟ?_q°`ü|#·¢îÂòP¿DDJëÚ/·ûbXSiïTåÑwDÀ§Q¡¡lÌÔM{´óW_$"RÖ4û£» £†tŸž/Y¾Ô;QColorDialog but with a much nicer and friendlier user interface. It uses several of the other widgets. ColorLineEdit ------------- ![ColorLineEdit](ColorLineEdit.png) ![ColorLineEdit with color preview](ColorLineEdit_with_color.png) This is a QLineEdit intended to be used to edit and display color names. It accepts several string formats: * #f00 (3 hexadecimal rgb digits) * #ff0000 (6 hexadecimal rgb digits) * rgb(255,0,0) (function-like) * red (color name) It can optionally display the color it represents on its background. ColorListWidget --------------- ![ColorListWidget](ColorListWidget.png) It allows to display and edit a list of colors. ColorPaletteWidget and Swatch ----------------------------- These widgets handle color palettes. ![Swatch](Swatch.png) **Swatch** only handles a single palette, can be used to just select colors from the palette or to modify the palette via drag and drop operations. **ColorPaletteModel** is a list model that represents palettes with can be used with the Qt item view widgets, it provides a name and a preview icon for each of the stored palettes. It also has functionality to load and save palettes from the filesystem. ![Read-only ColorPaletteWidget](ColorPaletteWidget_readonly.png) ![ColorPaletteWidget](ColorPaletteWidget.png) **ColorPaletteWidget** manages a list of palettes (via **ColorPaletteModel**). Has two modes: read-only only allows to select palettes and colors, otherwise it can be used to modify the list of palettes and the palette itself. ColorPreview and ColorSelector ------------------------------ ![ColorPreview](ColorPreview.png) **ColorPreview** is a widget that displays a color or compares two colors. **ColorSelector** is like **ColorPreview** but when clicked it shows a ColorDialog. GradientSlider and HueSlider ---------------------------- ![HueSlider](HueSlider.png) **GradientSlider** is a QSlider which uses a gradient as its background. **HueSlider** is specifically made to select a hue and has more information about the represented color. GradientEditor -------------- ![GradientEditor](GradientEditor.png) **GradientEditor** is similar in appearance to **GradientSlider** but it's for editing the gradient. GradientListModel and GradientDelegate -------------------------------------- ![GradientListModel](GradientListModel_combo.png) ![GradientListModel](GradientListModel_view.png) **GradientListModel** is a QAbstractListModel used to list gradients (useful for combo boxes, item views and the like). **GradientDelegate** is an item delegate to edit gradients in an item view. Qt-Color-Widgets-v2.2.0/gallery/Swatch.png000066400000000000000000000016671366475014400203670ustar00rootroot00000000000000‰PNG  IHDRÀ`Ä¢ê¾ pHYsÄÄ•+iIDATxœíÝ¡‹yÆñi©ŒÄm\¸ˆ…Ј@cöĈªÍ7²¢Q t¨»9W¦U9±.U'Ú5)d÷²zPè”´&cJ æÌügöΜyß<öûÑï/ê cȽwï¯àX‚ ¸ýéÔþ ‚´R±ßÇe9©Õì÷Ãý~ÚhØïÛí¢Ý¶ß÷Öë, í÷a–-£È~ßÍ6ql¿o¥i>ÛÑn>·ß×ûýÃje¿¯v:eQ¯¿~»oÿiàÿ‚„€ ! H‚„€ ! H‚„€ ! Hö@8Ú»÷W‚ H"Ç›d¤Ï<{ ßÊIìÙ¥û鯞=Ð/ÛÅØ³­³KÏè<[Î#û}·?Ûdž=P˜æ+Ϩ3Ú}òì~ì Ïè¤Sþ]¯7ì ! H‚„€ ! H‚„€ ! H‚„€ ! hØáhw{ Ç‰ã͇$SÇ(‹ËŸ'Ž=ÐïÃýÓ©côf°}¾pì.zë$sì’0»XFöûçÝÙlãØE­ôܱzÒ­vŽ=P§Þÿrpì~¨vea<þë†=4 AB@$ AB@$ AB@$ { ín$'ŽGIQI›öó2Îk“Göûýð¶1uüÙvpÕ^œÙï×½·avn¿ÏÂËhùÒ~?뾊7¯í÷iëÅ8ŸÚïGÍÁ|—Ùïûõpuøh¿ïTåwãñö&ç AB@$ AB@$ AB@$ AÃGûo”8%I%Míçe×&ûý~8lLû˜í`Ð^,ì÷ë^/Ì{š, £åÒ~?ëvãÍÆ~Ÿ¶Zã<·ßšÍùng¿ï×ë«ÃÁ~ß©V‹²4ooþä AB@$ AB@$ AB@$ AÃGûwt’8I¥éÙåqí‘gt;lœzö@Wƒö™gô¶ž{ö@—aôÒ³zÕ_{ö@/Zã©g4hÎ3Ï(¬¯>zö@«Åwóè3{ h‚„€ ! H‚„€ ! H‚„€ ! Hî1ç€â‰ùœgz IEND®B`‚Qt-Color-Widgets-v2.2.0/gallery/screenshot.cpp000066400000000000000000000166631366475014400213130ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include #include #include #include #include #include #include #include "QtColorWidgets/color_2d_slider.hpp" #include "QtColorWidgets/color_delegate.hpp" /// \todo show it #include "QtColorWidgets/color_dialog.hpp" #include "QtColorWidgets/color_line_edit.hpp" #include "QtColorWidgets/color_list_widget.hpp" #include "QtColorWidgets/color_palette_widget.hpp" #include "QtColorWidgets/color_preview.hpp" #include "QtColorWidgets/color_wheel.hpp" #include "QtColorWidgets/harmony_color_wheel.hpp" #include "QtColorWidgets/hue_slider.hpp" #include "QtColorWidgets/gradient_editor.hpp" #include "QtColorWidgets/gradient_list_model.hpp" #include "QtColorWidgets/gradient_delegate.hpp" bool run = false; QStringList just_these; void screenshot(QWidget& widget, QString name = QString()) { if ( name.isEmpty() ) { name = widget.metaObject()->className(); name.remove("color_widgets::"); } if ( !just_these.isEmpty() && !just_these.contains(name) ) return; widget.setWindowTitle(name); QPixmap pic(widget.size()); widget.render(&pic); name += ".png"; pic.save(name); if ( run ) widget.show(); } int main(int argc, char *argv[]) { QApplication a(argc, argv); QCommandLineParser parser; parser.addHelpOption(); parser.addPositionalArgument("just_these", "Only these widgets"); QCommandLineOption run_option("run", "Show widgets instead of saving to file"); parser.addOption(run_option); parser.process(a); run = parser.isSet(run_option); just_these = parser.positionalArguments(); QColor demo_color(64,172,143,128); color_widgets::ColorPalette palette1; color_widgets::ColorPalette palette2; int palette_columns = 12; palette1.setName("Palette 1"); palette2.setName("Palette 2"); palette1.setColumns(palette_columns); palette2.setColumns(palette_columns); for ( int i = 0; i < 6; i++ ) { for ( int j = 0; j < palette_columns; j++ ) { float f = float(j)/palette_columns; palette1.appendColor(QColor::fromHsvF(i/8.0,1-f,0.5+f/2)); palette2.appendColor(QColor::fromHsvF(i/8.0,1-f,1-f)); } } color_widgets::ColorPaletteModel palette_model; palette_model.addPalette(palette1, false); palette_model.addPalette(palette2, false); color_widgets::ColorPreview preview; preview.setColor(demo_color); preview.setDisplayMode(color_widgets::ColorPreview::SplitAlpha); preview.resize(128,32); screenshot(preview); color_widgets::ColorDialog dialog; dialog.setColorSpace(color_widgets::ColorWheel::ColorLCH); dialog.setColor(demo_color); screenshot(dialog); color_widgets::Color2DSlider slider2d; slider2d.setColor(demo_color); slider2d.resize(128,192); screenshot(slider2d); color_widgets::ColorLineEdit line_edit; line_edit.setColor(demo_color); line_edit.resize(line_edit.sizeHint()); screenshot(line_edit); line_edit.setPreviewColor(true); screenshot(line_edit, "ColorLineEdit_with_color"); color_widgets::ColorWheel wheel; wheel.resize(256, 256); wheel.setColor(demo_color); screenshot(wheel); color_widgets::HarmonyColorWheel harwheel; harwheel.resize(256, 256); harwheel.setColor(demo_color); harwheel.addHarmony(.333, true); harwheel.addHarmony(.667, true); screenshot(harwheel); color_widgets::Swatch swatch; swatch.setPalette(palette1); swatch.resize(swatch.sizeHint()); screenshot(swatch); color_widgets::ColorPaletteWidget palette_widget; palette_widget.setModel(&palette_model); screenshot(palette_widget); palette_widget.setReadOnly(true); screenshot(palette_widget, "ColorPaletteWidget_readonly"); color_widgets::HueSlider hue_slider; hue_slider.setColor(demo_color); hue_slider.resize(192, hue_slider.sizeHint().height()); // hue_slider.setInvertedAppearance(true); // hue_slider.setOrientation(Qt::Vertical); screenshot(hue_slider); color_widgets::ColorListWidget list_widget; list_widget.setColors({ demo_color, palette1.colorAt(palette_columns*0), palette1.colorAt(palette_columns*1), palette1.colorAt(palette_columns*3), palette1.colorAt(palette_columns*5), }); list_widget.resize(list_widget.sizeHint()); screenshot(list_widget); color_widgets::GradientEditor editor; QGradientStops gradient_colors; float n_colors = 4; for ( int i = 0; i <= n_colors; ++i ) gradient_colors.append(QGradientStop(i/n_colors, QColor::fromHsvF(i/n_colors, 0.5, 1))); editor.setStops(gradient_colors); screenshot(editor); QComboBox gradient_list; color_widgets::GradientListModel gradient_model; gradient_model.setGradient("Rainbow", gradient_colors); gradient_model.setGradient("Black to Transparent", QGradientStops{{0, Qt::black}, {1, QColor(0, 0, 0, 0)}}); gradient_list.setModel(&gradient_model); gradient_model.setIconSize(QSize(128, 24)); gradient_list.setIconSize(gradient_model.iconSize()); QObject::connect(&editor, &color_widgets::GradientEditor::stopsChanged, &gradient_model, [&gradient_model](const QGradientStops& stops){ gradient_model.setGradient("Rainbow", stops); }); gradient_list.resize(gradient_list.sizeHint()); screenshot(gradient_list, "GradientListModel_combo"); QListView gradient_view; color_widgets::GradientDelegate gradient_delegate; gradient_view.setItemDelegate(&gradient_delegate); gradient_view.setModel(&gradient_model); // gradient_model.setEditMode(color_widgets::GradientListModel::EditName); gradient_model.setEditMode(color_widgets::GradientListModel::EditGradient); gradient_view.resize(QSize(gradient_view.sizeHintForColumn(0) + 4, gradient_view.sizeHint().height())); screenshot(gradient_view, "GradientListModel_view"); QTableWidget gradient_table; gradient_table.setItemDelegate(&gradient_delegate); gradient_table.setRowCount(2); gradient_table.setColumnCount(2); gradient_table.setItem(0, 0, new QTableWidgetItem()); gradient_table.item(0, 0)->setData(Qt::EditRole, QVariant::fromValue(gradient_model.gradientBrush(0))); gradient_table.setItem(0, 1, new QTableWidgetItem(gradient_model.nameFromIndex(0))); gradient_table.setItem(1, 0, new QTableWidgetItem()); gradient_table.item(1, 0)->setData(Qt::EditRole, QVariant::fromValue(gradient_model.gradientBrush(1))); gradient_table.setItem(1, 1, new QTableWidgetItem(gradient_model.nameFromIndex(1))); screenshot(gradient_table, "GradientDelegate_table"); if ( run ) return a.exec(); return 0; } Qt-Color-Widgets-v2.2.0/include/000077500000000000000000000000001366475014400164025ustar00rootroot00000000000000Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/000077500000000000000000000000001366475014400213145ustar00rootroot00000000000000Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/AbstractWidgetList000066400000000000000000000000441366475014400250000ustar00rootroot00000000000000#include "abstract_widget_list.hpp" Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/BoundColorSelector000066400000000000000000000000441366475014400250040ustar00rootroot00000000000000#include "bound_color_selector.hpp" Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/CMakeLists.txt000066400000000000000000000013661366475014400240620ustar00rootroot00000000000000set (HEADERS abstract_widget_list.hpp bound_color_selector.hpp color_2d_slider.hpp color_delegate.hpp color_dialog.hpp color_line_edit.hpp color_list_widget.hpp color_names.hpp color_palette.hpp color_palette_model.hpp color_palette_widget.hpp color_preview.hpp color_selector.hpp color_wheel.hpp colorwidgets_global.hpp gradient_slider.hpp hue_slider.hpp swatch.hpp gradient_editor.hpp harmony_color_wheel.hpp gradient_list_model.hpp gradient_delegate.hpp ) file(RELATIVE_PATH PREFIX ${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_LIST_DIR}) foreach (HEADER IN LISTS HEADERS) target_sources (${TARGET_NAME} PRIVATE $ $) endforeach (HEADER IN HEADERS) Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/ColorDelegate000066400000000000000000000000361366475014400237470ustar00rootroot00000000000000#include "color_delegate.hpp" Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/ColorDialog000066400000000000000000000000341366475014400234320ustar00rootroot00000000000000#include "color_dialog.hpp" Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/ColorListWidget000066400000000000000000000000411366475014400243100ustar00rootroot00000000000000#include "color_list_widget.hpp" Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/ColorPreview000066400000000000000000000000351366475014400236550ustar00rootroot00000000000000#include "color_preview.hpp" Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/ColorSelector000066400000000000000000000000361366475014400240150ustar00rootroot00000000000000#include "color_selector.hpp" Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/ColorWheel000066400000000000000000000000331366475014400232760ustar00rootroot00000000000000#include "color_wheel.hpp" Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/GradientEditor000066400000000000000000000000371366475014400241430ustar00rootroot00000000000000#include "gradient_editor.hpp" Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/GradientListModel000066400000000000000000000000431366475014400246060ustar00rootroot00000000000000#include "gradient_list_model.hpp" Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/GradientSlider000066400000000000000000000000371366475014400241370ustar00rootroot00000000000000#include "gradient_slider.hpp" Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/HarmonyColorWheel000066400000000000000000000000431366475014400246350ustar00rootroot00000000000000#include "harmony_color_wheel.hpp" Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/HueSlider000066400000000000000000000000321366475014400231160ustar00rootroot00000000000000#include "hue_slider.hpp" Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/abstract_widget_list.hpp000066400000000000000000000051151366475014400262300ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef ABSTRACT_WIDGET_LIST_HPP #define ABSTRACT_WIDGET_LIST_HPP #include "colorwidgets_global.hpp" #include #include class QCP_EXPORT AbstractWidgetList : public QWidget { Q_OBJECT public: explicit AbstractWidgetList(QWidget *parent = 0); ~AbstractWidgetList(); /** * \brief Get the number of items */ int count() const; /** * \brief Swap row a and row b */ virtual void swap(int a, int b) = 0; /// Whether the given row index is valid bool isValidRow(int i) const { return i >= 0 && i < count(); } void setRowHeight(int row, int height); public Q_SLOTS: /** * \brief Remove row i */ void remove(int i); /** * \brief append a default row */ virtual void append() = 0; Q_SIGNALS: void removed(int i); protected: /** * \brief Create a new row with the given widget * * Must be caled by implementations of append() */ void appendWidget(QWidget* w); /** * \brief get the widget found at the given row */ QWidget* widget(int i); /** * \brief get the widget found at the given row */ template T* widget_cast(int i) { return qobject_cast(widget(i)); } /** * \brief clear all rows without emitting signals * * May be useful when implementation want to set all values at once */ void clear(); private Q_SLOTS: void remove_clicked(QWidget* w); void up_clicked(QWidget* w); void down_clicked(QWidget* w); private: class Private; Private * const p; QWidget* create_button(QWidget* data, QSignalMapper*mapper, QString icon_name, QString text, QString tooltip = QString()) const; }; #endif // ABSTRACT_WIDGET_LIST_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/bound_color_selector.hpp000066400000000000000000000024231366475014400262330ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef BOUND_COLOR_SELECTOR_HPP #define BOUND_COLOR_SELECTOR_HPP #include "color_selector.hpp" namespace color_widgets { /** * \brief A color selector bound to a color reference * \todo Maybe this can be removed */ class QCP_EXPORT BoundColorSelector : public ColorSelector { Q_OBJECT private: QColor* ref; public: explicit BoundColorSelector(QColor* reference, QWidget *parent = 0); private Q_SLOTS: void update_reference(QColor); }; } // namespace color_widgets #endif // BOUND_COLOR_SELECTOR_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/color_2d_slider.hpp000066400000000000000000000066061366475014400251020ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_WIDGETS_COLOR_2D_SLIDER_HPP #define COLOR_WIDGETS_COLOR_2D_SLIDER_HPP #include "colorwidgets_global.hpp" #include namespace color_widgets { /** * \brief A 2D slider that edits 2 color components */ class QCP_EXPORT Color2DSlider : public QWidget { Q_OBJECT Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged DESIGNABLE true STORED false ) Q_PROPERTY(qreal hue READ hue WRITE setHue DESIGNABLE false ) Q_PROPERTY(qreal saturation READ saturation WRITE setSaturation DESIGNABLE false ) Q_PROPERTY(qreal value READ value WRITE setValue DESIGNABLE false ) /** * \brief Which color component is used on the x axis */ Q_PROPERTY(Component componentX READ componentX WRITE setComponentX NOTIFY componentXChanged) /** * \brief Which color component is used on the y axis */ Q_PROPERTY(Component componentY READ componentY WRITE setComponentY NOTIFY componentYChanged) public: enum Component { Hue, Saturation, Value }; Q_ENUMS(Component) explicit Color2DSlider(QWidget *parent = nullptr); ~Color2DSlider(); /// Get current color QColor color() const; QSize sizeHint() const Q_DECL_OVERRIDE; /// Get current hue in the range [0-1] qreal hue() const; /// Get current saturation in the range [0-1] qreal saturation() const; /// Get current value in the range [0-1] qreal value() const; Component componentX() const; Component componentY() const; public Q_SLOTS: /// Set current color void setColor(const QColor& c); /** * @param h Hue [0-1] */ void setHue(qreal h); /** * @param s Saturation [0-1] */ void setSaturation(qreal s); /** * @param v Value [0-1] */ void setValue(qreal v); void setComponentX(Component componentX); void setComponentY(Component componentY); Q_SIGNALS: /** * Emitted when the user selects a color or setColor is called */ void colorChanged(QColor); /** * Emitted when the user selects a color */ void colorSelected(QColor); void componentXChanged(Component componentX); void componentYChanged(Component componentY); protected: void paintEvent(QPaintEvent* event) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent* event) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent* event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent* event) Q_DECL_OVERRIDE; void resizeEvent(QResizeEvent* event) Q_DECL_OVERRIDE; private: class Private; Private * const p; }; } // namespace color_widgets #endif // COLOR_WIDGETS_COLOR_2D_SLIDER_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/color_delegate.hpp000066400000000000000000000032121366475014400247730ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_DELEGATE_HPP #define COLOR_DELEGATE_HPP #include "colorwidgets_global.hpp" #include namespace color_widgets { /** Delegate to use a ColorSelector in a color list */ class QCP_EXPORT ColorDelegate : public QAbstractItemDelegate { Q_OBJECT public: explicit ColorDelegate(QWidget *parent = 0); virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem & option, const QModelIndex & index) override; virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; }; } // namespace color_widgets #endif // COLOR_DELEGATE_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/color_dialog.hpp000066400000000000000000000107701366475014400244670ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_DIALOG_HPP #define COLOR_DIALOG_HPP #include "colorwidgets_global.hpp" #include "color_preview.hpp" #include "color_wheel.hpp" #include class QAbstractButton; namespace color_widgets { class QCP_EXPORT ColorDialog : public QDialog { Q_OBJECT Q_ENUMS(ButtonMode) Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged DESIGNABLE true) Q_PROPERTY(ColorWheel::ShapeEnum wheelShape READ wheelShape WRITE setWheelShape NOTIFY wheelShapeChanged) Q_PROPERTY(ColorWheel::ColorSpaceEnum colorSpace READ colorSpace WRITE setColorSpace NOTIFY colorSpaceChanged) Q_PROPERTY(bool wheelRotating READ wheelRotating WRITE setWheelRotating NOTIFY wheelRotatingChanged) /** * \brief whether the color alpha channel can be edited. * * If alpha is disabled, the selected color's alpha will always be 255. */ Q_PROPERTY(bool alphaEnabled READ alphaEnabled WRITE setAlphaEnabled NOTIFY alphaEnabledChanged) public: enum ButtonMode { OkCancel, OkApplyCancel, Close }; explicit ColorDialog(QWidget *parent = 0, Qt::WindowFlags f = 0); ~ColorDialog(); /** * Get currently selected color */ QColor color() const; /** * Set the display mode for the color preview */ void setPreviewDisplayMode(ColorPreview::DisplayMode mode); /** * Get the color preview diplay mode */ ColorPreview::DisplayMode previewDisplayMode() const; bool alphaEnabled() const; /** * Select which dialog buttons to show * * There are three predefined modes: * OkCancel - this is useful when the dialog is modal and we just want to return a color * OkCancelApply - this is for non-modal dialogs * Close - for non-modal dialogs with direct color updates via colorChanged signal */ void setButtonMode(ButtonMode mode); ButtonMode buttonMode() const; QSize sizeHint() const; ColorWheel::ShapeEnum wheelShape() const; ColorWheel::ColorSpaceEnum colorSpace() const; bool wheelRotating() const; public Q_SLOTS: /** * Change color */ void setColor(const QColor &c); /** * Set the current color and show the dialog */ void showColor(const QColor &oldcolor); void setWheelShape(ColorWheel::ShapeEnum shape); void setColorSpace(ColorWheel::ColorSpaceEnum space); void setWheelRotating(bool rotating); /** * Set whether the color alpha channel can be edited. * If alpha is disabled, the selected color's alpha will always be 255. */ void setAlphaEnabled(bool a); Q_SIGNALS: /** * The current color was changed */ void colorChanged(QColor); /** * The user selected the new color by pressing Ok/Apply */ void colorSelected(QColor); void wheelShapeChanged(ColorWheel::ShapeEnum shape); void colorSpaceChanged(ColorWheel::ColorSpaceEnum space); void wheelRotatingChanged(bool rotating); void alphaEnabledChanged(bool alphaEnabled); private Q_SLOTS: /// Update all the Ui elements to match the selected color void setColorInternal(const QColor &color); /// Update from HSV sliders void set_hsv(); /// Update from RGB sliders void set_rgb(); /// Update from Alpha slider void set_alpha(); void on_edit_hex_colorChanged(const QColor& color); void on_edit_hex_colorEditingFinished(const QColor& color); void on_buttonBox_clicked(QAbstractButton*); protected: void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent * event); void mouseReleaseEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); private: class Private; Private * const p; }; } // namespace color_widgets #endif // COLOR_DIALOG_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/color_line_edit.hpp000066400000000000000000000056151366475014400251660ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_WIDGETS_COLOR_LINE_EDIT_HPP #define COLOR_WIDGETS_COLOR_LINE_EDIT_HPP #include "colorwidgets_global.hpp" #include #include namespace color_widgets { /** * \brief A line edit used to define a color name * * Supported string formats: * * Short hex strings #f00 * * Long hex strings #ff0000 * * Color names red * * Function-like rgb(255,0,0) * * Additional string formats supported when showAlpha is true: * * Long hex strings #ff0000ff * * Function like rgba(255,0,0,255) */ class QCP_EXPORT ColorLineEdit : public QLineEdit { Q_OBJECT Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) /** * \brief Whether the widget displays and edits the alpha channel */ Q_PROPERTY(bool showAlpha READ showAlpha WRITE setShowAlpha NOTIFY showAlphaChanged) /** * \brief If \b true, the background of the widget is changed to show the color */ Q_PROPERTY(bool previewColor READ previewColor WRITE setPreviewColor NOTIFY previewColorChanged) public: explicit ColorLineEdit(QWidget* parent = nullptr); ~ColorLineEdit(); QColor color() const; bool showAlpha() const; bool previewColor() const; public Q_SLOTS: void setColor(const QColor& color); void setShowAlpha(bool showAlpha); void setPreviewColor(bool previewColor); Q_SIGNALS: /** * \brief Emitted when the color is changed by any means */ void colorChanged(const QColor& color); /** * \brief Emitted when the user is typing a color but has not finished yet */ void colorEdited(const QColor& color); /** * \brief Emitted when the user finished to edit a string */ void colorEditingFinished(const QColor& color); void showAlphaChanged(bool showAlpha); void previewColorChanged(bool previewColor); protected: void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE; void dropEvent(QDropEvent * event) Q_DECL_OVERRIDE; void paintEvent(QPaintEvent* event) Q_DECL_OVERRIDE; private: class Private; Private* p; }; } // namespace color_widgets #endif // COLOR_WIDGETS_COLOR_LINE_EDIT_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/color_list_widget.hpp000066400000000000000000000045661366475014400255540ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_LIST_WIDGET_HPP #define COLOR_LIST_WIDGET_HPP #include "abstract_widget_list.hpp" #include "color_wheel.hpp" namespace color_widgets { class QCP_EXPORT ColorListWidget : public AbstractWidgetList { Q_OBJECT Q_PROPERTY(QList colors READ colors WRITE setColors NOTIFY colorsChanged ) Q_PROPERTY(ColorWheel::ShapeEnum wheelShape READ wheelShape WRITE setWheelShape NOTIFY wheelShapeChanged) Q_PROPERTY(ColorWheel::ColorSpaceEnum colorSpace READ colorSpace WRITE setColorSpace NOTIFY colorSpaceChanged) Q_PROPERTY(bool wheelRotating READ wheelRotating WRITE setWheelRotating NOTIFY wheelRotatingChanged) public: explicit ColorListWidget(QWidget *parent = 0); ~ColorListWidget(); QList colors() const; void setColors(const QList& colors); void swap(int a, int b); void append(); ColorWheel::ShapeEnum wheelShape() const; ColorWheel::ColorSpaceEnum colorSpace() const; bool wheelRotating() const; Q_SIGNALS: void colorsChanged(const QList&); void wheelShapeChanged(ColorWheel::ShapeEnum shape); void colorSpaceChanged(ColorWheel::ColorSpaceEnum space); void wheelRotatingChanged(bool rotating); public Q_SLOTS: void setWheelShape(ColorWheel::ShapeEnum shape); void setColorSpace(ColorWheel::ColorSpaceEnum space); void setWheelRotating(bool rotating); private Q_SLOTS: void emit_changed(); void handle_removed(int); void color_changed(int row); private: class Private; Private * const p; void append_widget(int col); }; } // namespace color_widgets #endif // COLOR_LIST_WIDGET_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/color_names.hpp000066400000000000000000000032661366475014400243350ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_WIDGETS_COLOR_NAMES_HPP #define COLOR_WIDGETS_COLOR_NAMES_HPP #include #include #include namespace color_widgets { /** * \brief Convert a string into a color * * Supported string formats: * * Short hex strings #f00 * * Long hex strings #ff0000 * * Color names red * * Function-like rgb(255,0,0) * * Additional string formats supported only when \p alpha is true: * * Long hex strings #ff0000ff * * Function like rgba(255,0,0,255) */ QCP_EXPORT QColor colorFromString(const QString& string, bool alpha = true); /** * \brief Convert a color into a string * * Format: * * If the color has full alpha: #ff0000 * * If alpha is true and the color has non-full alpha: #ff000088 */ QCP_EXPORT QString stringFromColor(const QColor& color, bool alpha = true); } // namespace color_widgets #endif // COLOR_WIDGETS_COLOR_NAMES_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/color_palette.hpp000066400000000000000000000150621366475014400246650ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_WIDGETS_COLOR_PALETTE_HPP #define COLOR_WIDGETS_COLOR_PALETTE_HPP #include #include #include #include #include #include #include "colorwidgets_global.hpp" namespace color_widgets { class QCP_EXPORT ColorPalette : public QObject { Q_OBJECT /** * \brief The list of colors */ Q_PROPERTY(QVector colors READ colors WRITE setColors NOTIFY colorsChanged) /** * \brief Name of the palette */ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) /** * \brief Number of colors to display in a row, if 0 unspecified */ Q_PROPERTY(int columns READ columns WRITE setColumns NOTIFY columnsChanged) /** * \brief Number of colors */ Q_PROPERTY(int count READ count) /** * \brief Name of the file the palette has been read from */ Q_PROPERTY(QString fileName READ fileName WRITE setFileName NOTIFY fileNameChanged) /** * \brief Whether it has been modified and it might be advisable to save it */ Q_PROPERTY(bool dirty READ dirty WRITE setDirty NOTIFY dirtyChanged) public: typedef QPair value_type; ColorPalette(const QVector& colors, const QString& name = QString(), int columns = 0); ColorPalette(const QVector >& colors, const QString& name = QString(), int columns = 0); explicit ColorPalette(const QString& name = QString()); ColorPalette(const ColorPalette& other); ColorPalette& operator=(const ColorPalette& other); ~ColorPalette(); ColorPalette(ColorPalette&& other); ColorPalette& operator=(ColorPalette&& other); /** * \brief Color at the given index */ Q_INVOKABLE QColor colorAt(int index) const; /** * \brief Color name at the given index */ Q_INVOKABLE QString nameAt(int index) const; QVector > colors() const; QVector onlyColors() const; int count() const; int columns(); QString name() const; /** * \brief Use a color table to set the colors */ Q_INVOKABLE void loadColorTable(const QVector& color_table); /** * \brief Convert to a color table */ Q_INVOKABLE QVector colorTable() const; /** * \brief Creates a ColorPalette from a color table */ static ColorPalette fromColorTable(const QVector& table); /** * \brief Use the pixels on an image to set the palette colors */ Q_INVOKABLE bool loadImage(const QImage& image); /** * \brief Creates a ColorPalette from a Gimp palette (gpl) file */ static ColorPalette fromImage(const QImage& image); /** * \brief Load contents from a Gimp palette (gpl) file * \returns \b true On Success * \note If this function returns \b false, the palette will become empty */ Q_INVOKABLE bool load(const QString& name); /** * \brief Creates a ColorPalette from a Gimp palette (gpl) file */ static ColorPalette fromFile(const QString& name); QString fileName() const; bool dirty() const; /** * \brief Returns a preview image of the colors in the palette */ QPixmap preview(const QSize& size, const QColor& background=Qt::transparent) const; public Q_SLOTS: void setColumns(int columns); void setColors(const QVector& colors); void setColors(const QVector >& colors); /** * \brief Change the color at the given index */ void setColorAt(int index, const QColor& color); /** * \brief Change the color at the given index */ void setColorAt(int index, const QColor& color, const QString& name); /** * \brief Change the name of a color */ void setNameAt(int index, const QString& name = QString()); /** * \brief Append a color at the end */ void appendColor(const QColor& color, const QString& name = QString()); /** * \brief Insert a color in an arbitrary location */ void insertColor(int index, const QColor& color, const QString& name = QString()); /** * \brief Remove the color at the given index */ void eraseColor(int index); /** * \brief Change file name and save * \returns \b true on success */ bool save(const QString& filename); /** * \brief save to file, the filename is \c fileName or determined automatically * \returns \b true on success */ bool save(); void setName(const QString& name); void setFileName(const QString& name); void setDirty(bool dirty); Q_SIGNALS: /** * \brief Emitted when all the colors have changed */ void colorsChanged(const QVector >&); void columnsChanged(int); void nameChanged(const QString&); void fileNameChanged(const QString&); void dirtyChanged(bool); /** * \brief Emitted when the color or the name at the given index has been modified */ void colorChanged(int index); /** * \brief Emitted when the color at the given index has been removed */ void colorRemoved(int index); /** * \brief Emitted when a single color has been added */ void colorAdded(int index); /** * \brief Emitted when the colors have been modified with a simple operation (set, append etc.) */ void colorsUpdated(const QVector>&); private: /** * \brief Returns \c name if it isn't null, otherwise a default value */ QString unnamed(const QString& name = QString()) const; /** * \brief Emit all the necessary signals when the palette has been completely overwritten */ void emitUpdate(); class Private; Private *p; }; } // namespace color_widgets #endif // COLOR_WIDGETS_COLOR_PALETTE_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/color_palette_model.hpp000066400000000000000000000105361366475014400260460ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_WIDGETS_COLOR_PALETTE_MODEL_HPP #define COLOR_WIDGETS_COLOR_PALETTE_MODEL_HPP #include #include "color_palette.hpp" namespace color_widgets { class QCP_EXPORT ColorPaletteModel : public QAbstractListModel { Q_OBJECT /** * \brief List of directories to be scanned for palette files */ Q_PROPERTY(QStringList searchPaths READ searchPaths WRITE setSearchPaths NOTIFY searchPathsChanged) /** * \brief Default directory to be used when saving a palette */ Q_PROPERTY(QString savePath READ savePath WRITE setSavePath NOTIFY savePathChanged) /** * \brief Size of the icon used for the palette previews */ Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize NOTIFY iconSizeChanged) public: ColorPaletteModel(); ~ColorPaletteModel(); int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; bool removeRows(int row, int count, const QModelIndex & parent = QModelIndex()) Q_DECL_OVERRIDE; QString savePath() const; QStringList searchPaths() const; QSize iconSize() const; /** * \brief Number of palettes */ int count() const; /** * \brief Returns a reference to the first palette with the given name * \pre hasPalette(name) */ const ColorPalette& palette(const QString& name) const; /** * \brief Whether a palette with the given name exists in the model */ bool hasPalette(const QString& name) const; /** * \brief Get the palette at the given index (row) * \pre 0 <= index < count() */ const ColorPalette& palette(int index) const; /** * \brief Updates an existing palette * \param index Palette index * \param palette New palette * \param save Whether to save the palette to the filesystem * * Saving will try: (in this order) * * To overwrite the file pointed by the old palette * * To write to the new palette file name * * To create a file in the save path * If all of the above fail, the palette will be replaced interally * but not on the filesystem * * \returns \b true if the palette has been successfully updated (and saved) */ bool updatePalette(int index, const ColorPalette& palette, bool save = true); /** * \brief Remove a palette from the model and optionally from the filesystem * \returns \b true if the palette has been successfully removed */ bool removePalette(int index, bool remove_file = true); /** * \brief Remove a palette to the model and optionally to the filesystem * \returns \b true if the palette has been successfully added */ bool addPalette(const ColorPalette& palette, bool save = true); /** * \brief The index of the palette with the given file name * \returns -1 if none is found */ int indexFromFile(const QString& filename) const; public Q_SLOTS: void setSavePath(const QString& savePath); void setSearchPaths(const QStringList& searchPaths); void addSearchPath(const QString& path); void setIconSize(const QSize& iconSize); /** * \brief Load palettes files found in the search paths */ void load(); Q_SIGNALS: void savePathChanged(const QString& savePath); void searchPathsChanged(const QStringList& searchPaths); void iconSizeChanged(const QSize& iconSize); private: class Private; Private* p; }; } // namespace color_widgets #endif // COLOR_WIDGETS_COLOR_PALETTE_MODEL_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/color_palette_widget.hpp000066400000000000000000000133001366475014400262210ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_WIDGETS_COLOR_PALETTE_WIDGET_HPP #define COLOR_WIDGETS_COLOR_PALETTE_WIDGET_HPP #include #include #include "color_palette_model.hpp" #include "swatch.hpp" namespace color_widgets { /** * \brief A widget to use and modify palettes */ class QCP_EXPORT ColorPaletteWidget : public QWidget { Q_OBJECT /** * \brief Model used to store the palettes */ Q_PROPERTY(ColorPaletteModel* model READ model WRITE setModel NOTIFY modelChanged) /** * \brief Size of a single color in the swatch widget */ Q_PROPERTY(QSize colorSize READ colorSize WRITE setColorSize NOTIFY colorSizeChanged) /** * \brief Policy for colorSize **/ Q_PROPERTY(color_widgets::Swatch::ColorSizePolicy colorSizePolicy READ colorSizePolicy WRITE setColorSizePolicy NOTIFY colorSizePolicyChanged) /** * \brief Border around the colors */ Q_PROPERTY(QPen border READ border WRITE setBorder NOTIFY borderChanged) /** * \brief Forces the Swatch to display that many rows of colors * * If there are too few elements, the widget will display less than this * many rows. * * A value of0 means that the number of rows is automatic. * * \note Conflicts with forcedColumns */ Q_PROPERTY(int forcedRows READ forcedRows WRITE setForcedRows NOTIFY forcedRowsChanged) /** * \brief Forces the Swatch to display that many columns of colors * * If there are too few elements, the widget will display less than this * many columns. * * A value of 0 means that the number of columns is automatic. * * \note Conflicts with forcedRows */ Q_PROPERTY(int forcedColumns READ forcedColumns WRITE setForcedColumns NOTIFY forcedColumnsChanged) /** * \brief Whether the palettes can be modified via user interaction */ Q_PROPERTY(bool readOnly READ readOnly WRITE setReadOnly NOTIFY readOnlyChanged) /** * \brief Currently selected color */ Q_PROPERTY(QColor currentColor READ currentColor WRITE setCurrentColor NOTIFY currentColorChanged) /** * \brief Currently selected model row */ Q_PROPERTY(int currentRow READ currentRow WRITE setCurrentRow NOTIFY currentRowChanged) /** * \brief Palette shown by the widget */ Q_PROPERTY(const ColorPalette& currentPalette READ currentPalette NOTIFY currentPaletteChanged) public: ColorPaletteWidget(QWidget* parent = nullptr); ~ColorPaletteWidget(); ColorPaletteModel* model() const; /** * \brief Currently selected palette * \pre model() != nullptr and there is a selected palette */ const ColorPalette& currentPalette() const; QSize colorSize() const; Swatch::ColorSizePolicy colorSizePolicy() const; QPen border() const; int forcedRows() const; int forcedColumns() const; bool readOnly() const; QColor currentColor() const; int currentRow() const; public Q_SLOTS: void setModel(ColorPaletteModel* model); void setColorSize(const QSize& colorSize); void setColorSizePolicy(Swatch::ColorSizePolicy colorSizePolicy); void setBorder(const QPen& border); void setForcedRows(int forcedRows); void setForcedColumns(int forcedColumns); void setReadOnly(bool readOnly); /** * \brief Clear the selected color */ void clearCurrentColor(); /** * \brief Attempt to select a color * * If the given color is available in the current palete, it will be selected * \return \b true on success */ bool setCurrentColor(const QColor& color); /** * \brief Attempt to select a color by name * * If the given color is available in the current palete, it will be selected * \return \b true on success */ bool setCurrentColor(const QString& name); /** * \brief Attempt to select a color by index * * If the given color is available in the current palete, it will be selected * \return \b true on success */ bool setCurrentColor(int index); /** * \brief Set the selected row in the model */ void setCurrentRow(int currentRow); Q_SIGNALS: void modelChanged(ColorPaletteModel* model); void colorSizeChanged(const QSize& colorSize); void colorSizePolicyChanged(Swatch::ColorSizePolicy colorSizePolicy); void forcedRowsChanged(int forcedRows); void forcedColumnsChanged(int forcedColumns); void readOnlyChanged(bool readOnly); void currentColorChanged(const QColor& currentColor); void currentColorChanged(int index); void borderChanged(const QPen& border); void currentRowChanged(int currentRow); void currentPaletteChanged(const ColorPalette& palette); private Q_SLOTS: void on_palette_list_currentIndexChanged(int index); void on_swatch_doubleClicked(int index); private: class Private; std::unique_ptr p; }; } // namespace color_widgets #endif // COLOR_WIDGETS_COLOR_PALETTE_WIDGET_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/color_preview.hpp000066400000000000000000000063571366475014400247170ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * \copyright Copyright (C) 2014 Calle Laakkonen * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_PREVIEW_HPP #define COLOR_PREVIEW_HPP #include "colorwidgets_global.hpp" #include namespace color_widgets { /** * Simple widget that shows a preview of a color */ class QCP_EXPORT ColorPreview : public QWidget { Q_OBJECT Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged DESIGNABLE true) Q_PROPERTY(QColor comparisonColor READ comparisonColor WRITE setComparisonColor NOTIFY comparisonColorChanged DESIGNABLE true) Q_PROPERTY(DisplayMode display_mode READ displayMode WRITE setDisplayMode NOTIFY displayModeChanged DESIGNABLE true) Q_PROPERTY(QBrush background READ background WRITE setBackground NOTIFY backgroundChanged DESIGNABLE true) Q_ENUMS(DisplayMode) public: enum DisplayMode { NoAlpha, ///< Show current color with no transparency AllAlpha, ///< show current color with transparency SplitAlpha, ///< Show both solid and transparent side by side SplitColor ///< Show current and comparison colors side by side }; Q_ENUMS(DisplayMode) explicit ColorPreview(QWidget *parent = 0); ~ColorPreview(); /// Get the background visible under transparent colors QBrush background() const; /// Change the background visible under transparent colors void setBackground(const QBrush &bk); /// Get color display mode DisplayMode displayMode() const; /// Set how transparent colors are handled void setDisplayMode(DisplayMode dm); /// Get current color QColor color() const; /// Get the comparison color QColor comparisonColor() const; QSize sizeHint () const; void paint(QPainter &painter, QRect rect) const; public Q_SLOTS: /// Set current color void setColor(const QColor &c); /// Set the comparison color void setComparisonColor(const QColor &c); Q_SIGNALS: /// Emitted when the user clicks on the widget void clicked(); /// Emitted on setColor void colorChanged(QColor); void comparisonColorChanged(QColor); void displayModeChanged(DisplayMode); void backgroundChanged(const QBrush&); protected: void paintEvent(QPaintEvent *); void resizeEvent(QResizeEvent *); void mouseReleaseEvent(QMouseEvent *ev); void mouseMoveEvent(QMouseEvent *ev); private: class Private; Private * const p; }; } // namespace color_widgets Q_DECLARE_METATYPE(color_widgets::ColorPreview::DisplayMode) #endif // COLOR_PREVIEW_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/color_selector.hpp000066400000000000000000000060611366475014400250460ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_SELECTOR_HPP #define COLOR_SELECTOR_HPP #include "color_preview.hpp" #include "color_wheel.hpp" namespace color_widgets { /** * Color preview that opens a color dialog */ class QCP_EXPORT ColorSelector : public ColorPreview { Q_OBJECT Q_ENUMS(UpdateMode) Q_PROPERTY(UpdateMode updateMode READ updateMode WRITE setUpdateMode NOTIFY updateModeChanged) Q_PROPERTY(Qt::WindowModality dialogModality READ dialogModality WRITE setDialogModality NOTIFY dialogModalityChanged) Q_PROPERTY(ColorWheel::ShapeEnum wheelShape READ wheelShape WRITE setWheelShape NOTIFY wheelShapeChanged) Q_PROPERTY(ColorWheel::ColorSpaceEnum colorSpace READ colorSpace WRITE setColorSpace NOTIFY colorSpaceChanged) Q_PROPERTY(bool wheelRotating READ wheelRotating WRITE setWheelRotating NOTIFY wheelRotatingChanged) public: enum UpdateMode { Confirm, ///< Update color only after the dialog has been accepted Continuous ///< Update color as it's being modified in the dialog }; explicit ColorSelector(QWidget *parent = 0); ~ColorSelector(); void setUpdateMode(UpdateMode m); UpdateMode updateMode() const; Qt::WindowModality dialogModality() const; void setDialogModality(Qt::WindowModality m); ColorWheel::ShapeEnum wheelShape() const; ColorWheel::ColorSpaceEnum colorSpace() const; bool wheelRotating() const; Q_SIGNALS: void wheelShapeChanged(ColorWheel::ShapeEnum shape); void colorSpaceChanged(ColorWheel::ColorSpaceEnum space); void wheelRotatingChanged(bool rotating); void updateModeChanged(UpdateMode); void dialogModalityChanged(Qt::WindowModality); public Q_SLOTS: void showDialog(); void setWheelShape(ColorWheel::ShapeEnum shape); void setColorSpace(ColorWheel::ColorSpaceEnum space); void setWheelRotating(bool rotating); private Q_SLOTS: void accept_dialog(); void reject_dialog(); void update_old_color(const QColor &c); protected: void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent * event); private: /// Connect/Disconnect colorChanged based on UpdateMode void connect_dialog(); /// Disconnect from dialog update void disconnect_dialog(); class Private; Private * const p; }; } // namespace color_widgets #endif // COLOR_SELECTOR_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/color_utils.hpp000066400000000000000000000040341366475014400243640ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_UTILS_HPP #define COLOR_UTILS_HPP #include #include #include "QtColorWidgets/colorwidgets_global.hpp" namespace color_widgets { namespace detail { inline qreal color_chromaF(const QColor& c) { qreal max = qMax(c.redF(), qMax(c.greenF(), c.blueF())); qreal min = qMin(c.redF(), qMin(c.greenF(), c.blueF())); return max - min; } inline qreal color_lumaF(const QColor& c) { return 0.30 * c.redF() + 0.59 * c.greenF() + 0.11 * c.blueF(); } QColor color_from_lch(qreal hue, qreal chroma, qreal luma, qreal alpha = 1 ); inline QColor rainbow_lch(qreal hue) { return color_from_lch(hue,1,1); } inline QColor rainbow_hsv(qreal hue) { return QColor::fromHsvF(hue,1,1); } inline qreal color_lightnessF(const QColor& c) { return ( qMax(c.redF(),qMax(c.greenF(),c.blueF())) + qMin(c.redF(),qMin(c.greenF(),c.blueF())) ) / 2; } inline qreal color_HSL_saturationF(const QColor& col) { qreal c = color_chromaF(col); qreal l = color_lightnessF(col); if ( qFuzzyCompare(l+1,1) || qFuzzyCompare(l+1,2) ) return 0; return c / (1-qAbs(2*l-1)); } QCP_EXPORT QColor color_from_hsl(qreal hue, qreal sat, qreal lig, qreal alpha = 1 ); } // namespace detail } // namespace color_widgets #endif // COLOR_UTILS_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/color_wheel.hpp000066400000000000000000000117031366475014400243310ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_WHEEL_HPP #define COLOR_WHEEL_HPP #include #include "colorwidgets_global.hpp" namespace color_widgets { /** * \brief Display an analog widget that allows the selection of a HSV color * * It has an outer wheel to select the Hue and an intenal square to select * Saturation and Lightness. */ class QCP_EXPORT ColorWheel : public QWidget { Q_OBJECT Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged DESIGNABLE true STORED false ) Q_PROPERTY(qreal hue READ hue WRITE setHue DESIGNABLE false ) Q_PROPERTY(qreal saturation READ saturation WRITE setSaturation DESIGNABLE false ) Q_PROPERTY(qreal value READ value WRITE setValue DESIGNABLE false ) Q_PROPERTY(unsigned wheelWidth READ wheelWidth WRITE setWheelWidth NOTIFY wheelWidthChanged DESIGNABLE true ) Q_PROPERTY(ShapeEnum selectorShape READ selectorShape WRITE setSelectorShape NOTIFY selectorShapeChanged DESIGNABLE true ) Q_PROPERTY(bool rotatingSelector READ rotatingSelector WRITE setRotatingSelector NOTIFY rotatingSelectorChanged DESIGNABLE true ) Q_PROPERTY(ColorSpaceEnum colorSpace READ colorSpace WRITE setColorSpace NOTIFY colorSpaceChanged DESIGNABLE true ) public: enum ShapeEnum { ShapeTriangle, ///< A triangle ShapeSquare, ///< A square }; enum AngleEnum { AngleFixed, ///< The inner part doesn't rotate AngleRotating, ///< The inner part follows the hue selector }; enum ColorSpaceEnum { ColorHSV, ///< Use the HSV color space ColorHSL, ///< Use the HSL color space ColorLCH, ///< Use Luma Chroma Hue (Y_601') }; Q_ENUM(ShapeEnum); Q_ENUM(AngleEnum); Q_ENUM(ColorSpaceEnum); explicit ColorWheel(QWidget *parent = 0); ~ColorWheel(); /// Get current color QColor color() const; virtual QSize sizeHint() const Q_DECL_OVERRIDE; /// Get current hue in the range [0-1] qreal hue() const; /// Get current saturation in the range [0-1] qreal saturation() const; /// Get current value in the range [0-1] qreal value() const; /// Get the width in pixels of the outer wheel unsigned int wheelWidth() const; /// Set the width in pixels of the outer wheel void setWheelWidth(unsigned int w); /// Shape of the internal selector ShapeEnum selectorShape() const; /// Whether the internal selector should rotare in accordance with the hue bool rotatingSelector() const; /// Color space used to preview/edit the color ColorSpaceEnum colorSpace() const; public Q_SLOTS: /// Set current color void setColor(QColor c); /** * @param h Hue [0-1] */ void setHue(qreal h); /** * @param s Saturation [0-1] */ void setSaturation(qreal s); /** * @param v Value [0-1] */ void setValue(qreal v); /// Sets the shape of the internal selector void setSelectorShape(ShapeEnum shape); /// Sets whether the internal selector should rotare in accordance with the hue void setRotatingSelector(bool rotating); /// Sets the color space used to preview/edit the color void setColorSpace(ColorSpaceEnum space); Q_SIGNALS: /** * Emitted when the user selects a color or setColor is called */ void colorChanged(QColor); /** * Emitted when the user selects a color */ void colorSelected(QColor); void wheelWidthChanged(unsigned); void selectorShapeChanged(ShapeEnum shape); void rotatingSelectorChanged(bool rotating); void colorSpaceChanged(ColorSpaceEnum space); protected: void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE; void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE; void dragEnterEvent(QDragEnterEvent* event) Q_DECL_OVERRIDE; void dropEvent(QDropEvent* event) Q_DECL_OVERRIDE; protected: class Private; ColorWheel(QWidget *parent, Private* data); Private* data() const { return p; } private: Private * const p; }; } // namespace color_widgets #endif // COLOR_WHEEL_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/color_wheel_private.hpp000066400000000000000000000177541366475014400260770ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * \copyright Copyright (C) 2017 caryoscelus * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/color_wheel.hpp" #include "QtColorWidgets/color_utils.hpp" #include #include #include namespace color_widgets { enum MouseStatus { Nothing, DragCircle, DragSquare }; class ColorWheel::Private { private: ColorWheel * const w; public: qreal hue, sat, val; bool backgroundIsDark; unsigned int wheel_width; MouseStatus mouse_status; QPixmap hue_ring; QImage inner_selector; std::vector inner_selector_buffer; ColorSpaceEnum color_space = ColorHSV; bool rotating_selector = true; ShapeEnum selector_shape = ShapeTriangle; QColor (*color_from)(qreal,qreal,qreal,qreal); QColor (*rainbow_from_hue)(qreal); int max_size = 128; Private(ColorWheel *widget) : w(widget), hue(0), sat(0), val(0), wheel_width(20), mouse_status(Nothing), color_from(&QColor::fromHsvF), rainbow_from_hue(&detail::rainbow_hsv) { } void setup() { qreal backgroundValue = w->palette().background().color().valueF(); backgroundIsDark = backgroundValue < 0.5; } virtual ~Private(){} /// Calculate outer wheel radius from idget center qreal outer_radius() const { return qMin(w->geometry().width(), w->geometry().height())/2; } /// Calculate inner wheel radius from idget center qreal inner_radius() const { return outer_radius()-wheel_width; } /// Calculate the edge length of the inner square qreal square_size() const { return inner_radius()*qSqrt(2); } /// Calculate the height of the inner triangle qreal triangle_height() const { return inner_radius()*3/2; } /// Calculate the side of the inner triangle qreal triangle_side() const { return inner_radius()*qSqrt(3); } /// return line from center to given point QLineF line_to_point(const QPoint &p) const { return QLineF (w->geometry().width()/2, w->geometry().height()/2, p.x(), p.y()); } /** * Ensures the internal image buffer is the correct size * and that the QImage is associated to it */ void init_buffer(QSize size) { std::size_t linear_size = size.width() * size.height(); if ( inner_selector_buffer.size() == linear_size ) return; inner_selector_buffer.resize(linear_size); inner_selector = QImage( reinterpret_cast(inner_selector_buffer.data()), size.width(), size.height(), QImage::Format_RGB32 ); } void render_square() { int width = qMin(square_size(), max_size); init_buffer(QSize(width, width)); for ( int y = 0; y < width; ++y ) { for ( int x = 0; x < width; ++x ) { QRgb color = color_from(hue,double(x)/width,double(y)/width,1).rgb(); inner_selector_buffer[width * y + x] = color; } } } /** * \brief renders the selector as a triangle * \note It's the same as a square with the edge with value=0 collapsed to a single point */ void render_triangle() { QSizeF size = selector_size(); if ( size.height() > max_size ) size *= max_size / size.height(); qreal ycenter = size.height()/2; QSize isize = size.toSize(); init_buffer(isize); for (int x = 0; x < isize.width(); x++ ) { qreal pval = x / size.height(); qreal slice_h = size.height() * pval; for (int y = 0; y < isize.height(); y++ ) { qreal ymin = ycenter-slice_h/2; qreal psat = qBound(0.0,(y-ymin)/slice_h,1.0); QRgb color = color_from(hue,psat,pval,1).rgb(); inner_selector_buffer[isize.width() * y + x] = color; } } } /// Updates the inner image that displays the saturation-value selector void render_inner_selector() { if ( selector_shape == ShapeTriangle ) render_triangle(); else render_square(); } /// Offset of the selector image QPointF selector_image_offset() { if ( selector_shape == ShapeTriangle ) return QPointF(-inner_radius(),-triangle_side()/2); return QPointF(-square_size()/2,-square_size()/2); } /** * \brief Size of the selector when rendered to the screen */ QSizeF selector_size() { if ( selector_shape == ShapeTriangle ) return QSizeF(triangle_height(), triangle_side()); return QSizeF(square_size(), square_size()); } /// Rotation of the selector image qreal selector_image_angle() { if ( selector_shape == ShapeTriangle ) { if ( rotating_selector ) return -hue*360-60; return -150; } else { if ( rotating_selector ) return -hue*360-45; else return 180; } } /// Updates the outer ring that displays the hue selector void render_ring() { hue_ring = QPixmap(outer_radius()*2,outer_radius()*2); hue_ring.fill(Qt::transparent); QPainter painter(&hue_ring); painter.setRenderHint(QPainter::Antialiasing); painter.setCompositionMode(QPainter::CompositionMode_Source); const int hue_stops = 24; QConicalGradient gradient_hue(0, 0, 0); if ( gradient_hue.stops().size() < hue_stops ) { for ( double a = 0; a < 1.0; a+=1.0/(hue_stops-1) ) { gradient_hue.setColorAt(a,rainbow_from_hue(a)); } gradient_hue.setColorAt(1,rainbow_from_hue(0)); } painter.translate(outer_radius(),outer_radius()); painter.setPen(Qt::NoPen); painter.setBrush(QBrush(gradient_hue)); painter.drawEllipse(QPointF(0,0),outer_radius(),outer_radius()); painter.setBrush(Qt::transparent);//palette().background()); painter.drawEllipse(QPointF(0,0),inner_radius(),inner_radius()); } void set_color(const QColor& c) { switch ( color_space ) { case ColorHSV: hue = qMax(0.0, c.hsvHueF()); sat = c.hsvSaturationF(); val = c.valueF(); break; case ColorHSL: hue = qMax(0.0, c.hueF()); sat = detail::color_HSL_saturationF(c); val = detail::color_lightnessF(c); break; case ColorLCH: hue = qMax(0.0, c.hsvHueF()); sat = detail::color_chromaF(c); val = detail::color_lumaF(c); break; } } void draw_ring_editor(double editor_hue, QPainter& painter, QColor color) { painter.setPen(QPen(color,3)); painter.setBrush(Qt::NoBrush); QLineF ray(0, 0, outer_radius(), 0); ray.setAngle(editor_hue*360); QPointF h1 = ray.p2(); ray.setLength(inner_radius()); QPointF h2 = ray.p2(); painter.drawLine(h1,h2); } }; } // namespace color_widgets Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/colorwidgets_global.hpp000066400000000000000000000005101366475014400260460ustar00rootroot00000000000000#ifndef QT_COLOR_WIDGETS_GLOBAL_H #define QT_COLOR_WIDGETS_GLOBAL_H #include #if defined(QTCOLORWIDGETS_STATICALLY_LINKED) # define QCP_EXPORT #elif defined(QTCOLORWIDGETS_LIBRARY) # define QCP_EXPORT Q_DECL_EXPORT #else # define QCP_EXPORT Q_DECL_IMPORT #endif #endif // QT_COLOR_WIDGETS_GLOBAL_H Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/gradient_delegate.hpp000066400000000000000000000070151366475014400254570ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_WIDGETS_GRADIENT_DELEGATE_HPP #define COLOR_WIDGETS_GRADIENT_DELEGATE_HPP #include #include #include "QtColorWidgets/gradient_editor.hpp" namespace color_widgets { /** * \brief Item delegate to edits gradients * * In order to make it work, return as edit data from the model a QBrush with a gradient */ class QCP_EXPORT GradientDelegate : public QStyledItemDelegate { Q_OBJECT public: QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const Q_DECL_OVERRIDE { QVariant data = index.data(Qt::EditRole); if ( data.canConvert() ) { QBrush brush = data.value(); if ( brush.gradient() ) { GradientEditor* editor = new GradientEditor(parent); editor->setStops(brush.gradient()->stops()); return editor; } } return QStyledItemDelegate::createEditor(parent, option, index); } void setModelData(QWidget * widget, QAbstractItemModel * model, const QModelIndex & index) const Q_DECL_OVERRIDE { if ( GradientEditor* editor = qobject_cast(widget) ) model->setData(index, QBrush(editor->gradient()), Qt::EditRole); else QStyledItemDelegate::setModelData(widget, model, index); } void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const Q_DECL_OVERRIDE { QVariant display_data = index.data(Qt::DisplayRole); QVariant gradient_data = display_data.isValid() ? display_data : index.data(Qt::EditRole); if ( gradient_data.canConvert() ) { QBrush brush = gradient_data.value(); if ( brush.gradient() ) { QBrush background; background.setTexture(QPixmap(QStringLiteral(":/color_widgets/alphaback.png"))); painter->fillRect(option.rect, background); QLinearGradient g(option.rect.topLeft(), option.rect.topRight()); g.setStops(brush.gradient()->stops()); painter->fillRect(option.rect, g); if ( option.state & QStyle::State_Selected ) { int border = 2; painter->setBrush(Qt::transparent); painter->setPen(QPen(option.palette.highlight(), border)); painter->drawRect(option.rect.adjusted(border/2, border/2, -border/2, -border/2)); } return; } } QStyledItemDelegate::paint(painter, option, index); } }; } // namespace color_widgets #endif // COLOR_WIDGETS_GRADIENT_DELEGATE_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/gradient_editor.hpp000066400000000000000000000073011366475014400251710ustar00rootroot00000000000000/** * \file gradient_editor.hpp * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef GRADIENT_EDITOR_HPP #define GRADIENT_EDITOR_HPP #include "colorwidgets_global.hpp" #include #include namespace color_widgets { class ColorDialog; /** * \brief A slider that moves on top of a gradient */ class QCP_EXPORT GradientEditor : public QWidget { Q_OBJECT Q_PROPERTY(QBrush background READ background WRITE setBackground NOTIFY backgroundChanged) Q_PROPERTY(QGradientStops stops READ stops WRITE setStops NOTIFY stopsChanged) Q_PROPERTY(QLinearGradient gradient READ gradient WRITE setGradient) Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation) Q_PROPERTY(int selectedStop READ selectedStop WRITE setSelectedStop NOTIFY selectedStopChanged) Q_PROPERTY(QColor selectedColor READ selectedColor WRITE setSelectedColor) public: explicit GradientEditor(QWidget *parent = 0); explicit GradientEditor(Qt::Orientation orientation, QWidget *parent = 0); ~GradientEditor(); QSize sizeHint() const override; /// Get the background, it's visible for transparent gradient stops QBrush background() const; /// Set the background, it's visible for transparent gradient stops void setBackground(const QBrush &bg); /// Get the colors that make up the gradient QGradientStops stops() const; /// Set the colors that make up the gradient void setStops(const QGradientStops &colors); /// Get the gradient QLinearGradient gradient() const; /// Set the gradient void setGradient(const QLinearGradient &gradient); Qt::Orientation orientation() const; /** * \brief Dialog shown when double clicking a stop */ ColorDialog* dialog() const; /** * \brief Index of the currently selected gradient stop (or -1 if there is no selection) */ int selectedStop() const; /** * \brief Color of the selected stop */ QColor selectedColor() const; public Q_SLOTS: void setOrientation(Qt::Orientation); void setSelectedStop(int stop); void setSelectedColor(const QColor& color); void addStop(); void removeStop(); Q_SIGNALS: void backgroundChanged(const QBrush&); void stopsChanged(const QGradientStops&); void selectedStopChanged(int); protected: void paintEvent(QPaintEvent *ev) override; void mousePressEvent(QMouseEvent *ev) override; void mouseMoveEvent(QMouseEvent *ev) override; void mouseReleaseEvent(QMouseEvent *ev) override; void leaveEvent(QEvent * event) override; void mouseDoubleClickEvent(QMouseEvent *event) override; void dragEnterEvent(QDragEnterEvent *event) override; void dragMoveEvent(QDragMoveEvent* event) override; void dragLeaveEvent(QDragLeaveEvent *event) override; void dropEvent(QDropEvent* event) override; private Q_SLOTS: void dialogUpdate(const QColor& c); private: class Private; Private * const p; }; } // namespace color_widgets #endif // GRADIENT_EDITOR_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/gradient_helper.hpp000066400000000000000000000055031366475014400251640ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef GRADIENT_HELPER_HPP #define GRADIENT_HELPER_HPP #include "colorwidgets_global.hpp" #include namespace color_widgets { inline QColor blendColors(const QColor& a, const QColor& b, qreal ratio) { return QColor::fromRgbF( a.redF() * (1-ratio) + b.redF() * ratio, a.greenF() * (1-ratio) + b.greenF() * ratio, a.blueF() * (1-ratio) + b.blueF() * ratio, a.alphaF() * (1-ratio) + b.alphaF() * ratio ); } /** * \brief Get an insertion point in the gradient * \param gradient Gradient stops to look into (must be properly set up) * \param factor Value in [0, 1] to get the color for * \return A pair whose first element is the index to insert the new value at, and a GradientStop */ inline QPair Q_DECL_EXPORT gradientBlendedColorInsert(const QGradientStops& gradient, qreal factor) { if ( gradient.empty() ) return {0, {0, QColor()}}; if ( gradient.size() == 1 || factor <= 0 ) return {0, gradient.front()}; int i = 0; QGradientStop s1; for ( auto s2 : gradient ) { if ( factor < s2.first ) { qreal ratio = (factor - s1.first) / (s2.first - s1.first); return {i, {factor, blendColors(s1.second, s2.second, ratio)}}; } s1 = s2; ++i; } return {gradient.size(), gradient.back()}; } /** * \brief Returns a color in the gradient * \param gradient Gradient stops to look into (must be properly set up) * \param factor Value in [0, 1] to get the color for */ inline QColor Q_DECL_EXPORT gradientBlendedColor(const QGradientStops& gradient, qreal factor) { return gradientBlendedColorInsert(gradient, factor).second.second; } /** * \brief Returns a color in the gradient * \param gradient Gradient to look into * \param factor Value in [0, 1] to get the color for */ inline QColor Q_DECL_EXPORT gradientBlendedColor(const QGradient& gradient, qreal factor) { return gradientBlendedColor(gradient.stops(), factor); } } // namespace color_widgets #endif // GRADIENT_HELPER_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/gradient_list_model.hpp000066400000000000000000000110651366475014400260400ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_WIDGETS_GRADIENT_LIST_MODEL_HPP #define COLOR_WIDGETS_GRADIENT_LIST_MODEL_HPP #include "colorwidgets_global.hpp" #include #include #include namespace color_widgets { class QCP_EXPORT GradientListModel : public QAbstractListModel { Q_OBJECT /** * \brief Size of the icon used for the gradient previews */ Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize NOTIFY iconSizeChanged) Q_PROPERTY(ItemEditMode editMode READ editMode WRITE setEditMode NOTIFY editModeChanged) public: enum ItemEditMode { EditNone = 0, EditName, EditGradient, }; Q_ENUM(ItemEditMode); GradientListModel(QObject *parent = nullptr); ~GradientListModel(); int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; Qt::ItemFlags flags(const QModelIndex & index) const Q_DECL_OVERRIDE; bool setData(const QModelIndex & index, const QVariant & value, int role) Q_DECL_OVERRIDE; QSize iconSize() const; /** * \brief Number of gradients */ int count() const; /** * \brief Remove all gradients */ void clear(); /** * \brief Returns a reference to the first gradient with the given name * \pre hasGradient(name) */ const QLinearGradient& gradient(const QString& name) const; /** * \brief Returns a reference to the first gradient with the given name * \pre hasGradient(name) */ QGradientStops gradientStops(const QString& name) const; /** * \brief Whether a gradient with the given name exists in the model */ bool hasGradient(const QString& name) const; /** * \brief Get the gradient at the given index (row) * \pre 0 <= index < count() */ const QLinearGradient& gradient(int index) const; /** * \brief Get the gradient stops at the given index (row) * \pre 0 <= index < count() */ QGradientStops gradientStops(int index) const; /** * \brief Inserts or updates a gradient * \returns The index for the new gradient */ int setGradient(const QString& name, const QGradient& gradient); int setGradient(const QString& name, const QGradientStops& gradient); /** * \brief Updates the gradient at \p index */ bool setGradient(int index, const QGradient& gradient); bool setGradient(int index, const QGradientStops& gradient); /** * \brief Renames the gradient at \p index * \returns \b true on success */ bool rename(int index, const QString& new_name); /** * \brief Renames a gradient * \returns \b true on success */ bool rename(const QString& old_name, const QString& new_name); /** * \brief Remove a gradient from the model * \returns \b true if the gradient has been successfully removed */ bool removeGradient(const QString& name); bool removeGradient(int index); /** * \brief The index of the gradient with the given name * \returns -1 if none is found */ int indexFromName(const QString& name) const; /** * \brief Name of the gradient at index */ QString nameFromIndex(int index) const; ItemEditMode editMode() const; /** * \brief Brush for a gradient * \pre 0 <= \p index < count() */ QBrush gradientBrush(int index) const; public Q_SLOTS: void setIconSize(const QSize& iconSize); void setEditMode(ItemEditMode mode); Q_SIGNALS: void iconSizeChanged(const QSize& iconSize); void editModeChanged(ItemEditMode mode); private: class Private; std::unique_ptr d; }; } // namespace color_widgets #endif // COLOR_WIDGETS_GRADIENT_LIST_MODEL_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/gradient_slider.hpp000066400000000000000000000066661366475014400252020ustar00rootroot00000000000000/** * \file gradient_slider.hpp * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * \copyright Copyright (C) 2014 Calle Laakkonen * \copyright Copyright (C) 2017 caryoscelus * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef GRADIENT_SLIDER_HPP #define GRADIENT_SLIDER_HPP #include "colorwidgets_global.hpp" #include #include namespace color_widgets { /** * \brief A slider that moves on top of a gradient */ class QCP_EXPORT GradientSlider : public QSlider { Q_OBJECT Q_PROPERTY(QBrush background READ background WRITE setBackground NOTIFY backgroundChanged) Q_PROPERTY(QGradientStops colors READ colors WRITE setColors DESIGNABLE false) Q_PROPERTY(QColor firstColor READ firstColor WRITE setFirstColor STORED false) Q_PROPERTY(QColor lastColor READ lastColor WRITE setLastColor STORED false) Q_PROPERTY(QLinearGradient gradient READ gradient WRITE setGradient) public: explicit GradientSlider(QWidget *parent = 0); explicit GradientSlider(Qt::Orientation orientation, QWidget *parent = 0); ~GradientSlider(); /// Get the background, it's visible for transparent gradient stops QBrush background() const; /// Set the background, it's visible for transparent gradient stops void setBackground(const QBrush &bg); /// Get the colors that make up the gradient QGradientStops colors() const; /// Set the colors that make up the gradient void setColors(const QGradientStops &colors); /// Get the gradient QLinearGradient gradient() const; /// Set the gradient void setGradient(const QLinearGradient &gradient); /** * Overload: create an evenly distributed gradient of the given colors */ void setColors(const QVector &colors); /** * \brief Set the first color of the gradient * * If the gradient is currently empty it will create a stop with the given color */ void setFirstColor(const QColor &c); /** * \brief Set the last color of the gradient * * If the gradient is has less than two colors, * it will create a stop with the given color */ void setLastColor(const QColor &c); /** * \brief Get the first color * * \returns QColor() con empty gradient */ QColor firstColor() const; /** * \brief Get the last color * * \returns QColor() con empty gradient */ QColor lastColor() const; Q_SIGNALS: void backgroundChanged(const QBrush&); protected: void paintEvent(QPaintEvent *ev) override; void mousePressEvent(QMouseEvent *ev) override; void mouseMoveEvent(QMouseEvent *ev) override; void mouseReleaseEvent(QMouseEvent *ev) override; private: class Private; Private * const p; }; } // namespace color_widgets #endif // GRADIENT_SLIDER_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/harmony_color_wheel.hpp000066400000000000000000000053421366475014400260700ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * \copyright Copyright (C) 2017 caryoscelus * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef HARMONY_COLOR_WHEEL_HPP #define HARMONY_COLOR_WHEEL_HPP #include "color_wheel.hpp" namespace color_widgets { /** * \brief ColorWheel with color harmonies */ class QCP_EXPORT HarmonyColorWheel : public ColorWheel { Q_OBJECT public: explicit HarmonyColorWheel(QWidget *parent = 0); ~HarmonyColorWheel(); /// Get all harmony colors (including main) QList harmonyColors() const; /// Get number of harmony colors (including main) unsigned int harmonyCount() const; /// Clear harmony color scheme void clearHarmonies(); /** * @brief Add harmony color * @param hue_diff Initial hue difference (in [0-1) range) * @param editable Whether this harmony should be editable * @returns Index of newly added harmony */ unsigned addHarmony(double hue_diff, bool editable); /** * @brief Add symmetric harmony color * @param relative_to Index of other harmony that should be symmetric relative to main hue * @returns Index of newly added harmony * Editability is inherited from symmetric editor */ unsigned addSymmetricHarmony(unsigned relative_to); /** * @brief Add opposite harmony color * @param relative_to Index of other harmony that should be opposite to this * @returns Index of newly added harmony * Editability is inherited from opposite editor */ unsigned addOppositeHarmony(unsigned relative_to); Q_SIGNALS: /** * Emitted when harmony settings or harmony colors are changed (including due to main hue change) */ void harmonyChanged(); protected: void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE; private: class Private; Private * p; }; } // namespace color_widgets #endif // COLOR_WHEEL_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/hue_slider.hpp000066400000000000000000000056021366475014400241530ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2014 Calle Laakkonen * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef HUE_SLIDER_HPP #define HUE_SLIDER_HPP #include "gradient_slider.hpp" namespace color_widgets { /** * \brief A slider for selecting a hue value */ class QCP_EXPORT HueSlider : public GradientSlider { Q_OBJECT /** * \brief Saturation used in the rainbow gradient, as a [0-1] float */ Q_PROPERTY(qreal colorSaturation READ colorSaturation WRITE setColorSaturation NOTIFY colorSaturationChanged) /** * \brief Value used in the rainbow gradient, as a [0-1] float */ Q_PROPERTY(qreal colorValue READ colorValue WRITE setColorValue NOTIFY colorValueChanged) /** * \brief Alpha used in the rainbow gradient, as a [0-1] float */ Q_PROPERTY(qreal colorAlpha READ colorAlpha WRITE setColorAlpha NOTIFY colorAlphaChanged) /** * \brief Color with corresponding color* components */ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) /** * \brief Normalized Hue, as indicated from the slider */ Q_PROPERTY(qreal colorHue READ colorHue WRITE setColorHue NOTIFY colorHueChanged) public: explicit HueSlider(QWidget *parent = nullptr); explicit HueSlider(Qt::Orientation orientation, QWidget *parent = nullptr); ~HueSlider(); qreal colorSaturation() const; qreal colorValue() const; qreal colorAlpha() const; QColor color() const; qreal colorHue() const; public Q_SLOTS: void setColorValue(qreal value); void setColorSaturation(qreal value); void setColorAlpha(qreal alpha); void setColorHue(qreal colorHue); /** * \brief Set Hue Saturation and ColorValue, ignoring alpha */ void setColor(const QColor& color); /** * \brief Set Hue Saturation, ColorValue and Alpha */ void setFullColor(const QColor& color); Q_SIGNALS: void colorHueChanged(qreal colorHue); void colorChanged(QColor); void colorAlphaChanged(qreal v); void colorSaturationChanged(qreal v); void colorValueChanged(qreal v); private: class Private; Private * const p; }; } // namespace color_widgets #endif // HUE_SLIDER_HPP Qt-Color-Widgets-v2.2.0/include/QtColorWidgets/swatch.hpp000066400000000000000000000135501366475014400233220ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef COLOR_WIDGETS_SWATCH_HPP #define COLOR_WIDGETS_SWATCH_HPP #include #include #include "color_palette.hpp" namespace color_widgets { /** * \brief A widget drawing a palette */ class QCP_EXPORT Swatch : public QWidget { Q_OBJECT /** * \brief Palette shown by the widget */ Q_PROPERTY(const ColorPalette& palette READ palette WRITE setPalette NOTIFY paletteChanged) /** * \brief Currently selected color (-1 if no color is selected) */ Q_PROPERTY(int selected READ selected WRITE setSelected NOTIFY selectedChanged) /** * \brief Preferred size for a color square */ Q_PROPERTY(QSize colorSize READ colorSize WRITE setColorSize NOTIFY colorSizeChanged) Q_PROPERTY(ColorSizePolicy colorSizePolicy READ colorSizePolicy WRITE setColorSizePolicy NOTIFY colorSizePolicyChanged) /** * \brief Border around the colors */ Q_PROPERTY(QPen border READ border WRITE setBorder NOTIFY borderChanged) /** * \brief Forces the Swatch to display that many rows of colors * * If there are too few elements, the widget will display less than this * many rows. * * A value of0 means that the number of rows is automatic. * * \note Conflicts with forcedColumns */ Q_PROPERTY(int forcedRows READ forcedRows WRITE setForcedRows NOTIFY forcedRowsChanged) /** * \brief Forces the Swatch to display that many columns of colors * * If there are too few elements, the widget will display less than this * many columns. * * A value of 0 means that the number of columns is automatic. * * \note Conflicts with forcedRows */ Q_PROPERTY(int forcedColumns READ forcedColumns WRITE setForcedColumns NOTIFY forcedColumnsChanged) /** * \brief Whether the palette can be modified via user interaction * \note Even when this is \b false, it can still be altered programmatically */ Q_PROPERTY(bool readOnly READ readOnly WRITE setReadOnly NOTIFY readOnlyChanged) public: enum ColorSizePolicy { Hint, ///< The size is just a hint Minimum, ///< Can expand but not contract Fixed ///< Must be exactly as specified }; Q_ENUMS(ColorSizePolicy) Swatch(QWidget* parent = 0); ~Swatch(); QSize sizeHint() const Q_DECL_OVERRIDE; QSize minimumSizeHint() const Q_DECL_OVERRIDE; const ColorPalette& palette() const; ColorPalette& palette(); int selected() const; /** * \brief Color at the currently selected index */ QColor selectedColor() const; /** * \brief Color index at the given position within the widget * \param p Point in local coordinates * \returns -1 if the position doesn't represent any color */ int indexAt(const QPoint& p); /** * \brief Color at the given position within the widget * \param p Point in local coordinates */ QColor colorAt(const QPoint& p); QSize colorSize() const; ColorSizePolicy colorSizePolicy() const; QPen border() const; int forcedRows() const; int forcedColumns() const; bool readOnly() const; public Q_SLOTS: void setPalette(const ColorPalette& palette); void setSelected(int selected); void clearSelection(); void setColorSize(const QSize& colorSize); void setColorSizePolicy(ColorSizePolicy colorSizePolicy); void setBorder(const QPen& border); void setForcedRows(int forcedRows); void setForcedColumns(int forcedColumns); void setReadOnly(bool readOnly); /** * \brief Remove the currently seleceted color **/ void removeSelected(); Q_SIGNALS: void paletteChanged(const ColorPalette& palette); void selectedChanged(int selected); void colorSelected(const QColor& color); void colorSizeChanged(const QSize& colorSize); void colorSizePolicyChanged(ColorSizePolicy colorSizePolicy); void doubleClicked(int index); void rightClicked(int index); void forcedRowsChanged(int forcedRows); void forcedColumnsChanged(int forcedColumns); void readOnlyChanged(bool readOnly); void borderChanged(const QPen& border); protected: bool event(QEvent* event) Q_DECL_OVERRIDE; void paintEvent(QPaintEvent* event) Q_DECL_OVERRIDE; void keyPressEvent(QKeyEvent* event) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void wheelEvent(QWheelEvent* event) Q_DECL_OVERRIDE; void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE; void dragMoveEvent(QDragMoveEvent* event) Q_DECL_OVERRIDE; void dragLeaveEvent(QDragLeaveEvent *event) Q_DECL_OVERRIDE; void dropEvent(QDropEvent* event) Q_DECL_OVERRIDE; protected Q_SLOTS: /** * \brief Connected to the internal palette object to keep eveything consistent */ void paletteModified(); private: class Private; Private* p; }; } // namespace color_widgets #endif // COLOR_WIDGETS_SWATCH_HPP Qt-Color-Widgets-v2.2.0/refactor.sh000077500000000000000000000050611366475014400171250ustar00rootroot00000000000000#!/bin/bash # # Copyright (C) 2013-2020 Mattia Basaglia # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . ################################################################################ # This script is to refactor the old class names to the new ones # # eg: occurrences of Color_Dialog become color_widgets::ColorDialog # # This script does very simple text replacements and overwrites existing files # # Use with care # # Usage: # # ./refactor.sh /path/to/sources # # # ################################################################################ old_classes=( Color_Delegate Color_Dialog Color_List_Widget Color_Preview Color_Selector Color_Wheel Gradient_Slider Hue_Slider ) old_enums=( Button_Mode Display_Mode Update_Mode Display_Enum Display_Flags ) file_extensions=( ui cpp hpp C H h cxx hxx ) function new_class_name() { echo "$1" | sed -e 's/_//g' -r -e 's/^/color_widgets::/' } function new_enum_name() { echo "$1" | sed -e 's/_//g' } directory="$1" if [ -z "$directory" ] then echo "Usage: $0 (directory)" exit 1 fi find_extensions="" for ext in ${file_extensions[@]} do find_extensions="$find_extensions -o -name '*.$ext'" done find_extensions="$(echo "$find_extensions" | sed -r 's/ -o //')" find_command="find \""$directory"\" -type f -a \( $find_extensions \) -print" files="$(bash -c "$find_command")" replacements="" for class in ${old_classes[@]} do replacements="$replacements $class $(new_class_name $class)" done for enum in ${old_enums[@]} do replacements="$replacements $enum $(new_enum_name $enum)" done for file in $files do replace $replacements -- "$file" done Qt-Color-Widgets-v2.2.0/resources/000077500000000000000000000000001366475014400167715ustar00rootroot00000000000000Qt-Color-Widgets-v2.2.0/resources/QtColorWidgets/000077500000000000000000000000001366475014400217035ustar00rootroot00000000000000Qt-Color-Widgets-v2.2.0/resources/QtColorWidgets/CMakeLists.txt000066400000000000000000000004631366475014400244460ustar00rootroot00000000000000set (SOURCES alphaback.png color_widgets.qrc ) file(RELATIVE_PATH PREFIX ${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_LIST_DIR}) foreach (SOURCE IN LISTS SOURCES) target_sources (${TARGET_NAME} PRIVATE $) endforeach (SOURCE IN SOURCES) Qt-Color-Widgets-v2.2.0/resources/QtColorWidgets/alphaback.png000066400000000000000000000020671366475014400243240ustar00rootroot00000000000000‰PNG  IHDRóÿahzTXtRaw profile type exifxÚå–Qvä( EÿµŠY’‚å`lÎéôòçac§’tº«Úùš11`%¡+¹BÛÏþÁ%!FŠæ9•”®Xb‘ŠIÇU÷žCÜûùÎÉ;9] ‘bÔã1§)ß ì—)oSO…Ü•m.,ïêT$y8-NCʇ0SŠT¦åx×÷0à¦ÑEuI–Ø#ú(Á=Ì3‚èˆÛ:Ußí_†>>Ó¹Uà“lÊÐçá¡wÅ­èUÇÖ„9ïrÓ}Ð Žy9ãúûëwžÓéúDþé5ã/ä¤iè¹ ¥kü¥œíMNHwn–Sº,¿“—79:ñõ¾æÞ·ãt5&9ÍCGÙgØ·Œhío%4Çm!`VÐ2J¢çŠ$[ÐêyåÊ·}lÜàb”M£HåFfÀ(ÒtÀ£q×¢«f$@C:(¤rù»ٲ›kœaxåLȆ2Æ+·=³©÷QPÌ!_±‚_22^ rÌÛ@„û ªí>ÛÇkpU´=̬a€1~K.ÝA+6Æ£ŽØ×©!‚gXA $VãÄÁEÈ™È @®‹FY€…Íd…“Uà  `ï8ï[ÅäãC¦‰ÔÁ¦h¬ ùã1#‡ª©E3Kæ–­XMšF…¥äi|Q««G7Oîž½x¥¬9fË){ιäZ¤(¾¸VP%—Rj…Ñ ÍoWl¨u‘E—¸Ø’_òR–Ú„š¶Ø¬¥æ-·Òê*«®¨ã5­¾æµ¬uã ©´ÅͶ´ù–·²ÕŽTëÚc·žº÷Ü õzQ›X?µ¨ñ¤&;©±Ñ/jºŸ*x|Nl01‰ à>°’È`2Ç(ƒÜ`Š *Lठ8+b 7ë|±{#g„Oç·p#€ï GÝä>sûµµî?tºe8‚Õ׬JÆ~0ÿ0Ò ºè³*Ž‘>«Èí5ÇHw¼xéŽNÐ/ ;* ;^<ƒ?¼štÇ‹¯ð‡;ÉIw¼ø_•H¸ŸÝtWÅy º[c¯äÑSDén½Zk$Jwk왽”Wt·Æ¾ŠÑ_g7Ý­±ÇéwüüGJÿvúœÅÚéBbKGD2P°…Í¥ pHYs  šœtIMEä 2ŽÁ=HtEXtCommentCreated with GIMPW+IDAT8ËcLKKûÏ€ã“f`b Œ0 `!ÏgÏž ÄáoI-ìcôIEND®B`‚Qt-Color-Widgets-v2.2.0/resources/QtColorWidgets/color_widgets.qrc000066400000000000000000000001511366475014400252530ustar00rootroot00000000000000 alphaback.png Qt-Color-Widgets-v2.2.0/src/000077500000000000000000000000001366475014400155465ustar00rootroot00000000000000Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/000077500000000000000000000000001366475014400204605ustar00rootroot00000000000000Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/CMakeLists.txt000066400000000000000000000013231366475014400232170ustar00rootroot00000000000000set (SOURCES abstract_widget_list.cpp bound_color_selector.cpp color_2d_slider.cpp color_delegate.cpp color_dialog.cpp color_dialog.ui color_line_edit.cpp color_list_widget.cpp color_names.cpp color_palette.cpp color_palette_model.cpp color_palette_widget.cpp color_palette_widget.ui color_preview.cpp color_selector.cpp color_utils.cpp color_wheel.cpp gradient_slider.cpp hue_slider.cpp swatch.cpp gradient_editor.cpp harmony_color_wheel.cpp gradient_list_model.cpp ) file(RELATIVE_PATH PREFIX ${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_LIST_DIR}) foreach (SOURCE IN LISTS SOURCES) target_sources (${TARGET_NAME} PRIVATE $) endforeach (SOURCE IN SOURCES) Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/abstract_widget_list.cpp000066400000000000000000000113701366475014400253670ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/abstract_widget_list.hpp" #include #include #include #include class AbstractWidgetList::Private { public: QList widgets; QSignalMapper mapper_up; QSignalMapper mapper_down; QSignalMapper mapper_remove; QTableWidget *table; }; AbstractWidgetList::AbstractWidgetList(QWidget *parent) : QWidget(parent), p(new Private) { connect(&p->mapper_up,SIGNAL(mapped(QWidget*)),SLOT(up_clicked(QWidget*))); connect(&p->mapper_down,SIGNAL(mapped(QWidget*)),SLOT(down_clicked(QWidget*))); connect(&p->mapper_remove,SIGNAL(mapped(QWidget*)),SLOT(remove_clicked(QWidget*))); QVBoxLayout *verticalLayout = new QVBoxLayout(this); verticalLayout->setContentsMargins(0, 0, 0, 0); p->table = new QTableWidget(this); verticalLayout->addWidget(p->table); p->table->insertColumn(0); p->table->insertColumn(1); p->table->insertColumn(2); p->table->insertColumn(3); p->table->setColumnWidth(0,128); p->table->setColumnWidth(1,24); p->table->setColumnWidth(2,24); p->table->setColumnWidth(3,24); p->table->horizontalHeader()->hide(); p->table->verticalHeader()->hide(); p->table->setShowGrid(false); QPushButton* add_button = new QPushButton(QIcon::fromTheme(QStringLiteral("list-add")), tr("Add New")); verticalLayout->addWidget(add_button); connect(add_button,&QAbstractButton::clicked,this, &AbstractWidgetList::append); } AbstractWidgetList::~AbstractWidgetList() { delete p; } int AbstractWidgetList::count() const { return p->widgets.size(); } void AbstractWidgetList::setRowHeight(int row, int height) { p->table->setRowHeight(row,height); } void AbstractWidgetList::clear() { p->widgets.clear(); while(p->table->rowCount() > 0) p->table->removeRow(0); } void AbstractWidgetList::remove(int i) { if ( isValidRow(i) ) { p->widgets.removeAt(i); p->table->removeRow(i); if ( i == 0 && !p->widgets.isEmpty() ) p->table->cellWidget(0,1)->setEnabled(false); else if ( i != 0 && i == count() ) p->table->cellWidget(count()-1,2)->setEnabled(false); Q_EMIT removed(i); } } void AbstractWidgetList::appendWidget(QWidget *w) { int row = count(); p->table->insertRow(row); QWidget* b_up = create_button(w,&p->mapper_up,QStringLiteral("go-up"),tr("Move Up")); QWidget* b_down = create_button(w,&p->mapper_down,QStringLiteral("go-down"),tr("Move Down")); QWidget* b_remove = create_button(w,&p->mapper_remove,QStringLiteral("list-remove"),tr("Remove")); if ( row == 0 ) b_up->setEnabled(false); else p->table->cellWidget(row-1,2)->setEnabled(true); b_down->setEnabled(false); p->table->setCellWidget(row,0,w); p->table->setCellWidget(row,1,b_up); p->table->setCellWidget(row,2,b_down); p->table->setCellWidget(row,3,b_remove); p->widgets.push_back(w); } QWidget *AbstractWidgetList::widget(int i) { if ( isValidRow(i) ) return p->widgets[i]; return 0; } QWidget *AbstractWidgetList::create_button(QWidget *data, QSignalMapper *mapper, QString icon_name, QString text, QString tooltip) const { QToolButton* btn = new QToolButton; btn->setIcon(QIcon::fromTheme(icon_name)); btn->setText(text); btn->setToolTip(tooltip.isNull() ? btn->text() : tooltip ); connect(btn,SIGNAL(clicked()),mapper,SLOT(map())); mapper->setMapping(btn,data); return btn; } void AbstractWidgetList::remove_clicked(QWidget *w) { int row = p->widgets.indexOf(w); remove(row); } void AbstractWidgetList::up_clicked(QWidget *w) { int row = p->widgets.indexOf(w); if ( row > 0 ) swap(row,row-1); } void AbstractWidgetList::down_clicked(QWidget *w) { int row = p->widgets.indexOf(w); if ( row+1 < count() ) swap(row,row+1); } Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/bound_color_selector.cpp000066400000000000000000000022551366475014400253750ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/bound_color_selector.hpp" namespace color_widgets { BoundColorSelector::BoundColorSelector(QColor* reference, QWidget *parent) : ColorSelector(parent), ref(reference) { setColor(*reference); connect(this,&ColorPreview::colorChanged,this, &BoundColorSelector::update_reference); } void BoundColorSelector::update_reference(QColor c) { *ref = c; } } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/color_2d_slider.cpp000066400000000000000000000142611366475014400242350ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/color_2d_slider.hpp" #include "QtColorWidgets/color_utils.hpp" #include #include #include #include namespace color_widgets { static const double selector_radius = 6; class Color2DSlider::Private { public: qreal hue = 1, sat = 1, val = 1; Component comp_x = Saturation; Component comp_y = Value; QImage square; qreal PixHue(float x, float y) { if ( comp_x == Hue ) return x; if ( comp_y == Hue ) return y; return hue; } qreal PixSat(float x, float y) { if ( comp_x == Saturation ) return x; if ( comp_y == Saturation ) return y; return sat; } qreal PixVal(float x, float y) { if ( comp_x == Value ) return x; if ( comp_y == Value ) return y; return val; } void renderSquare(const QSize& size) { square = QImage(size, QImage::Format_RGB32); for ( int y = 0; y < size.height(); ++y ) { qreal yfloat = 1 - qreal(y) / size.height(); for ( int x = 0; x < size.width(); ++x ) { qreal xfloat = qreal(x) / size.width(); square.setPixel( x, y, QColor::fromHsvF( PixHue(xfloat, yfloat), PixSat(xfloat, yfloat), PixVal(xfloat, yfloat) ).rgb()); } } } QPointF selectorPos(const QSize& size) { QPointF pt; switch ( comp_x ) { case Hue: pt.setX(size.width()*hue); break; case Saturation:pt.setX(size.width()*sat); break; case Value: pt.setX(size.width()*val); break; } switch ( comp_y ) { case Hue: pt.setY(size.height()*(1-hue)); break; case Saturation:pt.setY(size.height()*(1-sat)); break; case Value: pt.setY(size.height()*(1-val)); break; } return pt; } void setColorFromPos(const QPoint& pt, const QSize& size) { QPointF ptfloat( qBound(0.0, qreal(pt.x()) / size.width(), 1.0), qBound(0.0, 1 - qreal(pt.y()) / size.height(), 1.0) ); switch ( comp_x ) { case Hue: hue = ptfloat.x(); break; case Saturation:sat = ptfloat.x(); break; case Value: val = ptfloat.x(); break; } switch ( comp_y ) { case Hue: hue = ptfloat.y(); break; case Saturation:sat = ptfloat.y(); break; case Value: val = ptfloat.y(); break; } } }; Color2DSlider::Color2DSlider(QWidget* parent) : QWidget(parent), p(new Private) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); } Color2DSlider::~Color2DSlider() { delete p; } QColor Color2DSlider::color() const { return QColor::fromHsvF(p->hue, p->sat, p->val); } QSize Color2DSlider::sizeHint() const { return {128, 128}; } qreal Color2DSlider::hue() const { return p->hue; } qreal Color2DSlider::saturation() const { return p->sat; } qreal Color2DSlider::value() const { return p->val; } Color2DSlider::Component Color2DSlider::componentX() const { return p->comp_x; } Color2DSlider::Component Color2DSlider::componentY() const { return p->comp_y; } void Color2DSlider::setColor(const QColor& c) { p->hue = c.hsvHueF(); p->sat = c.saturationF(); p->val = c.valueF(); p->renderSquare(size()); update(); Q_EMIT colorChanged(color()); } void Color2DSlider::setHue(qreal h) { p->hue = h; p->renderSquare(size()); update(); Q_EMIT colorChanged(color()); } void Color2DSlider::setSaturation(qreal s) { p->sat = s; p->renderSquare(size()); update(); Q_EMIT colorChanged(color()); } void Color2DSlider::setValue(qreal v) { p->val = v; p->renderSquare(size()); update(); Q_EMIT colorChanged(color()); } void Color2DSlider::setComponentX(Color2DSlider::Component componentX) { if ( componentX != p->comp_x ) { p->comp_x = componentX; p->renderSquare(size()); update(); Q_EMIT componentXChanged(p->comp_x); } } void Color2DSlider::setComponentY(Color2DSlider::Component componentY) { if ( componentY != p->comp_y ) { p->comp_y = componentY; p->renderSquare(size()); update(); Q_EMIT componentXChanged(p->comp_y); } } void Color2DSlider::paintEvent(QPaintEvent*) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.drawImage(0,0,p->square); painter.setPen(QPen(p->val > 0.5 ? Qt::black : Qt::white, 3)); painter.setBrush(Qt::NoBrush); painter.drawEllipse(p->selectorPos(size()), selector_radius, selector_radius); } void Color2DSlider::mousePressEvent(QMouseEvent* event) { p->setColorFromPos(event->pos(), size()); Q_EMIT colorChanged(color()); update(); } void Color2DSlider::mouseMoveEvent(QMouseEvent* event) { p->setColorFromPos(event->pos(), size()); Q_EMIT colorChanged(color()); update(); } void Color2DSlider::mouseReleaseEvent(QMouseEvent* event) { p->setColorFromPos(event->pos(), size()); Q_EMIT colorChanged(color()); update(); } void Color2DSlider::resizeEvent(QResizeEvent* event) { p->renderSquare(event->size()); update(); } } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/color_delegate.cpp000066400000000000000000000063121366475014400241360ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/color_delegate.hpp" #include "QtColorWidgets/color_selector.hpp" #include "QtColorWidgets/color_dialog.hpp" #include #include namespace color_widgets { ColorDelegate::ColorDelegate(QWidget *parent) : QAbstractItemDelegate(parent) { } void ColorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (index.data().canConvert()) { QStyleOptionFrame panel; panel.initFrom(option.widget); if (option.widget->isEnabled()) panel.state = QStyle::State_Enabled; panel.rect = option.rect; panel.lineWidth = 2; panel.midLineWidth = 0; panel.state |= QStyle::State_Sunken; option.widget->style()->drawPrimitive(QStyle::PE_Frame, &panel, painter, nullptr); QRect r = option.widget->style()->subElementRect(QStyle::SE_FrameContents, &panel, nullptr); painter->setClipRect(r); painter->fillRect(option.rect, index.data().value()); } } bool ColorDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index) { if ( event->type() == QEvent::MouseButtonRelease && index.data().canConvert()) { QMouseEvent* mouse_event = static_cast(event); if ( mouse_event->button() == Qt::LeftButton && ( index.flags() & Qt::ItemIsEditable) ) { ColorDialog *editor = new ColorDialog(const_cast(option.widget)); connect(this, &QObject::destroyed, editor, &QObject::deleteLater); editor->setMinimumSize(editor->sizeHint()); auto original_color = index.data().value(); editor->setColor(original_color); auto set_color = [model, index](const QColor& color){ model->setData(index, QVariant(color)); }; connect(editor, &ColorDialog::colorSelected, this, set_color); editor->show(); } return true; } return QAbstractItemDelegate::editorEvent(event, model, option, index); } QSize ColorDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(index) Q_UNUSED(option) return QSize(24,16); } } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/color_dialog.cpp000066400000000000000000000242201366475014400236210ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * \copyright Copyright (C) 2014 Calle Laakkonen * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/color_dialog.hpp" #include "ui_color_dialog.h" #include #include #include #include #include #include namespace color_widgets { class ColorDialog::Private { public: Ui_ColorDialog ui; ButtonMode button_mode; bool pick_from_screen; bool alpha_enabled; QColor color; Private() : pick_from_screen(false), alpha_enabled(true) {} }; ColorDialog::ColorDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f), p(new Private) { p->ui.setupUi(this); setAcceptDrops(true); // Add "pick color" button QPushButton *pickButton = p->ui.buttonBox->addButton(tr("Pick"), QDialogButtonBox::ActionRole); pickButton->setIcon(QIcon::fromTheme(QStringLiteral("color-picker"))); setButtonMode(OkApplyCancel); connect(p->ui.wheel, &ColorWheel::colorSpaceChanged, this, &ColorDialog::colorSpaceChanged); connect(p->ui.wheel, &ColorWheel::selectorShapeChanged, this, &ColorDialog::wheelShapeChanged); connect(p->ui.wheel, &ColorWheel::rotatingSelectorChanged, this, &ColorDialog::wheelRotatingChanged); } ColorDialog::~ColorDialog() { delete p; } QSize ColorDialog::sizeHint() const { return QSize(400,0); } QColor ColorDialog::color() const { QColor col = p->color; if ( !p->alpha_enabled ) col.setAlpha(255); return col; } void ColorDialog::setColor(const QColor &c) { p->ui.preview->setComparisonColor(c); p->ui.edit_hex->setModified(false); setColorInternal(c); } void ColorDialog::showColor(const QColor &c) { setColor(c); show(); } void ColorDialog::setPreviewDisplayMode(ColorPreview::DisplayMode mode) { p->ui.preview->setDisplayMode(mode); } ColorPreview::DisplayMode ColorDialog::previewDisplayMode() const { return p->ui.preview->displayMode(); } void ColorDialog::setAlphaEnabled(bool a) { if ( a != p->alpha_enabled ) { p->alpha_enabled = a; p->ui.edit_hex->setShowAlpha(a); p->ui.line_alpha->setVisible(a); p->ui.label_alpha->setVisible(a); p->ui.slide_alpha->setVisible(a); p->ui.spin_alpha->setVisible(a); Q_EMIT alphaEnabledChanged(a); } } bool ColorDialog::alphaEnabled() const { return p->alpha_enabled; } void ColorDialog::setButtonMode(ButtonMode mode) { p->button_mode = mode; QDialogButtonBox::StandardButtons btns; switch(mode) { case OkCancel: btns = QDialogButtonBox::Ok | QDialogButtonBox::Cancel; break; case OkApplyCancel: btns = QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Apply | QDialogButtonBox::Reset; break; case Close: btns = QDialogButtonBox::Close; } p->ui.buttonBox->setStandardButtons(btns); } ColorDialog::ButtonMode ColorDialog::buttonMode() const { return p->button_mode; } void ColorDialog::setColorInternal(const QColor &col) { /** * \note Unlike setColor, this is used to update the current color which * migth differ from the final selected color */ p->ui.wheel->setColor(col); p->color = col; bool blocked = signalsBlocked(); blockSignals(true); Q_FOREACH(QWidget* w, findChildren()) w->blockSignals(true); p->ui.slide_red->setValue(col.red()); p->ui.spin_red->setValue(p->ui.slide_red->value()); p->ui.slide_red->setFirstColor(QColor(0,col.green(),col.blue())); p->ui.slide_red->setLastColor(QColor(255,col.green(),col.blue())); p->ui.slide_green->setValue(col.green()); p->ui.spin_green->setValue(p->ui.slide_green->value()); p->ui.slide_green->setFirstColor(QColor(col.red(),0,col.blue())); p->ui.slide_green->setLastColor(QColor(col.red(),255,col.blue())); p->ui.slide_blue->setValue(col.blue()); p->ui.spin_blue->setValue(p->ui.slide_blue->value()); p->ui.slide_blue->setFirstColor(QColor(col.red(),col.green(),0)); p->ui.slide_blue->setLastColor(QColor(col.red(),col.green(),255)); p->ui.slide_hue->setValue(qRound(p->ui.wheel->hue()*360.0)); p->ui.slide_hue->setColorSaturation(p->ui.wheel->saturation()); p->ui.slide_hue->setColorValue(p->ui.wheel->value()); p->ui.spin_hue->setValue(p->ui.slide_hue->value()); p->ui.slide_saturation->setValue(qRound(p->ui.wheel->saturation()*255.0)); p->ui.spin_saturation->setValue(p->ui.slide_saturation->value()); p->ui.slide_saturation->setFirstColor(QColor::fromHsvF(p->ui.wheel->hue(),0,p->ui.wheel->value())); p->ui.slide_saturation->setLastColor(QColor::fromHsvF(p->ui.wheel->hue(),1,p->ui.wheel->value())); p->ui.slide_value->setValue(qRound(p->ui.wheel->value()*255.0)); p->ui.spin_value->setValue(p->ui.slide_value->value()); p->ui.slide_value->setFirstColor(QColor::fromHsvF(p->ui.wheel->hue(), p->ui.wheel->saturation(),0)); p->ui.slide_value->setLastColor(QColor::fromHsvF(p->ui.wheel->hue(), p->ui.wheel->saturation(),1)); QColor apha_color = col; apha_color.setAlpha(0); p->ui.slide_alpha->setFirstColor(apha_color); apha_color.setAlpha(255); p->ui.slide_alpha->setLastColor(apha_color); p->ui.spin_alpha->setValue(col.alpha()); p->ui.slide_alpha->setValue(col.alpha()); if ( !p->ui.edit_hex->isModified() ) p->ui.edit_hex->setColor(col); p->ui.preview->setColor(col); blockSignals(blocked); Q_FOREACH(QWidget* w, findChildren()) w->blockSignals(false); Q_EMIT colorChanged(col); } void ColorDialog::set_hsv() { if ( !signalsBlocked() ) { QColor col = QColor::fromHsv( p->ui.slide_hue->value(), p->ui.slide_saturation->value(), p->ui.slide_value->value(), p->ui.slide_alpha->value() ); p->ui.wheel->setColor(col); setColorInternal(col); } } void ColorDialog::set_alpha() { if ( !signalsBlocked() ) { QColor col = p->color; col.setAlpha(p->ui.slide_alpha->value()); setColorInternal(col); } } void ColorDialog::set_rgb() { if ( !signalsBlocked() ) { QColor col( p->ui.slide_red->value(), p->ui.slide_green->value(), p->ui.slide_blue->value(), p->ui.slide_alpha->value() ); if (col.saturation() == 0) col = QColor::fromHsv(p->ui.slide_hue->value(), 0, col.value()); p->ui.wheel->setColor(col); setColorInternal(col); } } void ColorDialog::on_edit_hex_colorChanged(const QColor& color) { setColorInternal(color); } void ColorDialog::on_edit_hex_colorEditingFinished(const QColor& color) { p->ui.edit_hex->setModified(false); setColorInternal(color); } void ColorDialog::on_buttonBox_clicked(QAbstractButton *btn) { QDialogButtonBox::ButtonRole role = p->ui.buttonBox->buttonRole(btn); switch(role) { case QDialogButtonBox::AcceptRole: case QDialogButtonBox::ApplyRole: // Explicitly select the color p->ui.preview->setComparisonColor(color()); Q_EMIT colorSelected(color()); break; case QDialogButtonBox::ActionRole: // Currently, the only action button is the "pick color" button grabMouse(Qt::CrossCursor); p->pick_from_screen = true; break; case QDialogButtonBox::ResetRole: // Restore old color setColorInternal(p->ui.preview->comparisonColor()); break; default: break; } } void ColorDialog::dragEnterEvent(QDragEnterEvent *event) { if ( event->mimeData()->hasColor() || ( event->mimeData()->hasText() && QColor(event->mimeData()->text()).isValid() ) ) event->acceptProposedAction(); } void ColorDialog::dropEvent(QDropEvent *event) { if ( event->mimeData()->hasColor() ) { setColorInternal(event->mimeData()->colorData().value()); event->accept(); } else if ( event->mimeData()->hasText() ) { QColor col(event->mimeData()->text()); if ( col.isValid() ) { setColorInternal(col); event->accept(); } } } static QColor get_screen_color(const QPoint &global_pos) { int screenNum = QApplication::desktop()->screenNumber(global_pos); QScreen *screen = QApplication::screens().at(screenNum); WId wid = QApplication::desktop()->winId(); QImage img = screen->grabWindow(wid, global_pos.x(), global_pos.y(), 1, 1).toImage(); return img.pixel(0,0); } void ColorDialog::mouseReleaseEvent(QMouseEvent *event) { if (p->pick_from_screen) { setColorInternal(get_screen_color(event->globalPos())); p->pick_from_screen = false; releaseMouse(); } } void ColorDialog::mouseMoveEvent(QMouseEvent *event) { if (p->pick_from_screen) { setColorInternal(get_screen_color(event->globalPos())); } } void ColorDialog::setWheelShape(ColorWheel::ShapeEnum shape) { p->ui.wheel->setSelectorShape(shape); } ColorWheel::ShapeEnum ColorDialog::wheelShape() const { return p->ui.wheel->selectorShape(); } void ColorDialog::setColorSpace(ColorWheel::ColorSpaceEnum space) { p->ui.wheel->setColorSpace(space); } ColorWheel::ColorSpaceEnum ColorDialog::colorSpace() const { return p->ui.wheel->colorSpace(); } void ColorDialog::setWheelRotating(bool rotating) { p->ui.wheel->setRotatingSelector(rotating); } bool ColorDialog::wheelRotating() const { return p->ui.wheel->rotatingSelector(); } } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/color_dialog.ui000066400000000000000000000422361366475014400234630ustar00rootroot00000000000000 ColorDialog 0 0 491 380 Select Color 0 0 color_widgets::ColorPreview::SplitColor 255 Qt::Horizontal Saturation Hue 255 Qt::Horizontal Hex Blue 255 Qt::Horizontal 255 Qt::Horizontal 255 Qt::Horizontal Value Green Alpha Red 255 Qt::Horizontal true 359 255 255 255 255 255 255 Qt::Horizontal Qt::Horizontal Qt::Horizontal 0 359 Monospace true QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset color_widgets::ColorPreview QWidget

QtColorWidgets/color_preview.hpp
1 color_widgets::ColorWheel QWidget
QtColorWidgets/color_wheel.hpp
1 colorSelected(QColor) setColor(QColor)
color_widgets::GradientSlider QSlider
QtColorWidgets/gradient_slider.hpp
color_widgets::HueSlider color_widgets::GradientSlider
QtColorWidgets/hue_slider.hpp
color_widgets::ColorLineEdit QLineEdit
QtColorWidgets/color_line_edit.hpp
slide_saturation valueChanged(int) ColorDialog set_hsv() 416 71 537 54 slide_value valueChanged(int) ColorDialog set_hsv() 416 109 537 88 slide_red valueChanged(int) ColorDialog set_rgb() 416 156 557 142 slide_green valueChanged(int) ColorDialog set_rgb() 416 194 538 166 slide_blue valueChanged(int) ColorDialog set_rgb() 416 232 537 205 slide_alpha valueChanged(int) ColorDialog set_alpha() 416 279 531 251 wheel colorSelected(QColor) ColorDialog setColorInternal(QColor) 175 101 568 106 slide_saturation valueChanged(int) spin_saturation setValue(int) 416 71 480 62 spin_saturation valueChanged(int) slide_saturation setValue(int) 461 55 416 71 slide_value valueChanged(int) spin_value setValue(int) 416 109 480 91 spin_value valueChanged(int) slide_value setValue(int) 480 91 416 109 slide_red valueChanged(int) spin_red setValue(int) 416 156 482 162 spin_red valueChanged(int) slide_red setValue(int) 482 162 416 156 slide_green valueChanged(int) spin_green setValue(int) 416 194 482 200 spin_green valueChanged(int) slide_green setValue(int) 482 200 416 194 slide_alpha valueChanged(int) spin_alpha setValue(int) 416 279 482 285 spin_alpha valueChanged(int) slide_alpha setValue(int) 482 285 416 279 slide_blue valueChanged(int) spin_blue setValue(int) 416 232 482 238 spin_blue valueChanged(int) slide_blue setValue(int) 482 238 416 232 slide_hue valueChanged(int) spin_hue setValue(int) 405 20 462 26 spin_hue valueChanged(int) slide_hue setValue(int) 448 18 388 24 slide_hue valueChanged(int) ColorDialog set_hsv() 361 17 363 8 buttonBox accepted() ColorDialog accept() 250 373 430 267 buttonBox rejected() ColorDialog reject() 183 373 294 323 colorChanged(QColor) set_rgb() set_hsv() setColor(QColor) setColorInternal(QColor) set_alpha() Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/color_line_edit.cpp000066400000000000000000000130371366475014400243220ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * \copyright Copyright (C) 2017 caryoscelus * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/color_line_edit.hpp" #include #include #include #include #include #include #include "QtColorWidgets/color_utils.hpp" #include "QtColorWidgets/color_names.hpp" namespace color_widgets { class ColorLineEdit::Private { public: QColor color; bool show_alpha = false; bool preview_color = false; QBrush background; bool customAlpha() { return preview_color && show_alpha && color.alpha() < 255; } void setPalette(const QColor& color, ColorLineEdit* parent) { if ( preview_color ) { QColor bg = customAlpha() ? Qt::transparent : color; QColor text = detail::color_lumaF(color) > 0.5 || color.alphaF() < 0.2 ? Qt::black : Qt::white; parent->setStyleSheet( QString("background-color: %1; color: %2;") .arg(bg.name()).arg(text.name()) ); } } }; ColorLineEdit::ColorLineEdit(QWidget* parent) : QLineEdit(parent), p(new Private) { p->background.setTexture(QPixmap(QStringLiteral(":/color_widgets/alphaback.png"))); setColor(Qt::white); /// \todo determine if having this connection might be useful /*connect(this, &QLineEdit::textChanged, [this](const QString& text){ QColor color = p->colorFromString(text); if ( color.isValid() ) Q_EMIT colorChanged(color); });*/ connect(this, &QLineEdit::textEdited, [this](const QString& text){ QColor color = color_widgets::colorFromString(text, p->show_alpha); if ( color.isValid() ) { p->color = color; p->setPalette(color, this); Q_EMIT colorEdited(color); Q_EMIT colorChanged(color); } }); connect(this, &QLineEdit::editingFinished, [this](){ QColor color = color_widgets::colorFromString(text(), p->show_alpha); if ( color.isValid() ) { p->color = color; Q_EMIT colorEditingFinished(color); Q_EMIT colorChanged(color); } else { setText(color_widgets::stringFromColor(p->color, p->show_alpha)); Q_EMIT colorEditingFinished(p->color); Q_EMIT colorChanged(color); } p->setPalette(p->color, this); }); } ColorLineEdit::~ColorLineEdit() { delete p; } QColor ColorLineEdit::color() const { return p->color; } void ColorLineEdit::setColor(const QColor& color) { if ( color != p->color ) { p->color = color; p->setPalette(p->color, this); setText(color_widgets::stringFromColor(p->color, p->show_alpha)); Q_EMIT colorChanged(p->color); } } void ColorLineEdit::setShowAlpha(bool showAlpha) { if ( p->show_alpha != showAlpha ) { p->show_alpha = showAlpha; p->setPalette(p->color, this); setText(color_widgets::stringFromColor(p->color, p->show_alpha)); Q_EMIT showAlphaChanged(p->show_alpha); } } bool ColorLineEdit::showAlpha() const { return p->show_alpha; } void ColorLineEdit::dragEnterEvent(QDragEnterEvent *event) { if ( isReadOnly() ) return; if ( event->mimeData()->hasColor() || ( event->mimeData()->hasText() && color_widgets::colorFromString(event->mimeData()->text(), p->show_alpha).isValid() ) ) { event->acceptProposedAction(); } } void ColorLineEdit::dropEvent(QDropEvent *event) { if ( isReadOnly() ) return; if ( event->mimeData()->hasColor() ) { setColor(event->mimeData()->colorData().value()); event->accept(); } else if ( event->mimeData()->hasText() ) { QColor col = color_widgets::colorFromString(event->mimeData()->text(), p->show_alpha); if ( col.isValid() ) { setColor(col); event->accept(); } } } bool ColorLineEdit::previewColor() const { return p->preview_color; } void ColorLineEdit::setPreviewColor(bool previewColor) { if ( previewColor != p->preview_color ) { p->preview_color = previewColor; if ( p->preview_color ) p->setPalette(p->color, this); else setPalette(QApplication::palette()); Q_EMIT previewColorChanged(p->preview_color); } } void ColorLineEdit::paintEvent(QPaintEvent* event) { if ( p->customAlpha() ) { QPainter painter(this); QStyleOptionFrame panel; initStyleOption(&panel); QRect r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, nullptr); painter.fillRect(r, p->background); painter.fillRect(r, p->color); } QLineEdit::paintEvent(event); } } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/color_list_widget.cpp000066400000000000000000000077221366475014400247100ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/color_list_widget.hpp" #include "QtColorWidgets/color_selector.hpp" namespace color_widgets { class ColorListWidget::Private { public: QList colors; QSignalMapper mapper; ColorWheel::ShapeEnum wheel_shape = ColorWheel::ShapeTriangle; ColorWheel::ColorSpaceEnum color_space = ColorWheel::ColorHSV; bool wheel_rotating = true; }; ColorListWidget::ColorListWidget(QWidget *parent) : AbstractWidgetList(parent), p(new Private) { connect(this, &AbstractWidgetList::removed, this, &ColorListWidget::handle_removed); connect(&p->mapper, SIGNAL(mapped(int)), SLOT(color_changed(int))); } ColorListWidget::~ColorListWidget() { delete p; } QList ColorListWidget::colors() const { return p->colors; } void ColorListWidget::setColors(const QList &colors) { clear(); p->colors = colors; for(int i = 0;i < colors.size();i++ ) append_widget(i); Q_EMIT colorsChanged(colors); } void ColorListWidget::swap(int a, int b) { ColorSelector* sa = widget_cast(a); ColorSelector* sb = widget_cast(b); if ( sa && sb ) { QColor ca = sa->color(); sa->setColor(sb->color()); sb->setColor(ca); Q_EMIT colorsChanged(p->colors); } } void ColorListWidget::append() { p->colors.push_back(Qt::black); append_widget(p->colors.size()-1); Q_EMIT colorsChanged(p->colors); } void ColorListWidget::emit_changed() { Q_EMIT colorsChanged(p->colors); } void ColorListWidget::handle_removed(int i) { p->colors.removeAt(i); Q_EMIT colorsChanged(p->colors); } void ColorListWidget::color_changed(int row) { ColorSelector *cs = widget_cast(row); if ( cs ) { p->colors[row] = cs->color(); Q_EMIT colorsChanged(p->colors); } } void ColorListWidget::append_widget(int col) { ColorSelector* cbs = new ColorSelector; cbs->setDisplayMode(ColorPreview::AllAlpha); cbs->setColor(p->colors[col]); //connect(cbs,SIGNAL(colorChanged(QColor)),SLOT(emit_changed())); p->mapper.setMapping(cbs,col); connect(cbs,SIGNAL(colorChanged(QColor)),&p->mapper,SLOT(map())); connect(this, &ColorListWidget::wheelRotatingChanged, cbs, &ColorSelector::setWheelRotating); connect(this, &ColorListWidget::wheelShapeChanged, cbs, &ColorSelector::setWheelShape); connect(this, &ColorListWidget::colorSpaceChanged, cbs, &ColorSelector::setColorSpace); appendWidget(cbs); setRowHeight(count()-1,22); } void ColorListWidget::setWheelShape(ColorWheel::ShapeEnum shape) { Q_EMIT wheelShapeChanged(p->wheel_shape = shape); } ColorWheel::ShapeEnum ColorListWidget::wheelShape() const { return p->wheel_shape; } void ColorListWidget::setColorSpace(ColorWheel::ColorSpaceEnum space) { Q_EMIT colorSpaceChanged(p->color_space = space); } ColorWheel::ColorSpaceEnum ColorListWidget::colorSpace() const { return p->color_space; } void ColorListWidget::setWheelRotating(bool rotating) { Q_EMIT wheelRotatingChanged(p->wheel_rotating = rotating); } bool ColorListWidget::wheelRotating() const { return p->wheel_rotating; } } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/color_names.cpp000066400000000000000000000052671366475014400234770ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/color_names.hpp" #include static QRegularExpression regex_qcolor (QStringLiteral("^(?:(?:#[[:xdigit:]]{3})|(?:#[[:xdigit:]]{6})|(?:[[:alpha:]]+))$")); static QRegularExpression regex_func_rgb (QStringLiteral(R"(^rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)$)")); static QRegularExpression regex_hex_rgba (QStringLiteral("^#[[:xdigit:]]{8}$")); 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*\)$)")); namespace color_widgets { QString stringFromColor(const QColor& color, bool alpha) { if ( !alpha || color.alpha() == 255 ) return color.name(); return color.name()+QStringLiteral("%1").arg(color.alpha(), 2, 16, QChar('0')); } QColor colorFromString(const QString& string, bool alpha) { QString xs = string.trimmed(); QRegularExpressionMatch match; match = regex_qcolor.match(xs); if ( match.hasMatch() ) { return QColor(xs); } match = regex_func_rgb.match(xs); if ( match.hasMatch() ) { return QColor( match.captured(1).toInt(), match.captured(2).toInt(), match.captured(3).toInt() ); } if ( alpha ) { match = regex_hex_rgba.match(xs); if ( match.hasMatch() ) { return QColor( xs.mid(1,2).toInt(nullptr,16), xs.mid(3,2).toInt(nullptr,16), xs.mid(5,2).toInt(nullptr,16), xs.mid(7,2).toInt(nullptr,16) ); } match = regex_func_rgba.match(xs); if ( match.hasMatch() ) { return QColor( match.captured(1).toInt(), match.captured(2).toInt(), match.captured(3).toInt(), match.captured(4).toInt() ); } } return QColor(); } } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/color_palette.cpp000066400000000000000000000262031366475014400240230ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/color_palette.hpp" #include #include #include #include #include #include namespace color_widgets { class ColorPalette::Private { public: QVector > colors; int columns; QString name; QString fileName; bool dirty; bool valid_index(int index) { return index >= 0 && index < colors.size(); } }; ColorPalette::ColorPalette(const QVector& colors, const QString& name, int columns) : p ( new Private ) { setName(name); setColumns(columns); setColors(colors); } ColorPalette::ColorPalette(const QString& name) : p ( new Private ) { setName(name); p->columns = 0; p->dirty = false; } ColorPalette::ColorPalette(const QVector >& colors, const QString& name, int columns) { setName(name); setColumns(columns); setColors(colors); p->dirty = false; } ColorPalette::ColorPalette(const ColorPalette& other) : QObject(), p ( new Private(*other.p) ) { } ColorPalette& ColorPalette::operator=(const ColorPalette& other) { *p = *other.p; emitUpdate(); return *this; } ColorPalette::~ColorPalette() { delete p; } ColorPalette::ColorPalette(ColorPalette&& other) : QObject(), p ( other.p ) { other.p = nullptr; } ColorPalette& ColorPalette::operator=(ColorPalette&& other) { std::swap(p, other.p); emitUpdate(); return *this; } void ColorPalette::emitUpdate() { Q_EMIT colorsChanged(p->colors); Q_EMIT columnsChanged(p->columns); Q_EMIT nameChanged(p->name); Q_EMIT fileNameChanged(p->fileName); Q_EMIT dirtyChanged(p->dirty); } QColor ColorPalette::colorAt(int index) const { return p->valid_index(index) ? p->colors[index].first : QColor(); } QString ColorPalette::nameAt(int index) const { return p->valid_index(index) ? p->colors[index].second : QString(); } QVector > ColorPalette::colors() const { return p->colors; } int ColorPalette::count() const { return p->colors.size(); } int ColorPalette::columns() { return p->columns; } QString ColorPalette::name() const { return p->name; } void ColorPalette::loadColorTable(const QVector& color_table) { p->colors.clear(); p->colors.reserve(color_table.size()); for ( QRgb c : color_table ) { QColor color ( c ); color.setAlpha(255); p->colors.push_back(qMakePair(color,QString())); } Q_EMIT colorsChanged(p->colors); setDirty(true); } bool ColorPalette::loadImage(const QImage& image) { if ( image.isNull() ) return false; setColumns(image.width()); p->colors.clear(); p->colors.reserve(image.width()*image.height()); for ( int y = 0; y < image.height(); y++ ) { for ( int x = 0; x < image.width(); x++ ) { QColor color ( image.pixel(x, y) ); color.setAlpha(255); p->colors.push_back(qMakePair(color,QString())); } } Q_EMIT colorsChanged(p->colors); setDirty(true); return true; } ColorPalette ColorPalette::fromImage(const QImage& image) { ColorPalette p; p.loadImage(image); return p; } bool ColorPalette::load(const QString& name) { p->fileName = name; p->colors.clear(); p->columns = 0; p->dirty = false; p->name = QFileInfo(name).baseName(); QFile file(name); if ( !file.open(QFile::ReadOnly|QFile::Text) ) { emitUpdate(); return false; } QTextStream stream( &file ); if ( stream.readLine() != QLatin1String("GIMP Palette") ) { emitUpdate(); return false; } QString line; // parse properties QHash properties; while( !stream.atEnd() ) { line = stream.readLine(); if ( line.isEmpty() ) continue; if ( line[0] == '#' ) break; int colon = line.indexOf(':'); if ( colon == -1 ) break; properties[line.left(colon).toLower()] = line.right(line.size() - colon - 1).trimmed(); } /// \todo Store extra properties in the palette object setName(properties[QStringLiteral("name")]); setColumns(properties[QStringLiteral("columns")].toInt()); // Skip comments if ( !stream.atEnd() && line[0] == '#' ) while( !stream.atEnd() ) { qint64 pos = stream.pos(); line = stream.readLine(); if ( !line.isEmpty() && line[0] != '#' ) { stream.seek(pos); break; } } while( !stream.atEnd() ) { int r = 0, g = 0, b = 0; stream >> r >> g >> b; line = stream.readLine().trimmed(); p->colors.push_back(qMakePair(QColor(r, g, b), line)); } Q_EMIT colorsChanged(p->colors); setDirty(false); return true; } ColorPalette ColorPalette::fromFile(const QString& name) { ColorPalette p; p.load(name); return p; } bool ColorPalette::save(const QString& filename) { setFileName(filename); return save(); } bool ColorPalette::save() { QString filename = p->fileName; if ( filename.isEmpty() ) { filename = unnamed(p->name)+".gpl"; } QFile file(filename); if ( !file.open(QFile::Text|QFile::WriteOnly) ) return false; QTextStream stream(&file); stream << "GIMP Palette\n"; stream << "Name: " << unnamed(p->name) << '\n'; if ( p->columns ) stream << "Columns: " << p->columns << '\n'; /// \todo Options to add comments stream << "#\n"; for ( int i = 0; i < p->colors.size(); i++ ) { stream << qSetFieldWidth(3) << p->colors[i].first.red() << qSetFieldWidth(0) << ' ' << qSetFieldWidth(3) << p->colors[i].first.green() << qSetFieldWidth(0) << ' ' << qSetFieldWidth(3) << p->colors[i].first.blue() << qSetFieldWidth(0) << '\t' << unnamed(p->colors[i].second) << '\n'; } if ( !file.error() ) { setDirty(false); return true; } return false; } QString ColorPalette::fileName() const { return p->fileName; } void ColorPalette::setColumns(int columns) { if ( columns <= 0 ) columns = 0; if ( columns != p->columns ) { setDirty(true); Q_EMIT columnsChanged( p->columns = columns ); } } void ColorPalette::setColors(const QVector& colors) { p->colors.clear(); Q_FOREACH(const QColor& col, colors) p->colors.push_back(qMakePair(col,QString())); setDirty(true); Q_EMIT colorsChanged(p->colors); } void ColorPalette::setColors(const QVector >& colors) { p->colors = colors; setDirty(true); Q_EMIT colorsChanged(p->colors); } void ColorPalette::setColorAt(int index, const QColor& color) { if ( !p->valid_index(index) ) return; p->colors[index].first = color; setDirty(true); Q_EMIT colorChanged(index); Q_EMIT colorsUpdated(p->colors); } void ColorPalette::setColorAt(int index, const QColor& color, const QString& name) { if ( !p->valid_index(index) ) return; p->colors[index].first = color; p->colors[index].second = name; setDirty(true); Q_EMIT colorChanged(index); Q_EMIT colorsUpdated(p->colors); } void ColorPalette::setNameAt(int index, const QString& name) { if ( !p->valid_index(index) ) return; p->colors[index].second = name; setDirty(true); Q_EMIT colorChanged(index); Q_EMIT colorsUpdated(p->colors); } void ColorPalette::appendColor(const QColor& color, const QString& name) { p->colors.push_back(qMakePair(color,name)); setDirty(true); Q_EMIT colorAdded(p->colors.size()-1); Q_EMIT colorsUpdated(p->colors); } void ColorPalette::insertColor(int index, const QColor& color, const QString& name) { if ( index < 0 || index > p->colors.size() ) return; p->colors.insert(index, qMakePair(color, name)); setDirty(true); Q_EMIT colorAdded(index); Q_EMIT colorsUpdated(p->colors); } void ColorPalette::eraseColor(int index) { if ( !p->valid_index(index) ) return; p->colors.remove(index); setDirty(true); Q_EMIT colorRemoved(index); Q_EMIT colorsUpdated(p->colors); } void ColorPalette::setName(const QString& name) { setDirty(true); p->name = name; } void ColorPalette::setFileName(const QString& name) { setDirty(true); p->fileName = name; } QString ColorPalette::unnamed(const QString& name) const { return name.isEmpty() ? tr("Unnamed") : name; } QPixmap ColorPalette::preview(const QSize& size, const QColor& background) const { if ( !size.isValid() || p->colors.empty() ) return QPixmap(); QPixmap out( size ); out.fill(background); QPainter painter(&out); int count = p->colors.size(); int columns = p->columns; if ( !columns ) columns = std::ceil( std::sqrt( count * float(size.width()) / size.height() ) ); int rows = std::ceil( float(count) / columns ); QSizeF color_size(float(size.width()) / columns, float(size.height()) / rows); for ( int y = 0, i = 0; y < rows && i < count; y++ ) { for ( int x = 0; x < columns && i < count; x++, i++ ) { painter.fillRect(QRectF(x*color_size.width(), y*color_size.height(), color_size.width(), color_size.height()), p->colors[i].first ); } } return out; } bool ColorPalette::dirty() const { return p->dirty; } void ColorPalette::setDirty(bool dirty) { if ( dirty != p->dirty ) Q_EMIT dirtyChanged( p->dirty = dirty ); } QVector ColorPalette::onlyColors() const { QVector out; out.reserve(p->colors.size()); for ( int i = 0; i < p->colors.size(); i++ ) out.push_back(p->colors[i].first); return out; } QVector ColorPalette::colorTable() const { QVector out; out.reserve(p->colors.size()); for ( const auto& color_pair : p->colors ) out.push_back(color_pair.first.rgba()); return out; } ColorPalette ColorPalette::fromColorTable(const QVector& table) { ColorPalette palette; palette.loadColorTable(table); return palette; } } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/color_palette_model.cpp000066400000000000000000000211461366475014400252040ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/color_palette_model.hpp" #include #include #include namespace color_widgets { class ColorPaletteModel::Private { public: /// \todo Keep sorted by name (?) QList palettes; QSize icon_size; QStringList search_paths; QString save_path; Private() : icon_size(32, 32) {} bool acceptable(const QModelIndex& index) const { return acceptable(index.row()); } bool acceptable(int row) const { return row >= 0 && row <= palettes.count(); } QList::iterator find(const QString& name) { return std::find_if(palettes.begin(), palettes.end(), [&name](const ColorPalette& palette) { return palette.name() == name; }); } bool attemptSave(ColorPalette& palette, const QString& filename) { if ( filename.isEmpty() ) return false; return palette.save(filename); } void fixUnnamed(ColorPalette& palette) { if ( palette.name().isEmpty() ) palette.setName(ColorPaletteModel::tr("Unnamed")); } bool save(ColorPalette& palette, const QString& suggested_filename = QString()) { // Attempt to save with the existing file names if ( !suggested_filename.isEmpty() && attemptSave(palette, suggested_filename) ) return true; if ( attemptSave(palette, palette.fileName()) ) return true; // Set up the save directory QDir save_dir(save_path); if ( !save_dir.exists() && !QDir().mkdir(save_path) ) return false; // Attempt to save as (Name).gpl QString filename = palette.name()+".gpl"; if ( !save_dir.exists(filename) && attemptSave(palette, save_dir.absoluteFilePath(filename)) ) return true; // Get all of the files matching the pattern *.gpl save_dir.setNameFilters(QStringList() << QStringLiteral("*.gpl")); save_dir.setFilter(QDir::Files); QStringList existing_files = save_dir.entryList(); // For all the files that match (Name)(Number).gpl, find the maximum (Number) QRegularExpression name_regex(QRegularExpression::escape(palette.name())+"([0-9]+)\\.gpl"); int max = 0; for ( const auto& existing_file : existing_files ) { QRegularExpressionMatch match = name_regex.match(existing_file); if ( match.hasMatch() ) { int num = match.captured(1).toInt(); if ( num > max ) max = num; } } return attemptSave(palette, save_dir.absoluteFilePath(QStringLiteral("%1%2.gpl").arg(palette.name()).arg(max+1)) ); } }; ColorPaletteModel::ColorPaletteModel() : p ( new Private ) {} ColorPaletteModel::~ColorPaletteModel() { delete p; } int ColorPaletteModel::rowCount(const QModelIndex &) const { return count(); } QVariant ColorPaletteModel::data(const QModelIndex &index, int role) const { if ( !p->acceptable(index) ) return QVariant(); const ColorPalette& palette = p->palettes[index.row()]; switch( role ) { case Qt::DisplayRole: return palette.name(); case Qt::DecorationRole: return palette.preview(p->icon_size); case Qt::ToolTipRole: return tr("%1 (%2 colors)").arg(palette.name()).arg(palette.count()); } return QVariant(); } bool ColorPaletteModel::removeRows(int row, int count, const QModelIndex & parent) { Q_UNUSED(parent) if ( !p->acceptable(row) || count <= 0 ) return false; auto begin = p->palettes.begin() + row; auto end = row + count >= p->palettes.size() ? p->palettes.end() : begin + count; for ( auto it = begin; it != end; ++it ) { if ( !it->fileName().isEmpty() ) { QFileInfo file(it->fileName()); if ( file.isWritable() && file.isFile() ) QFile::remove(it->fileName()); } } p->palettes.erase(begin, end); return true; } QSize ColorPaletteModel::iconSize() const { return p->icon_size; } void ColorPaletteModel::setIconSize(const QSize& iconSize) { if ( p->icon_size != iconSize ) Q_EMIT iconSizeChanged( p->icon_size = iconSize ); } QString ColorPaletteModel::savePath() const { return p->save_path; } QStringList ColorPaletteModel::searchPaths() const { return p->search_paths; } void ColorPaletteModel::setSavePath(const QString& savePath) { if ( p->save_path != savePath ) Q_EMIT savePathChanged( p->save_path = savePath ); } void ColorPaletteModel::setSearchPaths(const QStringList& searchPaths) { if ( p->search_paths != searchPaths ) Q_EMIT searchPathsChanged( p->search_paths = searchPaths ); } void ColorPaletteModel::addSearchPath(const QString& path) { /// \todo Should compare canonical paths /// and these checks should also be made in setSearchPaths if ( !p->search_paths.contains(path) ) { p->search_paths.push_back(path); Q_EMIT searchPathsChanged( p->search_paths ); } } void ColorPaletteModel::load() { beginResetModel(); p->palettes.clear(); QStringList filters; filters << QStringLiteral("*.gpl"); for ( const QString& directory_name : p->search_paths ) { QDir directory(directory_name); directory.setNameFilters(filters); directory.setFilter(QDir::Files|QDir::Readable); directory.setSorting(QDir::Name); for ( const QFileInfo& file : directory.entryInfoList() ) { ColorPalette palette; if ( palette.load(file.absoluteFilePath()) ) { p->palettes.push_back(palette); } } } endResetModel(); } bool ColorPaletteModel::hasPalette(const QString& name) const { return p->find(name) != p->palettes.end(); } int ColorPaletteModel::count() const { return p->palettes.size(); } const ColorPalette& ColorPaletteModel::palette(const QString& name) const { return *p->find(name); } const ColorPalette& ColorPaletteModel::palette(int index) const { return p->palettes[index]; } bool ColorPaletteModel::updatePalette(int index, const ColorPalette& palette, bool save) { if ( !p->acceptable(index) ) return false; // Store the old file name QString filename = p->palettes[index].fileName(); // Update the palette ColorPalette& local_palette = p->palettes[index] = palette; p->fixUnnamed(local_palette); if ( save ) return p->save(local_palette, filename); return true; } bool ColorPaletteModel::removePalette(int index, bool remove_file) { if ( !p->acceptable(index) ) return false; QString file_name = p->palettes[index].fileName(); beginRemoveRows(QModelIndex(), index, index); p->palettes.removeAt(index); endRemoveRows(); if ( !file_name.isEmpty() && remove_file ) { QFileInfo file(file_name); if ( file.isWritable() && file.isFile() ) return QFile::remove(file_name); return false; } return true; } bool ColorPaletteModel::addPalette(const ColorPalette& palette, bool save) { beginInsertRows(QModelIndex(), p->palettes.size(), p->palettes.size()); p->palettes.push_back(palette); p->fixUnnamed(p->palettes.back()); endInsertRows(); if ( save ) return p->save(p->palettes.back()); return true; } int ColorPaletteModel::indexFromFile(const QString& filename) const { QString canonical = QFileInfo(filename).canonicalFilePath(); int i = 0; for ( const auto& pal : p->palettes ) { if ( !pal.fileName().isEmpty() && QFileInfo(pal.fileName()).canonicalFilePath() == canonical ) return i; i++; } return -1; } } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/color_palette_widget.cpp000066400000000000000000000303461366475014400253710ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/color_palette_widget.hpp" #include "ui_color_palette_widget.h" #include "QtColorWidgets/color_dialog.hpp" #include #include #include #include namespace color_widgets { class ColorPaletteWidget::Private : public Ui::ColorPaletteWidget { public: ColorPaletteModel* model = nullptr; bool read_only = false; bool hasSelectedPalette() { return model && palette_list->currentIndex() != -1; } const ColorPalette& selectedPalette() { return model->palette(palette_list->currentIndex()); } void addPalette(ColorPalette& palette) { bool save = false; // Save palettes in the savePath /// \todo This currently breaks opening the right directory /// ie: the one containing the original file. if ( !palette.fileName().isEmpty() ) { QFileInfo file(palette.fileName()); if ( file.dir().canonicalPath() != QDir(model->savePath()).canonicalPath() ) { palette.setFileName(QString()); save = true; } } model->addPalette(palette, save); palette_list->setCurrentIndex(model->count()-1); } bool openImage(const QString& file) { QImage image(file); if ( !image.isNull() ) { ColorPalette palette; palette.loadImage(image); palette.setName(QFileInfo(file).baseName()); palette.setFileName(file+".gpl"); addPalette(palette); return true; } return false; } bool openGpl(const QString& file) { int existing = model->indexFromFile(file); if ( existing != -1 ) { palette_list->setCurrentIndex(existing); return true; } ColorPalette palette; if ( palette.load(file) ) { addPalette(palette); return true; } return false; } bool openPalette(const QString& file, int type) { if ( type == 1 ) return openImage(file); return openGpl(file); } }; ColorPaletteWidget::ColorPaletteWidget(QWidget* parent) : QWidget(parent), p(new Private) { p->setupUi(this); // Connext Swatch signals connect(p->swatch, &Swatch::colorSizeChanged, this, &ColorPaletteWidget::colorSizeChanged); connect(p->swatch, &Swatch::colorSizePolicyChanged, this, &ColorPaletteWidget::colorSizePolicyChanged); connect(p->swatch, &Swatch::forcedRowsChanged, this, &ColorPaletteWidget::forcedRowsChanged); connect(p->swatch, &Swatch::forcedColumnsChanged, this, &ColorPaletteWidget::forcedColumnsChanged); connect(p->swatch, &Swatch::colorSelected, this, (void (ColorPaletteWidget::*)(const QColor&)) &ColorPaletteWidget::currentColorChanged); connect(p->swatch, &Swatch::selectedChanged, this, (void (ColorPaletteWidget::*)(int)) &ColorPaletteWidget::currentColorChanged); connect(p->swatch, &Swatch::borderChanged, this, &ColorPaletteWidget::borderChanged); connect(p->swatch, &Swatch::paletteChanged, this, &ColorPaletteWidget::currentPaletteChanged); connect(&p->swatch->palette(), &ColorPalette::dirtyChanged, p->button_palette_save, &QWidget::setEnabled); connect(&p->swatch->palette(), &ColorPalette::dirtyChanged, p->button_palette_revert, &QWidget::setEnabled); connect(p->palette_list, (void (QComboBox::*)(int))&QComboBox::currentIndexChanged, this, &ColorPaletteWidget::currentRowChanged); // Buttons changing the colors in the current palette connect(p->button_color_add, &QAbstractButton::clicked, [this](){ if ( !p->read_only && p->hasSelectedPalette() ) { ColorDialog dialog(this); dialog.setAlphaEnabled(false); if ( p->swatch->selected() != -1 ) dialog.setColor(p->swatch->selectedColor()); if ( dialog.exec() ) { p->swatch->palette().appendColor(dialog.color()); p->swatch->setSelected(p->swatch->palette().count()-1); } } }); connect(p->button_color_remove, &QAbstractButton::clicked, p->swatch, &Swatch::removeSelected); // Buttons modifying the current palette file connect(p->button_palette_delete, &QAbstractButton::clicked, [this]() { if ( !p->read_only && p->hasSelectedPalette() ) p->model->removePalette(p->palette_list->currentIndex()); }); connect(p->button_palette_save, &QAbstractButton::clicked, [this](){ if ( !p->read_only && p->hasSelectedPalette() && p->swatch->palette().dirty() ) if ( p->model->updatePalette( p->palette_list->currentIndex(), p->swatch->palette() ) ) { p->swatch->palette().setDirty(false); } /// \todo else ask for a file name (?) }); connect(p->button_palette_revert, &QAbstractButton::clicked, [this](){ if ( p->hasSelectedPalette() ) { p->swatch->setPalette(p->selectedPalette()); } }); // Buttons creating new palettes connect(p->button_palette_duplicate, &QAbstractButton::clicked, [this](){ if ( p->hasSelectedPalette() ) { ColorPalette new_palette = p->selectedPalette(); new_palette.setFileName(QString()); bool ok = false; QString name = QInputDialog::getText(this, tr("New Palette"), tr("Name"), QLineEdit::Normal, new_palette.name(), &ok); if ( ok ) { new_palette.setName(name); p->model->addPalette(new_palette); p->palette_list->setCurrentIndex(p->model->count()-1); } } }); /// \todo Show a dialog that asks for the number of columns (?) connect(p->button_palette_new, &QAbstractButton::clicked, [this](){ if ( p->hasSelectedPalette() ) { bool ok = false; QString name = QInputDialog::getText(this, tr("New Palette"), tr("Name"), QLineEdit::Normal, QString(), &ok); if ( ok ) { ColorPalette new_palette(name); p->model->addPalette(new_palette); p->palette_list->setCurrentIndex(p->model->count()-1); } } }); QString image_formats; Q_FOREACH(QByteArray ba, QImageReader::supportedImageFormats()) image_formats += " *."+QString(ba); connect(p->button_palette_open, &QAbstractButton::clicked, [this, image_formats](){ if ( p->model ) { QString default_dir; if ( p->hasSelectedPalette() ) { const ColorPalette& palette = p->selectedPalette(); if ( !palette.fileName().isEmpty() ) default_dir = QFileInfo(palette.fileName()).dir().path(); } QStringList file_formats = QStringList() << tr("GIMP Palettes (*.gpl)") << tr("Palette Image (%1)").arg(image_formats) << tr("All Files (*)"); QFileDialog open_dialog(this, tr("Open Palette"), default_dir); open_dialog.setFileMode(QFileDialog::ExistingFile); open_dialog.setAcceptMode(QFileDialog::AcceptOpen); open_dialog.setNameFilters(file_formats); if ( !open_dialog.exec() ) return; int type = file_formats.indexOf(open_dialog.selectedNameFilter()); QString file_name = open_dialog.selectedFiles()[0]; if ( !p->openPalette( file_name, type ) ) { QMessageBox::warning(this, tr("Open Palette"), tr("Failed to load the palette file\n%1").arg(file_name)); } } }); } ColorPaletteWidget::~ColorPaletteWidget() = default; ColorPaletteModel* ColorPaletteWidget::model() const { return p->model; } const ColorPalette& ColorPaletteWidget::currentPalette() const { return p->swatch->palette(); } QSize ColorPaletteWidget::colorSize() const { return p->swatch->colorSize(); } Swatch::ColorSizePolicy ColorPaletteWidget::colorSizePolicy() const { return p->swatch->colorSizePolicy(); } QPen ColorPaletteWidget::border() const { return p->swatch->border(); } int ColorPaletteWidget::forcedRows() const { return p->swatch->forcedRows(); } int ColorPaletteWidget::forcedColumns() const { return p->swatch->forcedColumns(); } bool ColorPaletteWidget::readOnly() const { return p->read_only; } QColor ColorPaletteWidget::currentColor() const { return p->swatch->selectedColor(); } void ColorPaletteWidget::setModel(ColorPaletteModel* model) { if ( model == p->model ) return; p->model = model; p->swatch->setPalette(ColorPalette()); p->palette_list->setModel(model); } void ColorPaletteWidget::setColorSize(const QSize& colorSize) { p->swatch->setColorSize(colorSize); } void ColorPaletteWidget::setColorSizePolicy(Swatch::ColorSizePolicy colorSizePolicy) { p->swatch->setColorSizePolicy(colorSizePolicy); } void ColorPaletteWidget::setBorder(const QPen& border) { p->swatch->setBorder(border); } void ColorPaletteWidget::setForcedRows(int forcedRows) { p->swatch->setForcedRows(forcedRows); } void ColorPaletteWidget::setForcedColumns(int forcedColumns) { p->swatch->setForcedColumns(forcedColumns); } void ColorPaletteWidget::setReadOnly(bool readOnly) { if ( readOnly == p->read_only ) return; p->swatch->setReadOnly(readOnly); p->group_edit_list->setVisible(!readOnly); p->group_edit_palette->setVisible(!readOnly); Q_EMIT readOnlyChanged(p->read_only = readOnly); } bool ColorPaletteWidget::setCurrentColor(const QColor& color) { const auto& palette = p->swatch->palette(); for ( int i = 0; i < palette.count(); i++ ) { if ( palette.colorAt(i) == color ) { p->swatch->setSelected(i); return true; } } p->swatch->clearSelection(); return false; } bool ColorPaletteWidget::setCurrentColor(const QString& name) { const auto& palette = p->swatch->palette(); for ( int i = 0; i < palette.count(); i++ ) { if ( palette.nameAt(i) == name ) { p->swatch->setSelected(i); return true; } } p->swatch->clearSelection(); return false; } bool ColorPaletteWidget::setCurrentColor(int index) { const auto& palette = p->swatch->palette(); if ( index >= 0 && index < palette.count() ) { p->swatch->setSelected(index); return true; } p->swatch->clearSelection(); return false; } void ColorPaletteWidget::on_palette_list_currentIndexChanged(int index) { if ( !p->model ) p->swatch->setPalette(ColorPalette()); else p->swatch->setPalette(p->model->palette(index)); p->swatch->palette().setDirty(false); } void ColorPaletteWidget::on_swatch_doubleClicked(int index) { if ( !p->read_only ) { ColorDialog dialog(this); dialog.setAlphaEnabled(false); dialog.setColor(p->swatch->palette().colorAt(index)); if ( dialog.exec() ) p->swatch->palette().setColorAt(index, dialog.color()); } } int ColorPaletteWidget::currentRow() const { return p->palette_list->currentIndex(); } void ColorPaletteWidget::setCurrentRow(int row) { p->palette_list->setCurrentIndex(row); } void ColorPaletteWidget::clearCurrentColor() { p->swatch->clearSelection(); } } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/color_palette_widget.ui000066400000000000000000000132301366475014400252150ustar00rootroot00000000000000 color_widgets::ColorPaletteWidget 0 0 227 186 0 0 0 0 0 0 0 0 0 0 0 Open a new palette from file Create a new palette Duplicate the current palette 0 0 0 0 0 Delete the current palette Revert changes to the current palette Save changes to the current palette Qt::Horizontal 40 20 Add a color to the palette Remove the selected color from the palette color_widgets::Swatch QWidget
QtColorWidgets/swatch.hpp
Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/color_preview.cpp000066400000000000000000000102741366475014400240470ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * \copyright Copyright (C) 2014 Calle Laakkonen * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/color_preview.hpp" #include #include #include #include #include namespace color_widgets { class ColorPreview::Private { public: QColor col; ///< color to be viewed QColor comparison; ///< comparison color QBrush back;///< Background brush, visible on a transparent color DisplayMode display_mode; ///< How the color(s) are to be shown Private() : col(Qt::red), back(Qt::darkGray, Qt::DiagCrossPattern), display_mode(NoAlpha) {} }; ColorPreview::ColorPreview(QWidget *parent) : QWidget(parent), p(new Private) { p->back.setTexture(QPixmap(QStringLiteral(":/color_widgets/alphaback.png"))); } ColorPreview::~ColorPreview() { delete p; } void ColorPreview::setBackground(const QBrush &bk) { p->back = bk; update(); Q_EMIT backgroundChanged(bk); } QBrush ColorPreview::background() const { return p->back; } ColorPreview::DisplayMode ColorPreview::displayMode() const { return p->display_mode; } void ColorPreview::setDisplayMode(DisplayMode m) { p->display_mode = m; update(); Q_EMIT displayModeChanged(m); } QColor ColorPreview::color() const { return p->col; } QColor ColorPreview::comparisonColor() const { return p->comparison; } QSize ColorPreview::sizeHint() const { return QSize(24,24); } void ColorPreview::paint(QPainter &painter, QRect rect) const { QColor c1, c2; switch(p->display_mode) { case DisplayMode::NoAlpha: c1 = c2 = p->col.rgb(); break; case DisplayMode::AllAlpha: c1 = c2 = p->col; break; case DisplayMode::SplitAlpha: c1 = p->col.rgb(); c2 = p->col; break; case DisplayMode::SplitColor: c1 = p->comparison; c2 = p->col; break; } QStyleOptionFrame panel; panel.initFrom(this); panel.lineWidth = 2; panel.midLineWidth = 0; panel.state |= QStyle::State_Sunken; style()->drawPrimitive(QStyle::PE_Frame, &panel, &painter, this); QRect r = style()->subElementRect(QStyle::SE_FrameContents, &panel, this); painter.setClipRect(r); if ( c1.alpha() < 255 || c2.alpha() < 255 ) painter.fillRect(0, 0, rect.width(), rect.height(), p->back); int w = rect.width() / 2; int h = rect.height(); painter.fillRect(0, 0, w, h, c1); painter.fillRect(w, 0, w, h, c2); } void ColorPreview::setColor(const QColor &c) { p->col = c; update(); Q_EMIT colorChanged(c); } void ColorPreview::setComparisonColor(const QColor &c) { p->comparison = c; update(); Q_EMIT comparisonColorChanged(c); } void ColorPreview::paintEvent(QPaintEvent *) { QStylePainter painter(this); paint(painter, geometry()); } void ColorPreview::resizeEvent(QResizeEvent *) { update(); } void ColorPreview::mouseReleaseEvent(QMouseEvent * ev) { if ( QRect(QPoint(0,0),size()).contains(ev->pos()) ) Q_EMIT clicked(); } void ColorPreview::mouseMoveEvent(QMouseEvent *ev) { if ( ev->buttons() &Qt::LeftButton && !QRect(QPoint(0,0),size()).contains(ev->pos()) ) { QMimeData *data = new QMimeData; data->setColorData(p->col); QDrag* drag = new QDrag(this); drag->setMimeData(data); QPixmap preview(24,24); preview.fill(p->col); drag->setPixmap(preview); drag->exec(); } } } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/color_selector.cpp000066400000000000000000000107531366475014400242100ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/color_selector.hpp" #include "QtColorWidgets/color_dialog.hpp" #include #include #include namespace color_widgets { class ColorSelector::Private { public: UpdateMode update_mode; ColorDialog *dialog; QColor old_color; Private(QWidget *widget) : dialog(new ColorDialog(widget)) { dialog->setButtonMode(ColorDialog::OkCancel); } }; ColorSelector::ColorSelector(QWidget *parent) : ColorPreview(parent), p(new Private(this)) { setUpdateMode(Continuous); p->old_color = color(); connect(this,&ColorPreview::clicked,this,&ColorSelector::showDialog); connect(this,SIGNAL(colorChanged(QColor)),this,SLOT(update_old_color(QColor))); connect(p->dialog,&QDialog::rejected,this,&ColorSelector::reject_dialog); connect(p->dialog,&ColorDialog::colorSelected, this, &ColorSelector::accept_dialog); connect(p->dialog, &ColorDialog::wheelRotatingChanged, this, &ColorSelector::wheelRotatingChanged); connect(p->dialog, &ColorDialog::wheelShapeChanged, this, &ColorSelector::wheelShapeChanged); connect(p->dialog, &ColorDialog::colorSpaceChanged, this, &ColorSelector::colorSpaceChanged); setAcceptDrops(true); } ColorSelector::~ColorSelector() { delete p; } ColorSelector::UpdateMode ColorSelector::updateMode() const { return p->update_mode; } void ColorSelector::setUpdateMode(UpdateMode m) { p->update_mode = m; Q_EMIT updateModeChanged(m); } Qt::WindowModality ColorSelector::dialogModality() const { return p->dialog->windowModality(); } void ColorSelector::setDialogModality(Qt::WindowModality m) { p->dialog->setWindowModality(m); Q_EMIT dialogModalityChanged(m); } void ColorSelector::setWheelShape(ColorWheel::ShapeEnum shape) { p->dialog->setWheelShape(shape); } ColorWheel::ShapeEnum ColorSelector::wheelShape() const { return p->dialog->wheelShape(); } void ColorSelector::setColorSpace(ColorWheel::ColorSpaceEnum space) { p->dialog->setColorSpace(space); } ColorWheel::ColorSpaceEnum ColorSelector::colorSpace() const { return p->dialog->colorSpace(); } void ColorSelector::setWheelRotating(bool rotating) { p->dialog->setWheelRotating(rotating); } bool ColorSelector::wheelRotating() const { return p->dialog->wheelRotating(); } void ColorSelector::showDialog() { p->old_color = color(); p->dialog->setColor(color()); connect_dialog(); p->dialog->show(); } void ColorSelector::connect_dialog() { if (p->update_mode == Continuous) connect(p->dialog, SIGNAL(colorChanged(QColor)), this, SLOT(setColor(QColor)), Qt::UniqueConnection); else disconnect_dialog(); } void ColorSelector::disconnect_dialog() { disconnect(p->dialog, SIGNAL(colorChanged(QColor)), this, SLOT(setColor(QColor))); } void ColorSelector::accept_dialog() { setColor(p->dialog->color()); p->old_color = color(); } void ColorSelector::reject_dialog() { setColor(p->old_color); } void ColorSelector::update_old_color(const QColor &c) { if (!p->dialog->isVisible()) p->old_color = c; } void ColorSelector::dragEnterEvent(QDragEnterEvent *event) { if ( event->mimeData()->hasColor() || ( event->mimeData()->hasText() && QColor(event->mimeData()->text()).isValid() ) ) event->acceptProposedAction(); } void ColorSelector::dropEvent(QDropEvent *event) { if ( event->mimeData()->hasColor() ) { setColor(event->mimeData()->colorData().value()); event->accept(); } else if ( event->mimeData()->hasText() ) { QColor col(event->mimeData()->text()); if ( col.isValid() ) { setColor(col); event->accept(); } } } } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/color_utils.cpp000066400000000000000000000047041366475014400235270ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/color_utils.hpp" namespace color_widgets { namespace detail { QColor color_from_lch(qreal hue, qreal chroma, qreal luma, qreal alpha ) { qreal h1 = hue*6; qreal x = chroma*(1-qAbs(std::fmod(h1,2)-1)); QColor col; if ( h1 >= 0 && h1 < 1 ) col = QColor::fromRgbF(chroma,x,0); else if ( h1 < 2 ) col = QColor::fromRgbF(x,chroma,0); else if ( h1 < 3 ) col = QColor::fromRgbF(0,chroma,x); else if ( h1 < 4 ) col = QColor::fromRgbF(0,x,chroma); else if ( h1 < 5 ) col = QColor::fromRgbF(x,0,chroma); else if ( h1 < 6 ) col = QColor::fromRgbF(chroma,0,x); qreal m = luma - color_lumaF(col); return QColor::fromRgbF( qBound(0.0,col.redF()+m,1.0), qBound(0.0,col.greenF()+m,1.0), qBound(0.0,col.blueF()+m,1.0), alpha); } QColor color_from_hsl(qreal hue, qreal sat, qreal lig, qreal alpha ) { qreal chroma = (1 - qAbs(2*lig-1))*sat; qreal h1 = hue*6; qreal x = chroma*(1-qAbs(std::fmod(h1,2)-1)); QColor col; if ( h1 >= 0 && h1 < 1 ) col = QColor::fromRgbF(chroma,x,0); else if ( h1 < 2 ) col = QColor::fromRgbF(x,chroma,0); else if ( h1 < 3 ) col = QColor::fromRgbF(0,chroma,x); else if ( h1 < 4 ) col = QColor::fromRgbF(0,x,chroma); else if ( h1 < 5 ) col = QColor::fromRgbF(x,0,chroma); else if ( h1 < 6 ) col = QColor::fromRgbF(chroma,0,x); qreal m = lig-chroma/2; return QColor::fromRgbF( qBound(0.0,col.redF()+m,1.0), qBound(0.0,col.greenF()+m,1.0), qBound(0.0,col.blueF()+m,1.0), alpha); } } // namespace detail } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/color_wheel.cpp000066400000000000000000000222061366475014400234700ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/color_wheel.hpp" #include "QtColorWidgets/color_wheel_private.hpp" #include #include #include #include namespace color_widgets { static const double selector_radius = 6; ColorWheel::ColorWheel(QWidget *parent, Private* data) : QWidget(parent), p(data) { p->setup(); setAcceptDrops(true); } ColorWheel::ColorWheel(QWidget *parent) : ColorWheel(parent, new Private(this)) { } ColorWheel::~ColorWheel() { delete p; } QColor ColorWheel::color() const { return p->color_from(p->hue, p->sat, p->val, 1); } QSize ColorWheel::sizeHint() const { return QSize(p->wheel_width*5, p->wheel_width*5); } qreal ColorWheel::hue() const { if ( p->color_space == ColorLCH && p->sat > 0.01 ) return color().hueF(); return p->hue; } qreal ColorWheel::saturation() const { return color().hsvSaturationF(); } qreal ColorWheel::value() const { return color().valueF(); } unsigned int ColorWheel::wheelWidth() const { return p->wheel_width; } void ColorWheel::setWheelWidth(unsigned int w) { p->wheel_width = w; p->render_inner_selector(); update(); Q_EMIT wheelWidthChanged(w); } void ColorWheel::paintEvent(QPaintEvent * ) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.translate(geometry().width()/2,geometry().height()/2); // hue wheel if(p->hue_ring.isNull()) p->render_ring(); painter.drawPixmap(-p->outer_radius(), -p->outer_radius(), p->hue_ring); // hue selector p->draw_ring_editor(p->hue, painter, Qt::black); // lum-sat square if(p->inner_selector.isNull()) p->render_inner_selector(); painter.rotate(p->selector_image_angle()); painter.translate(p->selector_image_offset()); QPointF selector_position; if ( p->selector_shape == ShapeSquare ) { qreal side = p->square_size(); selector_position = QPointF(p->sat*side, p->val*side); } else if ( p->selector_shape == ShapeTriangle ) { qreal side = p->triangle_side(); qreal height = p->triangle_height(); qreal slice_h = side * p->val; qreal ymin = side/2-slice_h/2; selector_position = QPointF(p->val*height, ymin + p->sat*slice_h); QPolygonF triangle; triangle.append(QPointF(0,side/2)); triangle.append(QPointF(height,0)); triangle.append(QPointF(height,side)); QPainterPath clip; clip.addPolygon(triangle); painter.setClipPath(clip); } painter.drawImage(QRectF(QPointF(0, 0), p->selector_size()), p->inner_selector); painter.setClipping(false); // lum-sat selector // we define the color of the selecto based on the background color of the widget // in order to improve to contrast if (p->backgroundIsDark) { bool isWhite = (p->val < 0.65 || p->sat > 0.43); painter.setPen(QPen(isWhite ? Qt::white : Qt::black, 3)); } else { painter.setPen(QPen(p->val > 0.5 ? Qt::black : Qt::white, 3)); } painter.setBrush(Qt::NoBrush); painter.drawEllipse(selector_position, selector_radius, selector_radius); } void ColorWheel::mouseMoveEvent(QMouseEvent *ev) { if (p->mouse_status == DragCircle ) { auto hue = p->line_to_point(ev->pos()).angle()/360.0; p->hue = hue; p->render_inner_selector(); Q_EMIT colorSelected(color()); Q_EMIT colorChanged(color()); update(); } else if(p->mouse_status == DragSquare) { QLineF glob_mouse_ln = p->line_to_point(ev->pos()); QLineF center_mouse_ln ( QPointF(0,0), glob_mouse_ln.p2() - glob_mouse_ln.p1() ); center_mouse_ln.setAngle(center_mouse_ln.angle()+p->selector_image_angle()); center_mouse_ln.setP2(center_mouse_ln.p2()-p->selector_image_offset()); if ( p->selector_shape == ShapeSquare ) { p->sat = qBound(0.0, center_mouse_ln.x2()/p->square_size(), 1.0); p->val = qBound(0.0, center_mouse_ln.y2()/p->square_size(), 1.0); } else if ( p->selector_shape == ShapeTriangle ) { QPointF pt = center_mouse_ln.p2(); qreal side = p->triangle_side(); p->val = qBound(0.0, pt.x() / p->triangle_height(), 1.0); qreal slice_h = side * p->val; qreal ycenter = side/2; qreal ymin = ycenter-slice_h/2; if ( slice_h > 0 ) p->sat = qBound(0.0, (pt.y()-ymin)/slice_h, 1.0); } Q_EMIT colorSelected(color()); Q_EMIT colorChanged(color()); update(); } } void ColorWheel::mousePressEvent(QMouseEvent *ev) { if ( ev->buttons() & Qt::LeftButton ) { setFocus(); QLineF ray = p->line_to_point(ev->pos()); if ( ray.length() <= p->inner_radius() ) p->mouse_status = DragSquare; else if ( ray.length() <= p->outer_radius() ) p->mouse_status = DragCircle; // Update the color mouseMoveEvent(ev); } } void ColorWheel::mouseReleaseEvent(QMouseEvent *ev) { mouseMoveEvent(ev); p->mouse_status = Nothing; } void ColorWheel::resizeEvent(QResizeEvent *) { p->render_ring(); p->render_inner_selector(); } void ColorWheel::setColor(QColor c) { qreal oldh = p->hue; p->set_color(c); if (!qFuzzyCompare(oldh+1, p->hue+1)) p->render_inner_selector(); update(); Q_EMIT colorChanged(c); } void ColorWheel::setHue(qreal h) { p->hue = qBound(0.0, h, 1.0); p->render_inner_selector(); update(); } void ColorWheel::setSaturation(qreal s) { p->sat = qBound(0.0, s, 1.0); update(); } void ColorWheel::setValue(qreal v) { p->val = qBound(0.0, v, 1.0); update(); } color_widgets::ColorWheel::ColorSpaceEnum ColorWheel::colorSpace() const { return p->color_space; } bool ColorWheel::rotatingSelector() const { return p->rotating_selector; } color_widgets::ColorWheel::ShapeEnum ColorWheel::selectorShape() const { return p->selector_shape; } void ColorWheel::setColorSpace(color_widgets::ColorWheel::ColorSpaceEnum space) { if ( p->color_space != space ) { p->color_space = space; QColor old_col = color(); switch ( space ) { case ColorHSL: p->hue = old_col.hueF(); p->sat = detail::color_HSL_saturationF(old_col); p->val = detail::color_lightnessF(old_col); p->color_from = &detail::color_from_hsl; p->rainbow_from_hue = &detail::rainbow_hsv; break; case ColorHSV: p->hue = old_col.hsvHueF(); p->sat = old_col.hsvSaturationF(); p->val = old_col.valueF(); p->color_from = &QColor::fromHsvF; p->rainbow_from_hue = &detail::rainbow_hsv; break; case ColorLCH: p->hue = old_col.hueF(); p->sat = detail::color_chromaF(old_col); p->val = detail::color_lumaF(old_col); p->color_from = &detail::color_from_lch; p->rainbow_from_hue = &detail::rainbow_lch; break; } p->render_ring(); p->render_inner_selector(); update(); Q_EMIT colorSpaceChanged(space); } } void ColorWheel::setRotatingSelector(bool rotating) { p->rotating_selector = rotating; update(); Q_EMIT rotatingSelectorChanged(rotating); } void ColorWheel::setSelectorShape(color_widgets::ColorWheel::ShapeEnum shape) { if ( shape != p->selector_shape ) { p->selector_shape = shape; update(); p->render_inner_selector(); Q_EMIT selectorShapeChanged(shape); } } void ColorWheel::dragEnterEvent(QDragEnterEvent* event) { if ( event->mimeData()->hasColor() || ( event->mimeData()->hasText() && QColor(event->mimeData()->text()).isValid() ) ) event->acceptProposedAction(); } void ColorWheel::dropEvent(QDropEvent* event) { if ( event->mimeData()->hasColor() ) { setColor(event->mimeData()->colorData().value()); event->accept(); } else if ( event->mimeData()->hasText() ) { QColor col(event->mimeData()->text()); if ( col.isValid() ) { setColor(col); event->accept(); } } } } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/gradient_editor.cpp000066400000000000000000000347621366475014400243430ustar00rootroot00000000000000/** * \file gradient_editor.cpp * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/gradient_editor.hpp" #include #include #include #include #include #include #include #include #include #include "QtColorWidgets/gradient_helper.hpp" #include "QtColorWidgets/color_dialog.hpp" namespace color_widgets { class GradientEditor::Private { public: QGradientStops stops; QBrush back; Qt::Orientation orientation; int highlighted = -1; QLinearGradient gradient; int selected = -1; int drop_index = -1; QColor drop_color; qreal drop_pos = 0; ColorDialog color_dialog; int dialog_selected = -1; Private() : back(Qt::darkGray, Qt::DiagCrossPattern) { back.setTexture(QPixmap(QStringLiteral(":/color_widgets/alphaback.png"))); gradient.setCoordinateMode(QGradient::StretchToDeviceMode); gradient.setSpread(QGradient::RepeatSpread); } void refresh_gradient() { gradient.setStops(stops); } qreal paint_pos(const QGradientStop& stop, const GradientEditor* owner) { return 2.5 + stop.first * (owner->geometry().width() - 5); } int closest(const QPoint& p, GradientEditor* owner) { if ( stops.empty() ) return -1; if ( stops.size() == 1 || owner->geometry().width() <= 5 ) return 0; qreal pos = move_pos(p, owner); int i = 1; for ( ; i < stops.size()-1; i++ ) if ( stops[i].first >= pos ) break; if ( stops[i].first - pos < pos - stops[i-1].first ) return i; return i-1; } qreal move_pos(const QPoint& p, GradientEditor* owner) { int width; qreal x; if ( orientation == Qt::Horizontal ) { width = owner->geometry().width(); x = p.x(); } else { width = owner->geometry().height(); x = p.y(); } return (width > 5) ? qMax(qMin((x - 2.5) / (width - 5), 1.0), 0.0) : 0; } void drop_event(QDropEvent* event, GradientEditor* owner) { drop_index = closest(event->pos(), owner); drop_pos = move_pos(event->pos(), owner); if ( drop_index == -1 ) drop_index = stops.size(); // Gather up the color if ( event->mimeData()->hasColor() ) drop_color = event->mimeData()->colorData().value(); else if ( event->mimeData()->hasText() ) drop_color = QColor(event->mimeData()->text()); owner->update(); } void clear_drop(GradientEditor* owner) { drop_index = -1; drop_color = QColor(); owner->update(); } void add_stop_data(int& index, qreal& pos, QColor& color) { if ( stops.empty() ) { index = 0; pos = 0; color = Qt::black; return; } if ( stops.size() == 1 ) { color = stops[0].second; if ( stops[0].first == 1 ) { index = 0; pos = 0.5; } else { index = 1; pos = (stops[0].first + 1) / 2; } return; } int i_before = selected; if ( i_before == -1 ) i_before = stops.size() - 1; if ( i_before == stops.size() - 1 ) { if ( stops[i_before].first < 1 ) { color = stops[i_before].second; pos = (stops[i_before].first + 1) / 2; index = stops.size(); return; } i_before--; } index = i_before + 1; pos = (stops[i_before].first + stops[i_before+1].first) / 2; color = blendColors(stops[i_before].second, stops[i_before+1].second, 0.5); } }; GradientEditor::GradientEditor(QWidget *parent) : GradientEditor(Qt::Horizontal, parent) {} GradientEditor::GradientEditor(Qt::Orientation orientation, QWidget *parent) : QWidget(parent), p(new Private) { p->orientation = orientation; setMouseTracking(true); resize(sizeHint()); setAcceptDrops(true); p->color_dialog.setParent(this); p->color_dialog.setWindowFlags(Qt::Dialog); p->color_dialog.setWindowModality(Qt::WindowModal); connect(&p->color_dialog, &ColorDialog::colorSelected, this, &GradientEditor::dialogUpdate); } GradientEditor::~GradientEditor() { p->color_dialog.setParent(nullptr); delete p; } void GradientEditor::dialogUpdate(const QColor& c) { if ( p->dialog_selected != -1 ) { p->stops[p->dialog_selected].second = c; p->dialog_selected = -1; p->refresh_gradient(); Q_EMIT stopsChanged(p->stops); update(); } } void GradientEditor::mouseDoubleClickEvent(QMouseEvent *ev) { if ( ev->button() == Qt::LeftButton ) { ev->accept(); if ( p->highlighted != -1 ) { qreal highlighted_pos = p->paint_pos(p->stops[p->highlighted], this); qreal mouse_pos = orientation() == Qt::Vertical ? ev->pos().y() : ev->pos().x(); qreal tolerance = 4; if ( std::abs(mouse_pos - highlighted_pos) <= tolerance ) { p->dialog_selected = p->highlighted; p->color_dialog.setColor(p->stops[p->highlighted].second); p->color_dialog.show(); return; } } qreal pos = p->move_pos(ev->pos(), this); auto info = gradientBlendedColorInsert(p->stops, pos); p->stops.insert(info.first, info.second); p->selected = p->highlighted = info.first; p->refresh_gradient(); Q_EMIT selectedStopChanged(p->selected); update(); } else { QWidget::mousePressEvent(ev); } } void GradientEditor::mousePressEvent(QMouseEvent *ev) { if ( ev->button() == Qt::LeftButton ) { ev->accept(); p->selected = p->highlighted = p->closest(ev->pos(), this); emit selectedStopChanged(p->selected); update(); } else { QWidget::mousePressEvent(ev); } } void GradientEditor::mouseMoveEvent(QMouseEvent *ev) { if ( ev->buttons() & Qt::LeftButton && p->selected != -1 ) { ev->accept(); qreal pos = p->move_pos(ev->pos(), this); if ( p->selected > 0 && pos < p->stops[p->selected-1].first ) { std::swap(p->stops[p->selected], p->stops[p->selected-1]); p->selected--; emit selectedStopChanged(p->selected); } else if ( p->selected < p->stops.size()-1 && pos > p->stops[p->selected+1].first ) { std::swap(p->stops[p->selected], p->stops[p->selected+1]); p->selected++; emit selectedStopChanged(p->selected); } p->highlighted = p->selected; p->stops[p->selected].first = pos; p->refresh_gradient(); update(); } else { p->highlighted = p->closest(ev->pos(), this); update(); } } void GradientEditor::mouseReleaseEvent(QMouseEvent *ev) { if ( ev->button() == Qt::LeftButton && p->selected != -1 ) { ev->accept(); QRect bound_rect = rect(); QPoint localpt = ev->localPos().toPoint(); const int w_margin = 24; const int h_margin = 8; if ( !bound_rect.contains(localpt) && p->stops.size() > 1 && ( localpt.x() < -w_margin || localpt.x() > bound_rect.width() + w_margin || localpt.y() < -h_margin || localpt.y() > bound_rect.height() + h_margin ) ) { p->stops.remove(p->selected); p->highlighted = p->selected = p->dialog_selected = -1; p->refresh_gradient(); emit selectedStopChanged(p->selected); } emit stopsChanged(p->stops); update(); } else { QWidget::mousePressEvent(ev); } } void GradientEditor::leaveEvent(QEvent*) { p->highlighted = -1; update(); } QBrush GradientEditor::background() const { return p->back; } void GradientEditor::setBackground(const QBrush &bg) { p->back = bg; update(); Q_EMIT backgroundChanged(bg); } QGradientStops GradientEditor::stops() const { return p->stops; } void GradientEditor::setStops(const QGradientStops &colors) { p->selected = p->highlighted = p->dialog_selected = -1; p->stops = colors; p->refresh_gradient(); emit selectedStopChanged(p->selected); emit stopsChanged(p->stops); update(); } QLinearGradient GradientEditor::gradient() const { return p->gradient; } void GradientEditor::setGradient(const QLinearGradient &gradient) { setStops(gradient.stops()); } Qt::Orientation GradientEditor::orientation() const { return p->orientation; } void GradientEditor::setOrientation(Qt::Orientation orientation) { p->orientation = orientation; update(); } void GradientEditor::paintEvent(QPaintEvent *) { QPainter painter(this); QStyleOptionFrame panel; panel.initFrom(this); panel.lineWidth = 1; panel.midLineWidth = 0; panel.state |= QStyle::State_Sunken; style()->drawPrimitive(QStyle::PE_Frame, &panel, &painter, this); QRect r = style()->subElementRect(QStyle::SE_FrameContents, &panel, this); painter.setClipRect(r); if(orientation() == Qt::Horizontal) p->gradient.setFinalStop(1, 0); else p->gradient.setFinalStop(0, -1); painter.setPen(Qt::NoPen); painter.setBrush(p->back); painter.drawRect(1,1,geometry().width()-2,geometry().height()-2); painter.setBrush(p->gradient); painter.drawRect(1,1,geometry().width()-2,geometry().height()-2); /// \todo Take orientation into account int i = 0; for ( const QGradientStop& stop : p->stops ) { QColor color = stop.second; Qt::GlobalColor border_color = Qt::black; Qt::GlobalColor core_color = Qt::white; if ( color.valueF() <= 0.5 && color.alphaF() >= 0.5 ) std::swap(core_color, border_color); QPointF p1 = QPointF(p->paint_pos(stop, this), 2.5); QPointF p2 = p1 + QPointF(0, geometry().height() - 5); if ( i == p->selected ) { painter.setPen(QPen(border_color, 5)); painter.drawLine(p1, p2); painter.setPen(QPen(core_color, 3)); painter.drawLine(p1, p2); } else if ( i == p->highlighted ) { painter.setPen(QPen(border_color, 3)); painter.drawLine(p1, p2); painter.setPen(QPen(core_color, 1)); painter.drawLine(p1, p2); } else { painter.setPen(QPen(border_color, 3)); painter.drawLine(p1, p2); } i++; } if ( p->drop_index != -1 && p->drop_color.isValid() ) { qreal pos = p->drop_pos * (geometry().width() - 5); painter.setPen(QPen(p->drop_color, 3)); QPointF p1 = QPointF(2.5, 2.5) + QPointF(pos, 0); QPointF p2 = p1 + QPointF(0, geometry().height() - 5); painter.drawLine(p1, p2); } } QSize GradientEditor::sizeHint() const { QStyleOptionSlider opt; opt.orientation = p->orientation; int w = style()->pixelMetric(QStyle::PM_SliderThickness, &opt, this); int h = std::max(84, style()->pixelMetric(QStyle::PM_SliderLength, &opt, this)); if ( p->orientation == Qt::Horizontal ) { std::swap(w, h); } QSlider s; return style()->sizeFromContents(QStyle::CT_Slider, &opt, QSize(w, h), &s) .expandedTo(QApplication::globalStrut()); } int GradientEditor::selectedStop() const { return p->selected; } void GradientEditor::setSelectedStop(int stop) { if ( stop >= -1 && stop < p->stops.size() ) { p->selected = stop; emit selectedStopChanged(p->selected); } } QColor GradientEditor::selectedColor() const { if ( p->selected != -1 ) return p->stops[p->selected].second; return {}; } void GradientEditor::setSelectedColor(const QColor& color) { if ( p->selected != -1 ) { p->stops[p->selected].second = color; p->refresh_gradient(); update(); } } void GradientEditor::dragEnterEvent(QDragEnterEvent *event) { p->drop_event(event, this); if ( p->drop_color.isValid() && p->drop_index != -1 ) { event->setDropAction(Qt::CopyAction); event->accept(); } } void GradientEditor::dragMoveEvent(QDragMoveEvent* event) { p->drop_event(event, this); } void GradientEditor::dragLeaveEvent(QDragLeaveEvent *) { p->clear_drop(this); } void GradientEditor::dropEvent(QDropEvent *event) { p->drop_event(event, this); if ( !p->drop_color.isValid() || p->drop_index == -1 ) return; p->stops.insert(p->drop_index, {p->drop_pos, p->drop_color}); p->refresh_gradient(); p->selected = p->drop_index; event->accept(); p->clear_drop(this); emit selectedStopChanged(p->selected); } void GradientEditor::addStop() { int index = -1; qreal pos = 0; QColor color; p->add_stop_data(index, pos, color); p->stops.insert(index, {pos, color}); p->selected = p->highlighted = index; p->refresh_gradient(); update(); emit selectedStopChanged(p->selected); } void GradientEditor::removeStop() { if ( p->stops.size() < 2 ) return; int selected = p->selected; if ( selected == -1 ) selected = p->stops.size() - 1; p->stops.remove(selected); p->refresh_gradient(); if ( p->selected != -1 ) { p->selected = -1; emit selectedStopChanged(p->selected); } p->dialog_selected = -1; update(); } ColorDialog * GradientEditor::dialog() const { return &p->color_dialog; } } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/gradient_list_model.cpp000066400000000000000000000201761366475014400252020ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/gradient_list_model.hpp" #include #include #include using namespace color_widgets; class GradientListModel::Private { public: struct Gradient { QLinearGradient gradient; QString name; }; QVector gradients; QSize icon_size{48, 32}; QBrush background; ItemEditMode edit_mode = EditNone; Private() { background.setTexture(QPixmap(QStringLiteral(":/color_widgets/alphaback.png"))); } int find(const QString& name) { for ( int i = 0; i < gradients.size(); i++ ) if ( gradients[0].name == name ) return i; return -1; } bool contains(const QString& name) { return find(name) != -1; } bool acceptable(const QModelIndex& index) const { return acceptable(index.row()); } bool acceptable(int row) const { return row >= 0 && row < gradients.size(); } QPixmap preview(const QLinearGradient& grad) { QPixmap out (icon_size); QPainter painter(&out); QRect r({0, 0}, icon_size); painter.fillRect(r, background); painter.fillRect(r, grad); return out; } QLinearGradient make_gradient(const QGradientStops& gradient_stops) { QLinearGradient gradient(0, 0, 1, 0); gradient.setCoordinateMode(QGradient::StretchToDeviceMode); gradient.setSpread(QGradient::RepeatSpread); gradient.setStops(gradient_stops); return gradient; } }; GradientListModel::GradientListModel(QObject *parent) : QAbstractListModel(parent), d(new Private()) { } GradientListModel::~GradientListModel() = default; int color_widgets::GradientListModel::count() const { return d->gradients.size(); } void color_widgets::GradientListModel::clear() { beginResetModel(); d->gradients.clear(); endResetModel(); } QSize color_widgets::GradientListModel::iconSize() const { return d->icon_size; } void color_widgets::GradientListModel::setIconSize ( const QSize& iconSize ) { d->icon_size = iconSize; Q_EMIT iconSizeChanged(d->icon_size); } int color_widgets::GradientListModel::setGradient ( const QString& name, const QGradient& gradient ) { return setGradient(name, gradient.stops()); } int color_widgets::GradientListModel::setGradient ( const QString& name, const QGradientStops& gradient_stops ) { int index = d->find(name); if ( index != -1 ) { return setGradient(index, gradient_stops); } index = d->gradients.size(); beginInsertRows(QModelIndex(), index, index); d->gradients.push_back({d->make_gradient(gradient_stops), name}); endInsertRows(); return index; } bool color_widgets::GradientListModel::setGradient(int index, const QGradient& gradient) { return setGradient(index, gradient.stops()); } bool color_widgets::GradientListModel::setGradient(int index, const QGradientStops& gradient_stops) { if ( index < 0 || index > d->gradients.size() ) return false; d->gradients[index].gradient.setStops(gradient_stops); QModelIndex mindex = createIndex(index, 0); Q_EMIT dataChanged(mindex, mindex, {Qt::DecorationRole, Qt::ToolTipRole}); return true; } QGradientStops color_widgets::GradientListModel::gradientStops ( const QString& name ) const { auto iter = d->find(name); if ( iter != -1 ) return d->gradients[iter].gradient.stops(); return {}; } QGradientStops color_widgets::GradientListModel::gradientStops ( int index ) const { if ( d->acceptable(index) ) return d->gradients[index].gradient.stops(); return {}; } const QLinearGradient & color_widgets::GradientListModel::gradient ( int index ) const { return d->gradients[index].gradient; } const QLinearGradient & color_widgets::GradientListModel::gradient ( const QString& name ) const { return d->gradients[d->find(name)].gradient; } int color_widgets::GradientListModel::indexFromName ( const QString& name ) const { return d->find(name); } int color_widgets::GradientListModel::rowCount ( const QModelIndex& ) const { return d->gradients.size(); } bool color_widgets::GradientListModel::hasGradient ( const QString& name ) const { return d->contains(name); } bool color_widgets::GradientListModel::removeGradient ( int index ) { if ( !d->acceptable(index) ) return false; beginRemoveRows(QModelIndex{}, index, index); d->gradients.erase(d->gradients.begin() + index); endRemoveRows(); return true; } bool color_widgets::GradientListModel::removeGradient ( const QString& name ) { return removeGradient(d->find(name)); } QVariant color_widgets::GradientListModel::data ( const QModelIndex& index, int role ) const { if ( !d->acceptable(index) ) return QVariant(); const auto& gradient = d->gradients[index.row()]; switch( role ) { case Qt::DisplayRole: return gradient.name; case Qt::DecorationRole: return d->preview(gradient.gradient); case Qt::ToolTipRole: return tr("%1 (%2 colors)").arg(gradient.name).arg(gradient.gradient.stops().size()); case Qt::EditRole: if ( d->edit_mode == EditGradient ) return QBrush(gradient.gradient); else if ( d->edit_mode == EditName ) return gradient.name; return {}; } return QVariant(); } bool color_widgets::GradientListModel::rename(int index, const QString& new_name) { if ( !d->acceptable(index) || d->contains(new_name) ) return false; QModelIndex mindex = createIndex(index, 0); d->gradients[index].name = new_name; Q_EMIT dataChanged(mindex, mindex, {Qt::DisplayRole, Qt::ToolTipRole}); return true; } bool color_widgets::GradientListModel::rename(const QString& old_name, const QString& new_name) { return rename(d->find(old_name), new_name); } Qt::ItemFlags color_widgets::GradientListModel::flags(const QModelIndex& index) const { auto flags = QAbstractListModel::flags(index); if ( d->edit_mode ) flags |= Qt::ItemIsEditable; return flags; } bool color_widgets::GradientListModel::setData(const QModelIndex& index, const QVariant& value, int role) { if ( !d->acceptable(index) ) return false; if ( role == Qt::DisplayRole ) { return rename(index.row(), value.toString()); } else if ( role == Qt::EditRole ) { if ( d->edit_mode == EditName ) return rename(index.row(), value.toString()); if ( d->edit_mode == EditGradient ) { const QGradient* grad = value.value().gradient(); if ( !grad ) return false; return setGradient(index.row(), *grad); } } return false; } color_widgets::GradientListModel::ItemEditMode color_widgets::GradientListModel::editMode() const { return d->edit_mode; } void color_widgets::GradientListModel::setEditMode(color_widgets::GradientListModel::ItemEditMode mode) { d->edit_mode = mode; Q_EMIT editModeChanged(mode); } QBrush color_widgets::GradientListModel::gradientBrush(int index) const { if ( d->acceptable(index) ) return QBrush(d->gradients[index].gradient); return {}; } QString color_widgets::GradientListModel::nameFromIndex(int index) const { if ( d->acceptable(index) ) return d->gradients[index].name; return {}; } Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/gradient_slider.cpp000066400000000000000000000154431366475014400243320ustar00rootroot00000000000000/** * \file gradient_slider.cpp * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * \copyright Copyright (C) 2014 Calle Laakkonen * \copyright Copyright (C) 2017 caryoscelus * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/gradient_slider.hpp" #include #include #include #include #include static void loadResource() { static bool loaded = false; if ( !loaded ) { Q_INIT_RESOURCE(color_widgets); loaded = true; } } namespace color_widgets { class GradientSlider::Private { public: QLinearGradient gradient; QBrush back; Private() : back(Qt::darkGray, Qt::DiagCrossPattern) { loadResource(); back.setTexture(QPixmap(QStringLiteral(":/color_widgets/alphaback.png"))); gradient.setCoordinateMode(QGradient::StretchToDeviceMode); gradient.setSpread(QGradient::RepeatSpread); } void mouse_event(QMouseEvent *ev, GradientSlider* owner) { qreal pos = (owner->geometry().width() > 5) ? static_cast(ev->pos().x() - 2.5) / (owner->geometry().width() - 5) : 0; pos = qMax(qMin(pos, 1.0), 0.0); owner->setSliderPosition(qRound(owner->minimum() + pos * (owner->maximum() - owner->minimum()))); } }; GradientSlider::GradientSlider(QWidget *parent) : GradientSlider(Qt::Horizontal, parent) {} GradientSlider::GradientSlider(Qt::Orientation orientation, QWidget *parent) : QSlider(orientation, parent), p(new Private) { setTickPosition(NoTicks); } GradientSlider::~GradientSlider() { delete p; } void GradientSlider::mousePressEvent(QMouseEvent *ev) { if ( ev->button() == Qt::LeftButton ) { ev->accept(); setSliderDown(true); p->mouse_event(ev, this); update(); } else { QSlider::mousePressEvent(ev); } } void GradientSlider::mouseMoveEvent(QMouseEvent *ev) { if ( ev->buttons() & Qt::LeftButton ) { ev->accept(); p->mouse_event(ev, this); update(); } else { QSlider::mouseMoveEvent(ev); } } void GradientSlider::mouseReleaseEvent(QMouseEvent *ev) { if ( ev->button() == Qt::LeftButton ) { ev->accept(); setSliderDown(false); update(); } else { QSlider::mousePressEvent(ev); } } QBrush GradientSlider::background() const { return p->back; } void GradientSlider::setBackground(const QBrush &bg) { p->back = bg; update(); Q_EMIT backgroundChanged(bg); } QGradientStops GradientSlider::colors() const { return p->gradient.stops(); } void GradientSlider::setColors(const QGradientStops &colors) { p->gradient.setStops(colors); update(); } QLinearGradient GradientSlider::gradient() const { return p->gradient; } void GradientSlider::setGradient(const QLinearGradient &gradient) { p->gradient = gradient; update(); } void GradientSlider::setColors(const QVector &colors) { QGradientStops stops; stops.reserve(colors.size()); double c = colors.size() - 1; if(c==0) { stops.append(QGradientStop(0, colors.at(0))); } else { for(int i=0;igradient.stops(); if(stops.isEmpty()) stops.push_back(QGradientStop(0.0, c)); else stops.front().second = c; p->gradient.setStops(stops); update(); } void GradientSlider::setLastColor(const QColor &c) { QGradientStops stops = p->gradient.stops(); if(stops.size()<2) stops.push_back(QGradientStop(1.0, c)); else stops.back().second = c; p->gradient.setStops(stops); update(); } QColor GradientSlider::firstColor() const { QGradientStops s = colors(); return s.empty() ? QColor() : s.front().second; } QColor GradientSlider::lastColor() const { QGradientStops s = colors(); return s.empty() ? QColor() : s.back().second; } void GradientSlider::paintEvent(QPaintEvent *) { QPainter painter(this); QStyleOptionFrame panel; panel.initFrom(this); panel.lineWidth = 1; panel.midLineWidth = 0; panel.state |= QStyle::State_Sunken; style()->drawPrimitive(QStyle::PE_Frame, &panel, &painter, this); QRect r = style()->subElementRect(QStyle::SE_FrameContents, &panel, this); painter.setClipRect(r); qreal gradient_direction = invertedAppearance() ? -1 : 1; if(orientation() == Qt::Horizontal) p->gradient.setFinalStop(gradient_direction, 0); else p->gradient.setFinalStop(0, -gradient_direction); painter.setPen(Qt::NoPen); painter.setBrush(p->back); painter.drawRect(1,1,geometry().width()-2,geometry().height()-2); painter.setBrush(p->gradient); painter.drawRect(1,1,geometry().width()-2,geometry().height()-2); qreal pos = (maximum() != 0) ? static_cast(value() - minimum()) / maximum() : 0; QColor color; auto stops = p->gradient.stops(); int i; for (i = 0; i < stops.size(); i++) { if (stops[i].first > pos) break; } if (i == 0) { color = firstColor(); } if (i == stops.size()) { color = lastColor(); } else { auto &a = stops[i - 1]; auto &b = stops[i]; auto c = (b.first - a.first); qreal q = (c != 0) ? (pos - a.first) / c : 0; color = QColor::fromRgbF(b.second.redF() * q + a.second.redF() * (1.0 - q), b.second.greenF() * q + a.second.greenF() * (1.0 - q), b.second.blueF() * q + a.second.blueF() * (1.0 - q), b.second.alphaF() * q + a.second.alphaF() * (1.0 - q)); } pos = pos * (geometry().width() - 5); if (color.valueF() > 0.5 || color.alphaF() < 0.5) { painter.setPen(QPen(Qt::black, 3)); } else { painter.setPen(QPen(Qt::white, 3)); } QPointF p1 = QPointF(2.5, 2.5) + QPointF(pos, 0); QPointF p2 = p1 + QPointF(0, geometry().height() - 5); painter.drawLine(p1, p2); } } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/harmony_color_wheel.cpp000066400000000000000000000140541366475014400252270ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * \copyright Copyright (C) 2017 caryoscelus * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/color_wheel_private.hpp" #include "QtColorWidgets/harmony_color_wheel.hpp" namespace color_widgets { struct RingEditor { double hue_diff; bool editable; int symmetric_to; int opposite_to; RingEditor(double hue_diff, bool editable, int symmetric_to=-1, int opposite_to=-1) : hue_diff(hue_diff), editable(editable), symmetric_to(symmetric_to), opposite_to(opposite_to) { } }; class HarmonyColorWheel::Private : public ColorWheel::Private { public: using ColorWheel::Private::Private; std::vector ring_editors; int current_ring_editor = -1; /** * Puts a double into [0; 1) range */ static inline double normalize(double angle) { return angle - std::floor(angle); } }; HarmonyColorWheel::HarmonyColorWheel(QWidget *parent) : ColorWheel(parent, new Private(this)) { connect(this, SIGNAL(colorChanged(QColor)), this, SIGNAL(harmonyChanged())); p = static_cast(data()); } HarmonyColorWheel::~HarmonyColorWheel() = default; QList HarmonyColorWheel::harmonyColors() const { QList result; result.push_back(color()); for (auto const& harmony : p->ring_editors) { auto hue = Private::normalize(p->hue+harmony.hue_diff); result.push_back(p->color_from(hue, p->sat, p->val, 1)); } return result; } unsigned int HarmonyColorWheel::harmonyCount() const { return 1 + p->ring_editors.size(); } void HarmonyColorWheel::clearHarmonies() { p->ring_editors.clear(); p->current_ring_editor = -1; Q_EMIT harmonyChanged(); update(); } unsigned HarmonyColorWheel::addHarmony(double hue_diff, bool editable) { auto count = p->ring_editors.size(); p->ring_editors.emplace_back(Private::normalize(hue_diff), editable, -1, -1); Q_EMIT harmonyChanged(); update(); return count; } unsigned HarmonyColorWheel::addSymmetricHarmony(unsigned relative_to) { auto count = p->ring_editors.size(); if (relative_to >= count) throw std::out_of_range("incorrect call to addSymmetricHarmony: harmony number out of range"); auto& relative = p->ring_editors[relative_to]; relative.symmetric_to = count; p->ring_editors.emplace_back(Private::normalize(-relative.hue_diff), relative.editable, relative_to, -1); Q_EMIT harmonyChanged(); update(); return count; } unsigned HarmonyColorWheel::addOppositeHarmony(unsigned relative_to) { auto count = p->ring_editors.size(); if (relative_to >= count) throw std::out_of_range("incorrect call to addOppositeHarmony: harmony number out of range"); auto& relative = p->ring_editors[relative_to]; relative.opposite_to = count; p->ring_editors.emplace_back(Private::normalize(0.5+relative.hue_diff), relative.editable, -1, relative_to); Q_EMIT harmonyChanged(); update(); return count; } void HarmonyColorWheel::paintEvent(QPaintEvent * ev) { ColorWheel::paintEvent(ev); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.translate(geometry().width()/2,geometry().height()/2); for (auto const& editor : p->ring_editors) { auto hue = p->hue+editor.hue_diff; // TODO: better color for uneditable indicator auto color = editor.editable ? Qt::white : Qt::gray; p->draw_ring_editor(hue, painter, color); } } void HarmonyColorWheel::mousePressEvent(QMouseEvent *ev) { if ( ev->buttons() & Qt::LeftButton ) { QLineF ray = p->line_to_point(ev->pos()); if ( ray.length() <= p->outer_radius() && ray.length() > p->inner_radius() ) { p->mouse_status = DragCircle; auto hue_diff = Private::normalize(ray.angle()/360 - p->hue); auto i = 0; for (auto const& editor : p->ring_editors) { const double eps = 1.0/64; if (editor.editable && editor.hue_diff <= hue_diff + eps && editor.hue_diff >= hue_diff - eps) { p->current_ring_editor = i; // no need to update color.. return; } ++i; } } } ColorWheel::mousePressEvent(ev); } void HarmonyColorWheel::mouseMoveEvent(QMouseEvent *ev) { if ( p->mouse_status == DragCircle && p->current_ring_editor != -1 ) { auto hue = p->line_to_point(ev->pos()).angle()/360.0; auto& editor = p->ring_editors[p->current_ring_editor]; editor.hue_diff = Private::normalize(hue - p->hue); if (editor.symmetric_to != -1) { auto& symmetric = p->ring_editors[editor.symmetric_to]; symmetric.hue_diff = Private::normalize(p->hue - hue); } else if (editor.opposite_to != -1) { auto& opposite = p->ring_editors[editor.opposite_to]; opposite.hue_diff = Private::normalize(editor.hue_diff-0.5); } Q_EMIT harmonyChanged(); update(); return; } ColorWheel::mouseMoveEvent(ev); } void HarmonyColorWheel::mouseReleaseEvent(QMouseEvent *ev) { ColorWheel::mouseReleaseEvent(ev); p->current_ring_editor = -1; } } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/hue_slider.cpp000066400000000000000000000071221366475014400233110ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2014 Calle Laakkonen * \copyright Copyright (C) 2013-2020 Mattia Basaglia * \copyright Copyright (C) 2017 caryoscelus * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/hue_slider.hpp" namespace color_widgets { class HueSlider::Private { private: HueSlider *w; public: qreal saturation = 1; qreal value = 1; qreal alpha = 1; Private(HueSlider *widget) : w(widget) { w->setRange(0, 359); connect(w, &QSlider::valueChanged, [this]{ Q_EMIT w->colorHueChanged(w->colorHue()); Q_EMIT w->colorChanged(w->color()); }); updateGradient(); } void updateGradient() { static const double n_colors = 6; QGradientStops colors; colors.reserve(n_colors+1); for ( int i = 0; i <= n_colors; ++i ) colors.append(QGradientStop(i/n_colors, QColor::fromHsvF(i/n_colors, saturation, value))); w->setColors(colors); } }; HueSlider::HueSlider(QWidget *parent) : GradientSlider(parent), p(new Private(this)) { } HueSlider::HueSlider(Qt::Orientation orientation, QWidget *parent) : GradientSlider(orientation, parent), p(new Private(this)) { } HueSlider::~HueSlider() { delete p; } qreal HueSlider::colorSaturation() const { return p->saturation; } void HueSlider::setColorSaturation(qreal s) { p->saturation = qBound(0.0, s, 1.0); p->updateGradient(); Q_EMIT colorSaturationChanged(s); } qreal HueSlider::colorValue() const { return p->value; } void HueSlider::setColorValue(qreal v) { p->value = qBound(0.0, v, 1.0); p->updateGradient(); Q_EMIT colorValueChanged(v); } qreal HueSlider::colorAlpha() const { return p->alpha; } void HueSlider::setColorAlpha(qreal alpha) { p->alpha = alpha; p->updateGradient(); Q_EMIT colorAlphaChanged(alpha); } QColor HueSlider::color() const { return QColor::fromHsvF(colorHue(), p->saturation, p->value, p->alpha); } void HueSlider::setColor(const QColor& color) { p->saturation = color.saturationF(); p->value = color.valueF(); p->updateGradient(); setColorHue(color.hueF()); Q_EMIT colorValueChanged(p->alpha); Q_EMIT colorSaturationChanged(p->alpha); } void HueSlider::setFullColor(const QColor& color) { p->alpha = color.alphaF(); setColor(color); Q_EMIT colorAlphaChanged(p->alpha); } qreal HueSlider::colorHue() const { if (maximum() == minimum()) return 0; auto hue = qreal(value() - minimum()) / (maximum() - minimum()); if (orientation() == Qt::Vertical) hue = 1 - hue; return hue; } void HueSlider::setColorHue(qreal colorHue) { // TODO: consider supporting invertedAppearance? if (orientation() == Qt::Vertical) colorHue = 1 - colorHue; setValue(minimum()+colorHue*(maximum()-minimum())); Q_EMIT colorHueChanged(colorHue); Q_EMIT colorChanged(color()); } } // namespace color_widgets Qt-Color-Widgets-v2.2.0/src/QtColorWidgets/swatch.cpp000066400000000000000000000517311366475014400224640ustar00rootroot00000000000000/** * \file * * \author Mattia Basaglia * * \copyright Copyright (C) 2013-2020 Mattia Basaglia * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #include "QtColorWidgets/swatch.hpp" #include #include #include #include #include #include #include #include #include #include #include namespace color_widgets { class Swatch::Private { public: ColorPalette palette; ///< Palette with colors and related metadata int selected; ///< Current selection index (-1 for no selection) QSize color_size; ///< Preferred size for the color squares ColorSizePolicy size_policy; QPen border; int forced_rows; int forced_columns; bool readonly; ///< Whether the palette can be modified via user interaction QPoint drag_pos; ///< Point used to keep track of dragging int drag_index; ///< Index used by drags int drop_index; ///< Index for a requested drop QColor drop_color; ///< Dropped color bool drop_overwrite; ///< Whether the drop will overwrite an existing color Swatch* owner; Private(Swatch* owner) : selected(-1), color_size(16,16), size_policy(Hint), border(Qt::black, 1), forced_rows(0), forced_columns(0), readonly(false), drag_index(-1), drop_index(-1), drop_overwrite(false), owner(owner) {} /** * \brief Number of rows/columns in the palette */ QSize rowcols() { int count = palette.count(); if ( count == 0 ) return QSize(); if ( forced_rows ) return QSize(std::ceil( float(count) / forced_rows ), forced_rows); int columns = palette.columns(); if ( forced_columns ) columns = forced_columns; else if ( columns == 0 ) columns = qMin(palette.count(), owner->width() / color_size.width()); int rows = std::ceil( float(count) / columns ); return QSize(columns, rows); } /** * \brief Sets the drop properties */ void dropEvent(QDropEvent* event) { // Find the output location drop_index = owner->indexAt(event->pos()); if ( drop_index == -1 ) drop_index = palette.count(); // Gather up the color if ( event->mimeData()->hasColor() ) { drop_color = event->mimeData()->colorData().value(); drop_color.setAlpha(255); } else if ( event->mimeData()->hasText() ) { drop_color = QColor(event->mimeData()->text()); } drop_overwrite = false; QRectF drop_rect = indexRect(drop_index); if ( drop_index < palette.count() && drop_rect.isValid() ) { // 1 column => vertical style if ( palette.columns() == 1 || forced_columns == 1 ) { // Dragged to the last quarter of the size of the square, add after if ( event->posF().y() >= drop_rect.top() + drop_rect.height() * 3.0 / 4 ) drop_index++; // Dragged to the middle of the square, overwrite existing color else if ( event->posF().x() > drop_rect.top() + drop_rect.height() / 4 && ( event->dropAction() != Qt::MoveAction || event->source() != owner ) ) drop_overwrite = true; } else { // Dragged to the last quarter of the size of the square, add after if ( event->posF().x() >= drop_rect.left() + drop_rect.width() * 3.0 / 4 ) drop_index++; // Dragged to the middle of the square, overwrite existing color else if ( event->posF().x() > drop_rect.left() + drop_rect.width() / 4 && ( event->dropAction() != Qt::MoveAction || event->source() != owner ) ) drop_overwrite = true; } } owner->update(); } /** * \brief Clears drop properties */ void clearDrop() { drop_index = -1; drop_color = QColor(); drop_overwrite = false; owner->update(); } /** * \brief Actual size of a color square */ QSizeF actualColorSize() { QSize rowcols = this->rowcols(); if ( !rowcols.isValid() ) return QSizeF(); return actualColorSize(rowcols); } /** * \brief Actual size of a color square * \pre rowcols.isValid() and obtained via rowcols() */ QSizeF actualColorSize(const QSize& rowcols) { return QSizeF (float(owner->width()) / rowcols.width(), float(owner->height()) / rowcols.height()); } /** * \brief Rectangle corresponding to the color at the given index * \pre rowcols.isValid() and obtained via rowcols() * \pre color_size obtained via rowlcols(rowcols) */ QRectF indexRect(int index, const QSize& rowcols, const QSizeF& color_size) { if ( index == -1 ) return QRectF(); return QRectF( index % rowcols.width() * color_size.width(), index / rowcols.width() * color_size.height(), color_size.width(), color_size.height() ); } /** * \brief Rectangle corresponding to the color at the given index */ QRectF indexRect(int index) { QSize rc = rowcols(); if ( index == -1 || !rc.isValid() ) return QRectF(); return indexRect(index, rc, actualColorSize(rc)); } }; Swatch::Swatch(QWidget* parent) : QWidget(parent), p(new Private(this)) { connect(&p->palette, &ColorPalette::colorsChanged, this, &Swatch::paletteModified); connect(&p->palette, &ColorPalette::colorAdded, this, &Swatch::paletteModified); connect(&p->palette, &ColorPalette::colorRemoved, this, &Swatch::paletteModified); connect(&p->palette, &ColorPalette::columnsChanged, this, (void(QWidget::*)())&QWidget::update); connect(&p->palette, &ColorPalette::colorsUpdated, this, (void(QWidget::*)())&QWidget::update); connect(&p->palette, &ColorPalette::colorChanged, [this](int index){ if ( index == p->selected ) Q_EMIT colorSelected( p->palette.colorAt(index) ); }); setFocusPolicy(Qt::StrongFocus); setAcceptDrops(true); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); setAttribute(Qt::WA_Hover, true); } Swatch::~Swatch() { delete p; } QSize Swatch::sizeHint() const { QSize rowcols = p->rowcols(); if ( !p->color_size.isValid() || !rowcols.isValid() ) return QSize(); return QSize( p->color_size.width() * rowcols.width(), p->color_size.height() * rowcols.height() ); } QSize Swatch::minimumSizeHint() const { if ( p->size_policy != Hint ) return sizeHint(); return QSize(); } const ColorPalette& Swatch::palette() const { return p->palette; } ColorPalette& Swatch::palette() { return p->palette; } int Swatch::selected() const { return p->selected; } QColor Swatch::selectedColor() const { return p->palette.colorAt(p->selected); } int Swatch::indexAt(const QPoint& pt) { QSize rowcols = p->rowcols(); if ( rowcols.isEmpty() ) return -1; QSizeF color_size = p->actualColorSize(rowcols); QPoint point( qBound(0, pt.x() / color_size.width(), rowcols.width() - 1), qBound(0, pt.y() / color_size.height(), rowcols.height() - 1) ); int index = point.y() * rowcols.width() + point.x(); if ( index >= p->palette.count() ) return -1; return index; } QColor Swatch::colorAt(const QPoint& pt) { return p->palette.colorAt(indexAt(pt)); } void Swatch::setPalette(const ColorPalette& palette) { clearSelection(); p->palette = palette; update(); Q_EMIT paletteChanged(p->palette); } void Swatch::setSelected(int selected) { if ( selected < 0 || selected >= p->palette.count() ) selected = -1; if ( selected != p->selected ) { Q_EMIT selectedChanged( p->selected = selected ); if ( selected != -1 ) Q_EMIT colorSelected( p->palette.colorAt(p->selected) ); update(); } } void Swatch::clearSelection() { setSelected(-1); } void Swatch::paintEvent(QPaintEvent* event) { Q_UNUSED(event) QSize rowcols = p->rowcols(); if ( rowcols.isEmpty() ) return; QSizeF color_size = p->actualColorSize(rowcols); QPainter painter(this); QStyleOptionFrame panel; panel.initFrom(this); panel.lineWidth = 1; panel.midLineWidth = 0; panel.state |= QStyle::State_Sunken; style()->drawPrimitive(QStyle::PE_Frame, &panel, &painter, this); QRect r = style()->subElementRect(QStyle::SE_FrameContents, &panel, this); painter.setClipRect(r); int count = p->palette.count(); painter.setPen(p->border); for ( int y = 0, i = 0; i < count; y++ ) { for ( int x = 0; x < rowcols.width() && i < count; x++, i++ ) { painter.setBrush(p->palette.colorAt(i)); painter.drawRect(p->indexRect(i, rowcols, color_size)); } } painter.setClipping(false); if ( p->drop_index != -1 ) { QRectF drop_area = p->indexRect(p->drop_index, rowcols, color_size); if ( p->drop_overwrite ) { painter.setBrush(p->drop_color); painter.setPen(QPen(Qt::gray)); painter.drawRect(drop_area); } else if ( rowcols.width() == 1 ) { // 1 column => vertical style painter.setPen(QPen(p->drop_color, 2)); painter.setBrush(Qt::transparent); painter.drawLine(drop_area.topLeft(), drop_area.topRight()); } else { painter.setPen(QPen(p->drop_color, 2)); painter.setBrush(Qt::transparent); painter.drawLine(drop_area.topLeft(), drop_area.bottomLeft()); // Draw also on the previous line when the first item of a line is selected if ( p->drop_index % rowcols.width() == 0 && p->drop_index != 0 ) { drop_area = p->indexRect(p->drop_index-1, rowcols, color_size); drop_area.translate(color_size.width(), 0); painter.drawLine(drop_area.topLeft(), drop_area.bottomLeft()); } } } if ( p->selected != -1 ) { QRectF rect = p->indexRect(p->selected, rowcols, color_size); painter.setBrush(Qt::transparent); painter.setPen(QPen(Qt::darkGray, 2)); painter.drawRect(rect); painter.setPen(QPen(Qt::gray, 2, Qt::DotLine)); painter.drawRect(rect); } } void Swatch::keyPressEvent(QKeyEvent* event) { if ( p->palette.count() == 0 ) QWidget::keyPressEvent(event); int selected = p->selected; int count = p->palette.count(); QSize rowcols = p->rowcols(); int columns = rowcols.width(); int rows = rowcols.height(); switch ( event->key() ) { default: QWidget::keyPressEvent(event); return; case Qt::Key_Left: if ( selected == -1 ) selected = count - 1; else if ( selected > 0 ) selected--; break; case Qt::Key_Right: if ( selected == -1 ) selected = 0; else if ( selected < count - 1 ) selected++; break; case Qt::Key_Up: if ( selected == -1 ) selected = count - 1; else if ( selected >= columns ) selected -= columns; break; case Qt::Key_Down: if ( selected == -1 ) selected = 0; else if ( selected < count - columns ) selected += columns; break; case Qt::Key_Home: if ( event->modifiers() & Qt::ControlModifier ) selected = 0; else selected -= selected % columns; break; case Qt::Key_End: if ( event->modifiers() & Qt::ControlModifier ) selected = count - 1; else selected += columns - (selected % columns) - 1; break; case Qt::Key_Delete: removeSelected(); return; case Qt::Key_Backspace: if (selected != -1 && !p->readonly ) { p->palette.eraseColor(selected); if ( p->palette.count() == 0 ) selected = -1; else selected = qMax(selected - 1, 0); } break; case Qt::Key_PageUp: if ( selected == -1 ) selected = 0; else selected = selected % columns; break; case Qt::Key_PageDown: if ( selected == -1 ) { selected = count - 1; } else { selected = columns * (rows-1) + selected % columns; if ( selected >= count ) selected -= columns; } break; } setSelected(selected); } void Swatch::removeSelected() { if (p->selected != -1 && !p->readonly ) { int selected = p->selected; p->palette.eraseColor(p->selected); setSelected(qMin(selected, p->palette.count() - 1)); } } void Swatch::mousePressEvent(QMouseEvent *event) { if ( event->button() == Qt::LeftButton ) { setSelected(indexAt(event->pos())); p->drag_pos = event->pos(); p->drag_index = indexAt(event->pos()); } else if ( event->button() == Qt::RightButton ) { int index = indexAt(event->pos()); if ( index != -1 ) Q_EMIT rightClicked(index); } } void Swatch::mouseMoveEvent(QMouseEvent *event) { if ( p->drag_index != -1 && (event->buttons() & Qt::LeftButton) && (p->drag_pos - event->pos()).manhattanLength() >= QApplication::startDragDistance() ) { QColor color = p->palette.colorAt(p->drag_index); QPixmap preview(24,24); preview.fill(color); QMimeData *mimedata = new QMimeData; mimedata->setColorData(color); mimedata->setText(p->palette.nameAt(p->drag_index)); QDrag *drag = new QDrag(this); drag->setMimeData(mimedata); drag->setPixmap(preview); Qt::DropActions actions = Qt::CopyAction; if ( !p->readonly ) actions |= Qt::MoveAction; drag->exec(actions); } } void Swatch::mouseReleaseEvent(QMouseEvent *event) { if ( event->button() == Qt::LeftButton ) { p->drag_index = -1; } } void Swatch::mouseDoubleClickEvent(QMouseEvent *event) { if ( event->button() == Qt::LeftButton ) { int index = indexAt(event->pos()); if ( index != -1 ) Q_EMIT doubleClicked(index); } } void Swatch::wheelEvent(QWheelEvent* event) { if ( event->delta() > 0 ) p->selected = qMin(p->selected + 1, p->palette.count() - 1); else if ( p->selected == -1 ) p->selected = p->palette.count() - 1; else if ( p->selected > 0 ) p->selected--; setSelected(p->selected); } void Swatch::dragEnterEvent(QDragEnterEvent *event) { if ( p->readonly ) return; p->dropEvent(event); if ( p->drop_color.isValid() && p->drop_index != -1 ) { if ( event->proposedAction() == Qt::MoveAction && event->source() == this ) event->setDropAction(Qt::MoveAction); else event->setDropAction(Qt::CopyAction); event->accept(); } } void Swatch::dragMoveEvent(QDragMoveEvent* event) { if ( p->readonly ) return; p->dropEvent(event); } void Swatch::dragLeaveEvent(QDragLeaveEvent *event) { Q_UNUSED(event) p->clearDrop(); } void Swatch::dropEvent(QDropEvent *event) { if ( p->readonly ) return; QString name; // Gather up the color if ( event->mimeData()->hasColor() && event->mimeData()->hasText() ) name = event->mimeData()->text(); // Not a color, discard if ( !p->drop_color.isValid() || p->drop_index == -1 ) return; p->dropEvent(event); // Move unto self if ( event->dropAction() == Qt::MoveAction && event->source() == this ) { // Not moved => noop if ( p->drop_index != p->drag_index && p->drop_index != p->drag_index + 1 ) { // Erase the old color p->palette.eraseColor(p->drag_index); if ( p->drop_index > p->drag_index ) p->drop_index--; p->selected = p->drop_index; // Insert the dropped color p->palette.insertColor(p->drop_index, p->drop_color, name); } } // Move into a color cell else if ( p->drop_overwrite ) { p->palette.setColorAt(p->drop_index, p->drop_color, name); } // Insert the dropped color else { p->palette.insertColor(p->drop_index, p->drop_color, name); } // Finalize event->accept(); p->drag_index = -1; p->clearDrop(); } void Swatch::paletteModified() { if ( p->selected >= p->palette.count() ) clearSelection(); if ( p->size_policy != Hint ) { QSize size_hint = sizeHint(); if ( size_hint.isValid() ) { if ( p->size_policy == Minimum ) setMinimumSize(size_hint); else if ( p->size_policy == Fixed ) setFixedSize(size_hint); } } update(); } QSize Swatch::colorSize() const { return p->color_size; } void Swatch::setColorSize(const QSize& colorSize) { if ( p->color_size != colorSize ) Q_EMIT colorSizeChanged(p->color_size = colorSize); } Swatch::ColorSizePolicy Swatch::colorSizePolicy() const { return p->size_policy; } void Swatch::setColorSizePolicy(ColorSizePolicy colorSizePolicy) { if ( p->size_policy != colorSizePolicy ) { setMinimumSize(0,0); setFixedSize(QWIDGETSIZE_MAX,QWIDGETSIZE_MAX); Q_EMIT colorSizePolicyChanged(p->size_policy = colorSizePolicy); paletteModified(); } } int Swatch::forcedColumns() const { return p->forced_columns; } int Swatch::forcedRows() const { return p->forced_rows; } void Swatch::setForcedColumns(int forcedColumns) { if ( forcedColumns <= 0 ) forcedColumns = 0; if ( forcedColumns != p->forced_columns ) { Q_EMIT forcedColumnsChanged(p->forced_columns = forcedColumns); Q_EMIT forcedRowsChanged(p->forced_rows = 0); } } void Swatch::setForcedRows(int forcedRows) { if ( forcedRows <= 0 ) forcedRows = 0; if ( forcedRows != p->forced_rows ) { Q_EMIT forcedColumnsChanged(p->forced_columns = 0); Q_EMIT forcedRowsChanged(p->forced_rows = forcedRows); } } bool Swatch::readOnly() const { return p->readonly; } void Swatch::setReadOnly(bool readOnly) { if ( readOnly != p->readonly ) { Q_EMIT readOnlyChanged(p->readonly = readOnly); setAcceptDrops(!p->readonly); } } bool Swatch::event(QEvent* event) { if(event->type() == QEvent::ToolTip) { QHelpEvent* help_ev = static_cast(event); int index = indexAt(help_ev->pos()); if ( index != -1 ) { QColor color = p->palette.colorAt(index); QString name = p->palette.nameAt(index); QString message = color.name(); if ( !name.isEmpty() ) message = tr("%1 (%2)").arg(name).arg(message); message = "MM "+message.toHtmlEscaped(); QToolTip::showText(help_ev->globalPos(), message, this, p->indexRect(index).toRect()); event->accept(); } else { QToolTip::hideText(); event->ignore(); } return true; } return QWidget::event(event); } QPen Swatch::border() const { return p->border; } void Swatch::setBorder(const QPen& border) { if ( border != p->border ) { p->border = border; Q_EMIT borderChanged(border); update(); } } } // namespace color_widgets