pax_global_header00006660000000000000000000000064137707323130014520gustar00rootroot0000000000000052 comment=7bb19b8007c4b94e10720c341344da42ba6c0cab gpick-gpick-0.2.6/000077500000000000000000000000001377073231300137155ustar00rootroot00000000000000gpick-gpick-0.2.6/.azure-pipelines/000077500000000000000000000000001377073231300171075ustar00rootroot00000000000000gpick-gpick-0.2.6/.azure-pipelines/ubuntu-latest.yml000066400000000000000000000024661377073231300224560ustar00rootroot00000000000000trigger: - master jobs: - job: build_on_ubuntu_latest strategy: maxParallel: 2 matrix: gcc_gtk3_lua52: publish_prefix: gcc-gtk3-lua52 lua_package: liblua5.2-dev gcc_gtk3_lua53: publish_prefix: gcc-gtk3-lua53 lua_package: liblua5.3-dev pool: vmImage: ubuntu-latest steps: - script: > sudo apt-get update && sudo apt-get install git ragel g++ gcc gettext libgtk-3-dev $(lua_package) libexpat1-dev libboost-filesystem-dev libboost-system-dev libboost-test-dev - task: CMake@1 inputs: workingDirectory: 'build' cmakeArgs: '-G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$(Build.ArtifactStagingDirectory)/ ..' - script: | cmake --build . --config Release workingDirectory: 'build' - script: | ./build/tests --log_format=JUNIT --report_format=HRF -k tests-log.xml -e tests-report.txt --no_result_code workingDirectory: '' - task: PublishTestResults@2 inputs: testResultsFormat: 'JUnit' testResultsFiles: 'tests-*.xml' - script: | cmake --build . --config Release --target install workingDirectory: 'build' - task: PublishBuildArtifacts@1 inputs: artifactName: $(publish_prefix)-ubuntu-latest pathToPublish: '$(Build.ArtifactStagingDirectory)' gpick-gpick-0.2.6/.gitignore000066400000000000000000000002321377073231300157020ustar00rootroot00000000000000.* *~ *.orig *.diff diff *.save *.old *.bak .*.swp *.out *.pyc *.log *.mo *.msm *.wixobj *.wixpdb *.msi *.pdb installer/files/* user-config.py build tags gpick-gpick-0.2.6/.hgignore000066400000000000000000000002471377073231300155230ustar00rootroot00000000000000syntax: glob .* *~ *.orig *.diff diff *.save *.old *.bak .*.swp *.out *.pyc *.log *.mo *.msm *.wixobj *.wixpdb *.msi *.pdb installer/files/* user-config.py build tags gpick-gpick-0.2.6/CMakeLists.txt000066400000000000000000000164451377073231300164670ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.1) project(gpick) option(ENABLE_NLS "compile with gettext support" true) option(USE_GTK3 "use GTK3 instead of GTK2" true) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") file(GLOB SOURCES source/*.cpp source/*.h source/color_names/*.cpp source/color_names/*.h source/dbus/*.cpp source/dbus/*.h source/dbus/*.c source/gtk/*.cpp source/gtk/*.h source/i18n/*.cpp source/i18n/*.h source/layout/*.cpp source/layout/*.h source/lua/*.cpp source/lua/*.h source/tools/*.cpp source/tools/*.h source/transformation/*.cpp source/transformation/*.h ) list(REMOVE_ITEM SOURCES source/Color.cpp source/Color.h source/MathUtil.cpp source/MathUtil.h source/lua/Script.cpp source/lua/Script.h) include(Version) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/source/version/Version.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/Version.cpp" @ONLY) list(APPEND SOURCES "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/Version.cpp") find_package(Boost 1.58 COMPONENTS filesystem system unit_test_framework REQUIRED) find_package(PkgConfig) if (PkgConfig_FOUND) if (USE_GTK3) pkg_check_modules(GTK3 gtk+-3.0>=3.0) else() pkg_check_modules(GTK2 gtk+-2.0>=2.24) pkg_check_modules(GioUnix gio-unix-2.0>=2.24) endif() pkg_search_module(Lua lua5.4>=5.4 lua5>=5.4 lua5.3>=5.3 lua5>=5.3 lua>=5.3 lua5.2>=5.2 lua>=5.2) pkg_check_modules(Expat expat>=1.0) endif (PkgConfig_FOUND) set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) find_package(Ragel 6.9 REQUIRED) function(set_compile_options target) if (MSVC) target_compile_options(${target} PRIVATE /MD /utf-8) target_compile_options(${target} PRIVATE $<$:/TP>) target_compile_definitions(${target} PRIVATE UNICODE GSEAL_ENABLE) if (ENABLE_NLS) target_compile_definitions(${target} PRIVATE ENABLE_NLS) endif() else() target_compile_options(${target} PRIVATE -Wall -Wfloat-conversion) target_compile_options(${target} PRIVATE $<$:-std=c++14>) if (ENABLE_NLS) target_compile_definitions(${target} PRIVATE ENABLE_NLS "LOCALEDIR=${CMAKE_INSTALL_PREFIX}/share/locale") endif() endif() endfunction() function(add_gtk_options target) if (USE_GTK3) target_link_libraries(${target} PRIVATE ${GTK3_LIBRARIES} ) target_include_directories(${target} PRIVATE ${GTK3_INCLUDE_DIRS} ) else() target_link_libraries(${target} PRIVATE ${GTK2_LIBRARIES} ${GioUnix_LIBRARIES} ) target_include_directories(${target} PRIVATE ${GTK2_INCLUDE_DIRS} ${GioUnix_INCLUDE_DIRS} ) endif() endfunction() file(GLOB MATH_SOURCES source/MathUtil.cpp source/MathUtil.h) add_library(gpick-math ${MATH_SOURCES}) set_compile_options(gpick-math) target_include_directories(gpick-math PRIVATE source ${Boost_INCLUDE_DIRS} ) file(GLOB COLOR_SOURCES source/Color.cpp source/Color.h) add_library(gpick-color ${COLOR_SOURCES}) set_compile_options(gpick-color) target_link_libraries(gpick-color PRIVATE gpick-math) target_include_directories(gpick-color PRIVATE source ${Boost_INCLUDE_DIRS} ) file(GLOB COMMON_SOURCES source/common/*.cpp source/common/*.h) add_library(gpick-common ${COMMON_SOURCES}) set_compile_options(gpick-common) target_include_directories(gpick-common PRIVATE source ${Boost_INCLUDE_DIRS} ) file(GLOB DYNV_SOURCES source/dynv/*.cpp source/dynv/*.h) add_library(gpick-dynv ${DYNV_SOURCES}) set_compile_options(gpick-dynv) target_link_libraries(gpick-dynv PRIVATE gpick-color) target_include_directories(gpick-dynv PRIVATE source ${Expat_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ) file(GLOB LUA_SOURCES source/lua/Script.cpp source/lua/Script.h) add_library(gpick-lua ${LUA_SOURCES}) set_compile_options(gpick-lua) target_link_libraries(gpick-lua PRIVATE ${Lua_LIBRARIES} ) target_include_directories(gpick-lua PRIVATE source ${Lua_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ) file(GLOB PARSER_SOURCES source/parser/*.cpp source/parser/*.h) ragel_target(text_file_parser source/parser/TextFileParser.rl ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/TextFileParser.cpp) list(APPEND PARSER_SOURCES ${RAGEL_text_file_parser_OUTPUTS}) add_library(gpick-parser ${PARSER_SOURCES}) set_compile_options(gpick-parser) target_include_directories(gpick-parser PRIVATE source ${Boost_INCLUDE_DIRS} ) if (ENABLE_NLS) find_package(Gettext REQUIRED) file(GLOB TRANSLATIONS share/locale/*/LC_MESSAGES/gpick.po) foreach(translation ${TRANSLATIONS}) file(RELATIVE_PATH name "${CMAKE_CURRENT_SOURCE_DIR}" ${translation}) get_filename_component(dir ${name} DIRECTORY) msgfmt_target(translation ${translation} ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${dir}/gpick.mo) set(MSGFMT_translation_COMPILE_FLAGS "--check-format --check-domain") list(APPEND TRANSLATION_FILES ${MSGFMT_translation_OUTPUTS}) endforeach() add_custom_target(translations ALL DEPENDS ${TRANSLATION_FILES}) file(GLOB LUA_SOURCES share/gpick/*.lua) add_custom_target(template COMMAND ${XGETTEXT_EXECUTABLE} --keyword=_ --keyword=N_ --from-code=UTF-8 --package-name=gpick --package-version=0.0 --output=${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/template_c.pot ${SOURCES} COMMAND ${XGETTEXT_EXECUTABLE} --language=C++ --keyword=_ --keyword=N_ --from-code=UTF-8 --package-name=gpick --package-version=0.0 --output=${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/template_lua.pot ${LUA_SOURCES} COMMAND ${MSGCAT_EXECUTABLE} --use-first ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/template_c.pot ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/template_lua.pot --output-file=${CMAKE_CURRENT_BINARY_DIR}/template.pot ) endif() add_executable(gpick ${SOURCES}) set_compile_options(gpick) add_gtk_options(gpick) target_link_libraries(gpick PRIVATE gpick-color gpick-math gpick-dynv gpick-lua gpick-parser gpick-common ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Lua_LIBRARIES} ${Expat_LIBRARIES} Threads::Threads ) target_include_directories(gpick PRIVATE source ${Boost_INCLUDE_DIRS} ${Lua_INCLUDE_DIRS} ${Expat_INCLUDE_DIRS} ) file(GLOB TESTS_SOURCES source/test/*.cpp source/test/*.h) add_executable(tests ${TESTS_SOURCES}) set_compile_options(tests) target_compile_definitions(tests PRIVATE BOOST_TEST_DYN_LINK) target_link_libraries(tests PRIVATE gpick-color gpick-math gpick-dynv gpick-lua gpick-parser gpick-common ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} ${Lua_LIBRARIES} ${Expat_LIBRARIES} Threads::Threads ) target_include_directories(tests PRIVATE source ${Boost_INCLUDE_DIRS} ${Lua_INCLUDE_DIRS} ${Expat_INCLUDE_DIRS} ) install(TARGETS gpick DESTINATION bin) install(FILES share/metainfo/gpick.appdata.xml DESTINATION share/metainfo) install(FILES share/applications/gpick.desktop DESTINATION share/applications) install(FILES share/mime/packages/gpick.xml DESTINATION share/mime/packages) install(FILES share/doc/gpick/copyright DESTINATION share/doc/gpick) install(FILES share/man/man1/gpick.1 DESTINATION share/man/man1) file(GLOB RESOURCE_FILES share/gpick/*.png share/gpick/*.lua share/gpick/*.txt) install(FILES ${RESOURCE_FILES} DESTINATION share/gpick) install(DIRECTORY share/icons DESTINATION share) if (ENABLE_NLS) foreach(translation ${TRANSLATION_FILES}) file(RELATIVE_PATH name "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}" ${translation}) get_filename_component(dir ${name} DIRECTORY) install(FILES ${translation} DESTINATION ${dir}) endforeach() endif() gpick-gpick-0.2.6/LICENSE.txt000066400000000000000000000027501377073231300155440ustar00rootroot00000000000000BSD 3-Clause License Copyright (c) 2009-2016, Albertas Vyšniauskas All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. gpick-gpick-0.2.6/README.md000066400000000000000000000047471377073231300152100ustar00rootroot00000000000000# Gpick - advanced color picker and palette editor. [![Build Status](https://dev.azure.com/thezbyg/Gpick/_apis/build/status/thezbyg.gpick?branchName=master)](https://dev.azure.com/thezbyg/Gpick/_build/latest?definitionId=1&branchName=master) Gpick is an application that allows you to sample any color from anywhere on the desktop, and use it to create palettes (i.e. collections of colors) for use in graphic design applications. Gpick also has other features that help in the creation of color palettes, such as: * The ability to create a palette from an imported image * Automatic naming of colors * Color scheme generator * Import and export from various file formats ## Building from source ### Compiler Some of C++14 features are required. Compilation is currently only tested on gcc version 5.3.1. ### Build dependencies SCons 2.4 or newer: a software construction tool ([http://www.scons.org](http://www.scons.org)). CMake 3.1 or newer: build process management application ([https://cmake.org/](https://cmake.org/)). Either SCons or CMake can be used. Ragel 6.8 or newer: state machine compiler ([http://www.colm.net/open-source/ragel](http://www.colm.net/open-source/ragel)). ### Dependencies GTK+ 2.24 ([http://www.gtk.org](http://www.gtk.org)). GTK+ 3.0 ([http://www.gtk.org](http://www.gtk.org)). Either GTK+ 2.x or GTK+ 3.x can be used. Lua 5.4, 5.3 or 5.2 ([http://www.lua.org](http://www.lua.org)). Expat ([http://expat.sourceforge.net](http://expat.sourceforge.net)). Boost 1.58 or newer ([http://www.boost.org](http://www.boost.org)). Used libraries: * Filesystem. * System. * Interprocess. * Test (only when building/running tests). ### Optional dependencies gettext ([http://www.gnu.org/s/gettext](http://www.gnu.org/s/gettext)). Required if ENABLE\_NLS is enabled. Required by default. ### Building Using SCons: `scons` to compile all files and place executable file in `build/source/`. `scons install` to install executable and resources to `DESTDIR`. By default `DESTDIR` is `/usr/local`. Using CMake: `mkdir build && cd build` to create out-of-source build directory. `cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local` to prepare build files for installation to '/usr/local'. `make` to compile all files. `make install` to install executable and resources to `DESTDIR`. Default `DESTDIR` value is set by `CMAKE_INSTALL_PREFIX` variable. ### Build options ENABLE\_NLS - compile with gettext support. Enabled by default. USE\_GTK3 - use GTK3 instead of GTK2. Enabled by default. gpick-gpick-0.2.6/SConscript000066400000000000000000000366731377073231300157460ustar00rootroot00000000000000#!/usr/bin/env python # coding: utf-8 import os, string, sys, shutil, math from tools import * env = GpickEnvironment(ENV = os.environ, BUILDERS = {'WriteNsisVersion': Builder(action = WriteNsisVersion, suffix = ".nsi")}) vars = Variables(os.path.join(env.GetLaunchDir(), 'user-config.py')) vars.Add('DESTDIR', 'Directory to install under', '/usr/local') vars.Add('LOCALEDIR', 'Path to locale directory', '') vars.Add('DEBARCH', 'Debian package architecture', 'i386') vars.Add(BoolVariable('ENABLE_NLS', 'Compile with gettext support', True)) vars.Add(BoolVariable('DEBUG', 'Compile with debug information', False)) vars.Add('BUILD_TARGET', 'Build target', '') vars.Add('TOOLCHAIN', 'Toolchain', 'gcc') vars.Add('MSVS_VERSION', 'Visual Studio version', '11.0') vars.Add(BoolVariable('PREBUILD_GRAMMAR', 'Use prebuild grammar files', False)) vars.Add(BoolVariable('USE_GTK3', 'Use GTK3 instead of GTK2', False)) vars.Update(env) if env['LOCALEDIR'] == '': env['LOCALEDIR'] = env['DESTDIR'] + '/share/locale' v = Variables(os.path.join(env.GetLaunchDir(), 'version.py')) v.Add('GPICK_BUILD_VERSION', '', '0.0') v.Update(env) if not env['BUILD_TARGET']: env['BUILD_TARGET'] = sys.platform if env['BUILD_TARGET'] == 'win32': if env['TOOLCHAIN'] == 'msvc': env['TARGET_ARCH'] = 'x86' env['MSVS'] = {'VERSION': env['MSVS_VERSION']} env['MSVC_VERSION'] = env['MSVS_VERSION'] env["MSVC_SETUP_RUN"] = False Tool('msvc')(env) else: if sys.platform != 'win32': env.Tool('crossmingw', toolpath = ['tools']) else: env.Tool('mingw') env.AddCustomBuilders() env.GetVersionInfo() try: umask = os.umask(0o022) except OSError: # ignore on systems that don't support umask pass if 'CC' in os.environ: env['CC'] = os.environ['CC'] if 'CFLAGS' in os.environ: env['CCFLAGS'] += SCons.Util.CLVar(os.environ['CFLAGS']) if 'CXX' in os.environ: env['CXX'] = os.environ['CXX'] if 'CXXFLAGS' in os.environ: env['CXXFLAGS'] += SCons.Util.CLVar(os.environ['CXXFLAGS']) if 'LDFLAGS' in os.environ: env['LINKFLAGS'] += SCons.Util.CLVar(os.environ['LDFLAGS']) if not env.GetOption('clean'): conf = Configure(env) programs = {} if env['ENABLE_NLS']: programs['GETTEXT'] = {'checks':{'msgfmt': 'GETTEXT'}} programs['XGETTEXT'] = {'checks':{'xgettext': 'XGETTEXT'}, 'required': False} programs['MSGMERGE'] = {'checks':{'msgmerge': 'MSGMERGE'}, 'required': False} programs['MSGCAT'] = {'checks':{'msgcat': 'MSGCAT'}, 'required': False} programs['RAGEL'] = {'checks':{'ragel': 'RAGEL'}} env.ConfirmPrograms(conf, programs) libs = {} if not env['TOOLCHAIN'] == 'msvc': if not env['USE_GTK3']: libs['GTK_PC'] = {'checks':{'gtk+-2.0': '>= 2.24.0'}} libs['GIO_PC'] = {'checks':{'gio-unix-2.0': '>= 2.26.0', 'gio-2.0': '>= 2.26.0'}} else: libs['GTK_PC'] = {'checks':{'gtk+-3.0': '>= 3.0.0'}} libs['LUA_PC'] = {'checks':{'lua5.4': '>= 5.4', 'lua5.3': '>= 5.3', 'lua': '>= 5.2', 'lua5.2': '>= 5.2'}} env.ConfirmLibs(conf, libs) env.ConfirmBoost(conf, '1.58') env = conf.Finish() Decider('MD5-timestamp') if not env['TOOLCHAIN'] == 'msvc': if not ('CFLAGS' in os.environ or 'CXXFLAGS' in os.environ or 'LDFLAGS' in os.environ): if env['DEBUG']: env.Append( CXXFLAGS = ['-Wall', '-g3', '-O0'], CFLAGS = ['-Wall', '-g3', '-O0'], LINKFLAGS = ['-Wl,-as-needed'], ) else: env.Append( CPPDEFINES = ['NDEBUG'], CDEFINES = ['NDEBUG'], CXXFLAGS = ['-Wall', '-O3'], CFLAGS = ['-Wall', '-O3'], LINKFLAGS = ['-Wl,-as-needed', '-s'], ) env.Append( CXXFLAGS = ['-std=c++14'], ) else: stdMissing = True for flag in env['CXXFLAGS']: if flag.startswith('-std='): stdMissing = False break if stdMissing: env.Append( CXXFLAGS = ['-std=c++14'], ) if env['BUILD_TARGET'] == 'win32': env.Append( LINKFLAGS = ['-Wl,--enable-auto-import', '-static-libgcc', '-static-libstdc++'], CPPDEFINES = ['_WIN32_WINNT=0x0501'], ) else: env['LINKCOM'] = [env['LINKCOM'], 'mt.exe -nologo -manifest ${TARGET}.manifest -outputresource:$TARGET;1'] if env['DEBUG']: env.Append( CXXFLAGS = ['/Od', '/EHsc', '/MD', '/Gy', '/Zi', '/TP', '/wd4819'], CPPDEFINES = ['WIN32', '_DEBUG', 'NOMINMAX'], LINKFLAGS = ['/MANIFEST', '/DEBUG'], ) else: env.Append( CXXFLAGS = ['/O2', '/Oi', '/GL', '/EHsc', '/MD', '/Gy', '/Zi', '/TP', '/wd4819'], CPPDEFINES = ['WIN32', 'NDEBUG', 'NOMINMAX'], LINKFLAGS = ['/MANIFEST', '/LTCG'], ) env.Append(CPPPATH = ['#source']) def buildVersion(env): version_env = env.Clone() version_env.Append(CPPDEFINES = { 'BUILD_DATE': env['GPICK_BUILD_DATE'], 'BUILD_REVISION': env['GPICK_BUILD_REVISION'], 'BUILD_PLATFORM': sys.platform, 'BUILD_VERSION': env['GPICK_BUILD_VERSION'], }) return version_env.StaticObject(version_env.Glob('source/version/*.cpp')) def buildLayout(env): layout_env = env.Clone() if not env.GetOption('clean') and not env['TOOLCHAIN'] == 'msvc': layout_env.ParseConfig('pkg-config --cflags --libs $GTK_PC') layout_env.ParseConfig('pkg-config --cflags --libs $LUA_PC') return layout_env.StaticObject(layout_env.Glob('source/layout/*.cpp')) def buildGtk(env): gtk_env = env.Clone() if not env.GetOption('clean') and not env['TOOLCHAIN'] == 'msvc': gtk_env.ParseConfig('pkg-config --cflags --libs $GTK_PC') gtk_env.ParseConfig('pkg-config --cflags --libs $LUA_PC') return gtk_env.StaticObject(gtk_env.Glob('source/gtk/*.cpp')) def buildI18n(env): i18n_env = env.Clone() if not env.GetOption('clean'): if i18n_env['ENABLE_NLS']: i18n_env.Append(CPPDEFINES = ['ENABLE_NLS', 'LOCALEDIR=' + i18n_env['LOCALEDIR']]) return i18n_env.StaticObject(i18n_env.Glob('source/i18n/*.cpp')) def buildDbus(env): dbus_env = env.Clone() if not env.GetOption('clean') and not env['TOOLCHAIN'] == 'msvc': if not env['USE_GTK3']: dbus_env.ParseConfig('pkg-config --cflags $GIO_PC') else: dbus_env.ParseConfig('pkg-config --cflags $GTK_PC') if not env['BUILD_TARGET'] == 'win32': sources = dbus_env.Glob('source/dbus/*.c') + dbus_env.Glob('source/dbus/*.cpp') else: sources = dbus_env.Glob('source/dbus/*.cpp') return dbus_env.StaticObject(sources) def buildTools(env): tools_env = env.Clone() if not env.GetOption('clean') and not env['TOOLCHAIN'] == 'msvc': tools_env.ParseConfig('pkg-config --cflags --libs $GTK_PC') tools_env.ParseConfig('pkg-config --cflags --libs $LUA_PC') if tools_env['ENABLE_NLS']: tools_env.Append(CPPDEFINES = ['ENABLE_NLS']) return tools_env.StaticObject(tools_env.Glob('source/tools/*.cpp')) def buildLua(env): lua_env = env.Clone() if not env.GetOption('clean') and not env['TOOLCHAIN'] == 'msvc': lua_env.ParseConfig('pkg-config --cflags --libs $GTK_PC') lua_env.ParseConfig('pkg-config --cflags --libs $LUA_PC') return lua_env.StaticObject(lua_env.Glob('source/lua/*.cpp')) def buildColorNames(env): return env.StaticObject(env.Glob('source/color_names/*.cpp')) def buildWindowsResources(env): resources_env = env.Clone() resources_env.Append(RESOURCE_TEMPLATE_VARS = { 'VERSION': env['GPICK_BUILD_VERSION'], 'VERSION_COMMA': env['GPICK_BUILD_VERSION'].replace('.', ','), 'REVISION': env['GPICK_BUILD_REVISION'], 'BUILD_DATE': env['GPICK_BUILD_DATE'], }) resources = resources_env.AlwaysBuild(resources_env.ResourceTemplate(resources_env.Glob('source/winres/*.rct'))) objects = resources_env.RES(resources) Command("source/winres/gpick-icon.ico", File("source/winres/gpick-icon.ico").srcnode(), Copy("$TARGET", "${SOURCE}")) if not (env['TOOLCHAIN'] == 'msvc'): Command("source/winres/gpick.exe.manifest", File("source/winres/gpick.exe.manifest").srcnode(), Copy("$TARGET", "${SOURCE}")) Depends(resources, 'source/winres/gpick-icon.ico') if not (env['TOOLCHAIN'] == 'msvc'): Depends(resources, 'source/winres/gpick.exe.manifest') return objects def addDebianPackageAlias(env): DEBNAME = "gpick" DEBVERSION = str(env['GPICK_BUILD_VERSION'])+"-1" DEBMAINT = "Albertas Vyšniauskas " DEBARCH = env['DEBARCH'] DEBDEPENDS = "libgtk2.0-0 (>= 2.24), libc6 (>= 2.13), liblua5.2-0 (>= 5.2), libcairo2 (>=1.8), libglib2.0-0 (>=2.24)" DEBPRIORITY = "optional" DEBSECTION = "graphics" DEBDESC = "Advanced color picker" DEBDESCLONG = """ Gpick is a program used to pick colors from anywhere on the screen, mix them to get new colors, generate shades and tints and export palettes to common file formats or simply copy them to the clipboard """ DEBPACKAGEFILE = '%s_%s_%s.deb' % (DEBNAME, DEBVERSION, DEBARCH) CONTROL_TEMPLATE = """Package: %s Version: %s Section: %s Priority: %s Architecture: %s Depends: %s Installed-Size: %s Maintainer: %s Description: %s %s""" DEBCONTROLDIR = os.path.join("deb", DEBNAME, "DEBIAN") DEBCONTROLFILE = os.path.join(DEBCONTROLDIR, "control") DEBINSTALLDIR = os.path.join('deb' , DEBNAME, 'usr') env['DESTDIR'] = DEBINSTALLDIR #redirect install location def writeControlFile(target = None, source = None, env = None): installedSize = 0 files = Glob(os.path.join('build', 'deb', DEBNAME, 'usr')) for i in files: installedSize += os.stat(str(i))[6] installedSize = int(math.ceil(installedSize/1024)) controlInfo = CONTROL_TEMPLATE % ( DEBNAME, DEBVERSION, DEBSECTION, DEBPRIORITY, DEBARCH, DEBDEPENDS, str(installedSize), DEBMAINT, DEBDESC, DEBDESCLONG) f = open(str(target[0]), 'w') f.write(controlInfo) f.close() return None env.Append(BUILDERS = { 'DebianPackage': Builder(action = "fakeroot dpkg-deb -b %s %s" % ("$SOURCE", "$TARGET")), 'DebianControl': Builder(action = writeControlFile), }) env.Alias(target = "debian", source = [ env.Install(dir = DEBCONTROLDIR, source = [env.Glob("deb/DEBIAN/*")]), env.DebianControl(source = env.Alias('install'), target = DEBCONTROLFILE), env.DebianPackage(source = env.Dir(os.path.join('deb', DEBNAME)), target = os.path.join('.', DEBPACKAGEFILE)) ]) def buildGpick(env): gpick_env = env.Clone() if not env.GetOption('clean') and not env['TOOLCHAIN'] == 'msvc': gpick_env.ParseConfig('pkg-config --cflags --libs $GTK_PC', None, False) gpick_env.ParseConfig('pkg-config --cflags --libs $LUA_PC', None, False) if env['ENABLE_NLS']: gpick_env.Append(CPPDEFINES = ['ENABLE_NLS']) gpick_env.Append(CPPDEFINES = ['GSEAL_ENABLE']) sources = gpick_env.Glob('source/*.cpp') + gpick_env.Glob('source/transformation/*.cpp') objects = [] objects += buildVersion(env) objects += buildGtk(env) objects += buildLayout(env) objects += buildI18n(env) objects += buildDbus(env) objects += buildTools(env) objects += buildLua(env) objects += buildColorNames(env) if env['TOOLCHAIN'] == 'msvc': gpick_env.Append(LIBS = ['glib-2.0', 'gtk-win32-2.0', 'gobject-2.0', 'gdk-win32-2.0', 'cairo', 'gdk_pixbuf-2.0', 'lua5.2', 'expat2.1', 'pango-1.0', 'pangocairo-1.0', 'intl']) gpick_env.Append(LINKFLAGS = ['/SUBSYSTEM:WINDOWS', '/ENTRY:mainCRTStartup'], CPPDEFINES = ['XML_STATIC']) objects += buildWindowsResources(env) else: gpick_env.Append(LIBS = ['boost_filesystem', 'boost_system']) if not gpick_env['BUILD_TARGET'] == 'win32': gpick_env.Append(LIBS = ['expat']) if gpick_env['BUILD_TARGET'].startswith('linux') or gpick_env['BUILD_TARGET'].startswith('gnu0') or gpick_env['BUILD_TARGET'].startswith('gnukfreebsd'): gpick_env.Append(LIBS = ['rt']) text_file_parser_objects = gpick_env.StaticObject(['source/parser/TextFile.cpp', gpick_env.Ragel('source/parser/TextFileParser.rl')]) objects += text_file_parser_objects dynv_objects = gpick_env.StaticObject(gpick_env.Glob('source/dynv/*.cpp')) objects += dynv_objects common_objects = gpick_env.StaticObject(gpick_env.Glob('source/common/*.cpp')) objects += common_objects gpick_objects = gpick_env.StaticObject(sources) objects += gpick_objects object_map = {} for obj in objects: if str(obj.dir) == '.': object_map[os.path.splitext(obj.name)[0]] = obj else: object_map[str(obj.dir) + '/' + os.path.splitext(obj.name)[0]] = obj executable = gpick_env.Program('gpick', source = [objects]) test_env = gpick_env.Clone() test_env.Append(LIBS = ['boost_unit_test_framework'], CPPDEFINES = ['BOOST_TEST_DYN_LINK']) tests = test_env.Program('tests', source = test_env.Glob('source/test/*.cpp') + [object_map['source/Color'], object_map['source/MathUtil'], object_map['source/lua/Script']] + dynv_objects + text_file_parser_objects + common_objects) return executable, tests executable, tests = buildGpick(env) env.Alias(target = "build", source = [executable, env.Install('source', executable)]) env.Alias(target = "test", source = [tests, env.Install('source', tests)]) if 'debian' in COMMAND_LINE_TARGETS: addDebianPackageAlias(env) if env['ENABLE_NLS']: translations = env.Glob('share/locale/*/LC_MESSAGES/gpick.po') locales = env.Gettext(translations) Depends(executable, locales) stripped_locales = [] for translation in translations: stripped_locales.append(env.Msgcat(translation, File(translation).srcnode(), MSGCAT_FLAGS = ['--no-location', '--sort-output', '--no-wrap', '--to-code=utf-8'])) env.Alias(target = "strip_locales", source = stripped_locales) env.Alias(target = "locales", source = locales) template_c = env.Xgettext("template_c.pot", env.Glob('source/*.cpp') + env.Glob('source/tools/*.cpp') + env.Glob('source/transformation/*.cpp'), XGETTEXT_FLAGS = ['--keyword=N_', '--from-code=UTF-8', '--package-version="$GPICK_BUILD_VERSION"']) template_lua = env.Xgettext("template_lua.pot", env.Glob('share/gpick/*.lua'), XGETTEXT_FLAGS = ['--language=C++', '--keyword=N_', '--from-code=UTF-8', '--package-version="$GPICK_BUILD_VERSION"']) template = env.Msgcat("template.pot", [template_c, template_lua], MSGCAT_FLAGS = ['--use-first']) env.Alias(target = "template", source = [ template ]) env.Alias(target = "install", source = [ env.InstallProgram(dir = env['DESTDIR'] +'/bin', source = [executable]), env.InstallData(dir = env['DESTDIR'] +'/share/metainfo', source = ['share/metainfo/gpick.appdata.xml']), env.InstallData(dir = env['DESTDIR'] +'/share/applications', source = ['share/applications/gpick.desktop']), env.InstallData(dir = env['DESTDIR'] +'/share/mime/packages', source = ['share/mime/packages/gpick.xml']), env.InstallData(dir = env['DESTDIR'] +'/share/doc/gpick', source = ['share/doc/gpick/copyright']), env.InstallData(dir = env['DESTDIR'] +'/share/gpick', source = [env.Glob('share/gpick/*.png'), env.Glob('share/gpick/*.lua'), env.Glob('share/gpick/*.txt')]), env.InstallData(dir = env['DESTDIR'] +'/share/man/man1', source = ['share/man/man1/gpick.1']), env.InstallData(dir = env['DESTDIR'] +'/share/icons/hicolor/48x48/apps/', source = [env.Glob('share/icons/hicolor/48x48/apps/*.png')]), env.InstallData(dir = env['DESTDIR'] +'/share/icons/hicolor/scalable/apps/', source = [env.Glob('share/icons/hicolor/scalable/apps/*.svg')]), env.InstallDataAutoDir(dir = env['DESTDIR'] + '/share/locale/', relative_dir = 'share/locale/', source = [env.Glob('share/locale/*/LC_MESSAGES/gpick.mo')]), ]) env.Alias(target = "nsis", source = [ env.WriteNsisVersion("version.py") ]) env.Alias(target = "version", source = [ env.Template(target = "#version.txt", source = "version.template"), ]) tarFiles = env.GetSourceFiles("(" + RegexEscape(os.sep) + r"\.)|(" + RegexEscape(os.sep) + r"\.svn$)|(^" + RegexEscape(os.sep) + r"build$)", r"(^\.)|(\.pyc$)|(\.orig$)|(~$)|(\.log$)|(\.diff)|(\.mo$)|(\.patch)|(^gpick-.*\.tar\.gz$)|(^user-config\.py$)") if 'TAR' in env: env.Alias(target = "tar", source = [ 'version', env.Append(TARFLAGS = ['-z']), env.Prepend(TARFLAGS = ['--transform', '"s,(^(build/)?),gpick_' + str(env['GPICK_BUILD_VERSION']) + '/,x"']), env.Tar('gpick_' + str(env['GPICK_BUILD_VERSION']) + '.tar.gz', tarFiles) ]) env.Default(executable, env.Install('source', executable)) gpick-gpick-0.2.6/SConstruct000066400000000000000000000001271377073231300157470ustar00rootroot00000000000000#!/usr/bin/env python SConscript(['SConscript'], variant_dir = 'build', duplicate = 0) gpick-gpick-0.2.6/cmake/000077500000000000000000000000001377073231300147755ustar00rootroot00000000000000gpick-gpick-0.2.6/cmake/FindGettext.cmake000066400000000000000000000017011377073231300202230ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8) find_program(MSGMERGE_EXECUTABLE NAMES msgmerge) find_program(MSGFMT_EXECUTABLE NAMES msgfmt) find_program(MSGCAT_EXECUTABLE NAMES msgcat) find_program(XGETTEXT_EXECUTABLE NAMES xgettext) mark_as_advanced(MSGFMT_EXECUTABLE) mark_as_advanced(MSGMERGE_EXECUTABLE) mark_as_advanced(MSGCAT_EXECUTABLE) mark_as_advanced(XGETTEXT_EXECUTABLE) if (MSGFMT_EXECUTABLE) macro(MSGFMT_TARGET Name Input Output) get_filename_component(dir ${Output} DIRECTORY) file(MAKE_DIRECTORY ${dir}) add_custom_command( OUTPUT ${Output} COMMAND ${MSGFMT_EXECUTABLE} ARGS ${MSGFMT_EXECUTABLE_opts} -f -o ${Output} ${Input} DEPENDS ${Input} COMMENT "Compiling translations ${Output}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) set(MSGFMT_${Name}_DEFINED TRUE) set(MSGFMT_${Name}_OUTPUTS ${Output}) set(MSGFMT_${Name}_INPUT ${Input}) set(MSGFMT_${Name}_COMPILE_FLAGS ${MSGFMT_EXECUTABLE_opts}) endmacro() endif() gpick-gpick-0.2.6/cmake/FindRagel.cmake000066400000000000000000000032351377073231300176350ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8) find_program(RAGEL_EXECUTABLE NAMES ragel DOC "path to the ragel executable") mark_as_advanced(RAGEL_EXECUTABLE) if (RAGEL_EXECUTABLE) execute_process(COMMAND ${RAGEL_EXECUTABLE} --version OUTPUT_VARIABLE RAGEL_version_output ERROR_VARIABLE RAGEL_version_error RESULT_VARIABLE RAGEL_version_result OUTPUT_STRIP_TRAILING_WHITESPACE) if (${RAGEL_version_result} EQUAL 0) string(REGEX REPLACE "^Ragel State Machine Compiler version ([^ ]+) .*$" "\\1" RAGEL_VERSION "${RAGEL_version_output}") else() message(SEND_ERROR "Command \"${RAGEL_EXECUTABLE} --version\" failed with output: ${RAGEL_version_error}") endif() macro(RAGEL_TARGET Name Input Output) set(RAGEL_TARGET_usage "RAGEL_TARGET( [COMPILE_FLAGS ]") if (${ARGC} GREATER 3) if (${ARGC} EQUAL 5) if ("${ARGV3}" STREQUAL "COMPILE_FLAGS") set(RAGEL_EXECUTABLE_opts "${ARGV4}") separate_arguments(RAGEL_EXECUTABLE_opts) else() message(SEND_ERROR ${RAGEL_TARGET_usage}) endif() else() message(SEND_ERROR ${RAGEL_TARGET_usage}) endif() endif() add_custom_command(OUTPUT ${Output} COMMAND ${RAGEL_EXECUTABLE} ARGS ${RAGEL_EXECUTABLE_opts} -o${Output} ${Input} DEPENDS ${Input} COMMENT "Compiling state machine ${Output}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) set(RAGEL_${Name}_DEFINED TRUE) set(RAGEL_${Name}_OUTPUTS ${Output}) set(RAGEL_${Name}_INPUT ${Input}) set(RAGEL_${Name}_COMPILE_FLAGS ${RAGEL_EXECUTABLE_opts}) endmacro() endif() include(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(RAGEL REQUIRED_VARS RAGEL_EXECUTABLE VERSION_VAR RAGEL_VERSION) gpick-gpick-0.2.6/cmake/Version.cmake000066400000000000000000000037231377073231300174310ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8) find_program(GIT_EXECUTABLE git DOC "Git version control") mark_as_advanced(GIT_EXECUTABLE) find_file(GITDIR NAMES .git PATHS ${CMAKE_CURRENT_SOURCE_DIR} NO_DEFAULT_PATH) find_file(VERSION_FILE NAMES version.py PATHS ${CMAKE_CURRENT_SOURCE_DIR} NO_DEFAULT_PATH) if (NOT VERSION_FILE) message(SEND_ERROR "Missing version file \"version.py\"") endif() file(STRINGS "${VERSION_FILE}" GPICK_VERSION LIMIT_COUNT 1) string(FIND ${GPICK_VERSION} "=" position) string(LENGTH ${GPICK_VERSION} length) math(EXPR position "${position} + 2") math(EXPR length "${length} - ${position} - 1") string(SUBSTRING ${GPICK_VERSION} ${position} ${length} GPICK_VERSION) set(GPICK_BUILD_PLATFORM "${CMAKE_SYSTEM_NAME}") if (GIT_EXECUTABLE AND GITDIR) set(old_tz $ENV{TZ}) set(ENV{TZ} UTC) execute_process(COMMAND "${GIT_EXECUTABLE}" show --quiet "--date=format-local:%Y-%m-%d;%H:%M:%S" "--format=%H;%cd;" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" OUTPUT_VARIABLE version_parts ERROR_VARIABLE version_error OUTPUT_STRIP_TRAILING_WHITESPACE ) set(ENV{TZ} "${old_tz}") if (version_error) message(SEND_ERROR "Failed to get version: ${version_error}") endif() list(LENGTH version_parts length) if (length LESS 2) message(SEND_ERROR "Invalid version string ${version_parts}") endif() list(GET version_parts 0 GPICK_REVISION) list(GET version_parts 1 GPICK_BUILD_DATE) list(GET version_parts 2 GPICK_BUILD_TIME) string(SUBSTRING ${GPICK_REVISION} 0 10 GPICK_REVISION) else() find_file(VERSION_TXT_FILE NAMES version.txt PATHS ${CMAKE_CURRENT_SOURCE_DIR} NO_DEFAULT_PATH) if (VERSION_TXT_FILE) file(STRINGS "${VERSION_TXT_FILE}" version_parts LIMIT_COUNT 3) list(GET version_parts 0 GPICK_REVISION) list(GET version_parts 1 GPICK_BUILD_DATE) list(GET version_parts 2 GPICK_BUILD_TIME) string(SUBSTRING ${GPICK_REVISION} 0 10 GPICK_REVISION) return() endif() set(GPICK_REVISION "unknown") set(GPICK_BUILD_DATE "") set(GPICK_BUILD_TIME "") endif() gpick-gpick-0.2.6/deb/000077500000000000000000000000001377073231300144475ustar00rootroot00000000000000gpick-gpick-0.2.6/deb/DEBIAN/000077500000000000000000000000001377073231300153715ustar00rootroot00000000000000gpick-gpick-0.2.6/deb/DEBIAN/postinst000077500000000000000000000002021377073231300171740ustar00rootroot00000000000000#!/bin/sh set -e if [ "$1" = "configure" ] && which update-desktop-database >/dev/null 2>&1 ; then update-desktop-database -q fi gpick-gpick-0.2.6/deb/DEBIAN/postrm000077500000000000000000000001771377073231300166500ustar00rootroot00000000000000#!/bin/sh set -e if [ "$1" = "remove" ] && which update-desktop-database >/dev/null 2>&1 ; then update-desktop-database -q fi gpick-gpick-0.2.6/doc/000077500000000000000000000000001377073231300144625ustar00rootroot00000000000000gpick-gpick-0.2.6/doc/Doxyfile000066400000000000000000001776201377073231300162050ustar00rootroot00000000000000# Doxyfile 1.6.2-20100208 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = Gpick # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = build/ # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = NO # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it parses. # With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this tag. # The format is ext=language, where ext is a file extension, and language is one of # the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, # Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat # .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = YES # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by # doxygen. The layout file controls the global structure of the generated output files # in an output format independent way. The create the layout file that represents # doxygen's defaults, run doxygen with the -l option. You can optionally specify a # file name after the option, if omitted DoxygenLayout.xml will be used as the name # of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = source/ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = NO # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = YES # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER # are set, an additional index file will be generated that can be used as input for # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated # HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. # For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's # filter section matches. # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # When the SEARCHENGINE tag is enabled doxygen will generate a search box for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be implemented using a PHP enabled web server instead of at the web client using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server based approach is that it scales better to large projects and allows full text search. The disadvances is that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = NO # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = YES # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES gpick-gpick-0.2.6/installer/000077500000000000000000000000001377073231300157125ustar00rootroot00000000000000gpick-gpick-0.2.6/installer/License.txt000066400000000000000000000027701377073231300200430ustar00rootroot00000000000000Copyright (c) 2009-2013, Albertas Vyniauskas and Gpick developers All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. gpick-gpick-0.2.6/installer/Makefile000066400000000000000000000020661377073231300173560ustar00rootroot00000000000000 VERSION_FULL=$(shell python -c 'import getversion; getversion.getversion("full")') VERSION=$(shell python -c 'import getversion; getversion.getversion("ms")') MSI=gpick_$(VERSION_FULL) HEAT_SRCS=gpick_files.xstl gtk_files.xstl SRCS=gpick.wxs $(HEAT_SRCS:.xstl=.wxs) OBJS=$(SRCS:.wxs=.wixobj) CANDLE=candle.exe LIGHT=light.exe HEAT=heat.exe HEAT_FLAGS=-ag -dr INSTALLDIR -suid -srd -var var.FilePath FLAGS=-dFilePath=files -dVersionFull=$(VERSION_FULL) -dVersion=$(VERSION) LIGHT_FLAGS=-ext WixUtilExtension -ext WixUIExtension $(FLAGS) CANDLE_FLAGS=$(FLAGS) DEPFILES= files/Gpick.exe .SUFFIXES: .wxs .wixobj .xstl all: $(MSI).msi $(MSI).msi: $(OBJS) $(DEPFILES) $(HEAT_SRCS) $(LIGHT) -nologo $(LIGHT_FLAGS) -out $@ $(OBJS) .xstl.wxs: $(HEAT) dir "files" -nologo $(HEAT_FLAGS) -cg C.Files.$(<:.xstl=) -t $< -out $@ .wxs.wixobj: $(CANDLE) -nologo $(CANDLE_FLAGS) -out $@ $^ clean: $(RM) $(MSI).msi $(OBJS) install: $(MSI).msi $(RM) install.log msiexec -i $(MSI).msi -l*v install.log uninstall: msiexec -x $(MSI).msi gpick-gpick-0.2.6/installer/getversion.py000066400000000000000000000005631377073231300204550ustar00rootroot00000000000000import os,sys,re parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0,parentdir) import version def getversion(style): if style == "full": print version.GPICK_BUILD_VERSION else: result = re.match(r"^(\d+\.\d+\.\d+)(.*)$", version.GPICK_BUILD_VERSION) if result: print result.group(1) else: print "invalid_version" gpick-gpick-0.2.6/installer/gpick.wxs000066400000000000000000000224501377073231300175550ustar00rootroot00000000000000 Privileged 1 NOT Installed Installed AND PATCH Installed NOT Installed 1 NOT Installed OR WixUI_InstallMode = "Change" Installed AND NOT PATCH Installed AND PATCH 1 1 1 1 1 gpick-gpick-0.2.6/installer/gpick_files.xstl000066400000000000000000000013241377073231300211050ustar00rootroot00000000000000 gpick-gpick-0.2.6/installer/gtk_files.xstl000066400000000000000000000013661377073231300206030ustar00rootroot00000000000000 gpick-gpick-0.2.6/installer/script.nsi000066400000000000000000000311031377073231300177270ustar00rootroot00000000000000 !include "MUI2.nsh" !include "FileFunc.nsh" ; GetOptions !include ..\build\version.nsi !define PRODUCT_VERSION "${VERSION}" !define PRODUCT_NAME "Gpick" !define PRODUCT_NAME_SMALL "gpick" !define PRODUCT_PUBLISHER "Albertas Vyniauskas" !define PRODUCT_WEB_SITE "http://code.google.com/p/gpick/" !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" !define PRODUCT_UNINST_ROOT_KEY "HKLM" !define REGISTRY_APP_PATHS "Software\Microsoft\Windows\CurrentVersion\App Paths" Name "Gpick" OutFile "Gpick_${VERSION}_win32-setup.exe" Caption "Gpick v${VERSION} Setup" SetCompressor /SOLID lzma SetCompressorDictSize 32 InstallDir $PROGRAMFILES\Gpick InstallDirRegKey HKLM "Software\Gpick" "" RequestExecutionLevel admin ; gtk installer name for embedding !define GTK_INSTALLER_EXE "gtk2-runtime-2.24.10-2012-10-10-ash.exe" Var MUI_TEMP Var STARTMENU_FOLDER var install_option_removeold ; uninstall the old version first (if present): yes (default), no. var gtk_mode ; "public", "private" or "none" var gtk_tmp ; temporary variable !define MUI_WELCOMEPAGE !define MUI_LICENSEPAGE !define MUI_DIRECTORYPAGE !define MUI_ABORTWARNING !define MUI_UNINSTALLER !define MUI_UNCONFIRMPAGE !define MUI_FINISHPAGE !insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_LICENSE "License.txt" !define MUI_PAGE_CUSTOMFUNCTION_LEAVE on_components_page_leave !insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER !insertmacro MUI_PAGE_INSTFILES !define MUI_FINISHPAGE_NOAUTOCLOSE !define MUI_FINISHPAGE_NOREBOOTSUPPORT !insertmacro MUI_PAGE_FINISH !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES !insertmacro MUI_LANGUAGE "English" AllowSkipFiles off var gtk_dll_abs_path Section "!Program Files" SecProgramFiles SectionIn RO SetOutPath "$INSTDIR" File ..\build\source\gpick.exe File lua5.2.dll SetOutPath "$INSTDIR\share\gpick" File ..\share\gpick\colors0.txt File ..\share\gpick\colors.txt File ..\share\gpick\gpick-falloff-none.png File ..\share\gpick\gpick-falloff-linear.png File ..\share\gpick\gpick-falloff-quadratic.png File ..\share\gpick\gpick-falloff-cubic.png File ..\share\gpick\gpick-falloff-exponential.png File ..\share\icons\hicolor\48x48\apps\gpick.png File ..\share\gpick\init.lua File ..\share\gpick\helpers.lua File ..\share\gpick\layouts.lua SetOutPath "$INSTDIR" WriteRegStr HKLM "Software\Gpick" "" $INSTDIR SetShellVarContext all ; use all user variables as opposed to current user ; Don't set any paths for this exe if it has a private GTK+ installation. !ifndef NO_GTK StrCmp $gtk_mode "private" skip_exe_PATH !endif ; set a special path for this exe, as GTK may not be in a global path. ReadRegStr $gtk_dll_abs_path HKLM "SOFTWARE\GTK\2.0" "DllPath" WriteRegStr HKLM "${REGISTRY_APP_PATHS}\gpick.exe" "Path" "$gtk_dll_abs_path" !ifndef NO_GTK skip_exe_PATH: !endif !ifndef NO_GTK WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "GtkInstalledMode" "$gtk_mode" !endif WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "InstallationDirectory" "$INSTDIR" WriteRegStr HKLM "SOFTWARE\${PRODUCT_NAME}" "Vendor" "${PRODUCT_PUBLISHER}" WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayName" "${PRODUCT_NAME}" WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\Uninstall.exe" WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "InstallLocation" "$INSTDIR" WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\gpick.ico" WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" WriteRegStr HKLM "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" WriteRegDWORD HKLM "${PRODUCT_UNINST_KEY}" "NoModify" 1 WriteRegDWORD HKLM "${PRODUCT_UNINST_KEY}" "NoRepair" 1 WriteUninstaller "$INSTDIR\Uninstall.exe" SectionEnd Section "GTK+ (for this program only)" SecGtkPrivate SectionIn 1 SetShellVarContext all ; use all user variables as opposed to current user AddSize 12200 ; ~ size of unpacked gtk SetOutPath "$INSTDIR" File "${GTK_INSTALLER_EXE}" ; TODO: in the future, when we have translations for this program, ; make the GTK+ translations installation dependent on their installation status. ExecWait '"${GTK_INSTALLER_EXE}" /sideeffects=no /dllpath=root /translations=no /compatdlls=no /S /D=$INSTDIR' Delete "$INSTDIR\${GTK_INSTALLER_EXE}" SectionEnd ; disabled by default Section /o "GTK+ (shared installation)" SecGtkPublic SectionIn 1 SetShellVarContext all ; use all user variables as opposed to current user AddSize 12200 ; ~ size of unpacked gtk SetOutPath "$INSTDIR" File "${GTK_INSTALLER_EXE}" ExecWait '"${GTK_INSTALLER_EXE}"' Delete "$INSTDIR\${GTK_INSTALLER_EXE}" SectionEnd ; Executed on installation start Function .onInit SetShellVarContext all ; use all user variables as opposed to current user ${GetOptions} "$CMDLINE" "/removeold=" $install_option_removeold Call PreventMultipleInstances Call DetectPrevInstallation StrCpy $gtk_mode "private" ; default FunctionEnd function .onselchange !ifndef NO_GTK ; Remember which gtk section was selected. ; Deselect the other section. ; If it was private, we check if public is checked and uncheck private. StrCmp $gtk_mode "private" check_public ; old selection StrCmp $gtk_mode "public" check_private ; old selection goto check_exit check_public: SectionGetFlags ${SecGtkPublic} $gtk_tmp ; see if it's checked IntOp $gtk_tmp $gtk_tmp & ${SF_SELECTED} IntCmp $gtk_tmp ${SF_SELECTED} "" check_exit check_exit SectionGetFlags ${SecGtkPrivate} $gtk_tmp ; unselect the other one IntOp $gtk_tmp $gtk_tmp & ${SECTION_OFF} SectionSetFlags ${SecGtkPrivate} $gtk_tmp goto check_exit check_private: SectionGetFlags ${SecGtkPrivate} $gtk_tmp ; see if it's checked IntOp $gtk_tmp $gtk_tmp & ${SF_SELECTED} IntCmp $gtk_tmp ${SF_SELECTED} "" check_exit check_exit SectionGetFlags ${SecGtkPublic} $gtk_tmp ; unselect the other one IntOp $gtk_tmp $gtk_tmp & ${SECTION_OFF} SectionSetFlags ${SecGtkPublic} $gtk_tmp check_exit: ; store the current mode StrCpy $gtk_mode "none" SectionGetFlags ${SecGtkPrivate} $gtk_tmp IntOp $gtk_tmp $gtk_tmp & ${SF_SELECTED} IntCmp $gtk_tmp ${SF_SELECTED} "" mode_end_private mode_end_private StrCpy $gtk_mode "private" mode_end_private: SectionGetFlags ${SecGtkPublic} $gtk_tmp IntOp $gtk_tmp $gtk_tmp & ${SF_SELECTED} IntCmp $gtk_tmp ${SF_SELECTED} "" mode_end_public mode_end_public StrCpy $gtk_mode "public" mode_end_public: ; MessageBox MB_ICONINFORMATION|MB_OK "gtk_mode: $gtk_mode" /SD IDOK !endif ; !NO_GTK functionend Function on_components_page_leave StrCmp $gtk_mode "none" "" noabort Call AskForGtk noabort: FunctionEnd ; Section descriptions !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SecProgramFiles} "Gpick - Advanced color picker" !insertmacro MUI_DESCRIPTION_TEXT ${SecGtkPrivate} "GTK+ libraries, needed by Gpick. \ This will install a private version of GTK+, usable only by Gpick." !insertmacro MUI_DESCRIPTION_TEXT ${SecGtkPublic} "GTK+ libraries, needed by Gpick. \ This will install a system-wide version of GTK+, shareable with other programs." !insertmacro MUI_FUNCTION_DESCRIPTION_END Section "Desktop Shortcut" SecDesktopShortcut SetOutPath "$INSTDIR" CreateShortCut "$DESKTOP\Gpick.lnk" "$INSTDIR\Gpick.exe" "" SectionEnd Section "-Start Menu Shortcut" SecStartMenu SetOutPath "$INSTDIR" !insertmacro MUI_STARTMENU_WRITE_BEGIN Application CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER" CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Gpick.lnk" "$INSTDIR\Gpick.exe" CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe" !insertmacro MUI_STARTMENU_WRITE_END SectionEnd ; ------------------ POST INSTALL ;Uninstaller Section Section "Uninstall" SetShellVarContext all ; use all user variables as opposed to current user SetAutoClose false ReadRegStr $gtk_mode HKLM "SOFTWARE\${PRODUCT_NAME}" "GtkInstalledMode" StrCmp $gtk_mode "private" "" skip_gtk_remove ; remove private GTK+, specify the same custom options are during installation ExecWait "$INSTDIR\gtk2_runtime_uninst.exe /remove_config=yes /sideeffects=no /dllpath=root /translations=no /compatdlls=no /S" ; _?=$INSTDIR ; Delete "$INSTDIR\gtk2_runtime_uninst.exe" ; If using _? flag, it won't get deleted automatically, do it manually. skip_gtk_remove: DeleteRegKey HKLM "SOFTWARE\${PRODUCT_NAME}" DeleteRegKey HKLM "${PRODUCT_UNINST_KEY}" StrCmp $gtk_mode "private" skip_exe_PATH_remove DeleteRegKey HKLM "${REGISTRY_APP_PATHS}\gpick.exe" skip_exe_PATH_remove: Delete "$INSTDIR\Uninstall.exe" Delete "$INSTDIR\gpick.exe" Delete "$INSTDIR\lua5.2.dll" Delete "$INSTDIR\share\gpick\colors0.txt" Delete "$INSTDIR\share\gpick\colors.txt" Delete "$INSTDIR\share\gpick\gpick-falloff-none.png" Delete "$INSTDIR\share\gpick\gpick-falloff-linear.png" Delete "$INSTDIR\share\gpick\gpick-falloff-quadratic.png" Delete "$INSTDIR\share\gpick\gpick-falloff-cubic.png" Delete "$INSTDIR\share\gpick\gpick-falloff-exponential.png" Delete "$INSTDIR\share\gpick\gpick.png" Delete "$INSTDIR\share\gpick\init.lua" Delete "$INSTDIR\share\gpick\helpers.lua" Delete "$INSTDIR\share\gpick\layouts.lua" RMDir "$INSTDIR\share\gpick" RMDir "$INSTDIR\share\locale" RMDir "$INSTDIR\share" RMDir "$INSTDIR" !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP Delete "$SMPROGRAMS\$MUI_TEMP\Gpick.lnk" Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk" Delete "$DESKTOP\Gpick.lnk" ;Delete empty start menu parent diretories StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" startMenuDeleteLoop: ClearErrors RMDir $MUI_TEMP GetFullPathName $MUI_TEMP "$MUI_TEMP\.." IfErrors startMenuDeleteLoopDone StrCmp $MUI_TEMP $SMPROGRAMS startMenuDeleteLoopDone startMenuDeleteLoop startMenuDeleteLoopDone: DeleteRegKey /ifempty HKLM "Software\Gpick" SectionEnd ; Detect previous installation Function DetectPrevInstallation ; if /removeold=no option is given, don't check anything. StrCmp $install_option_removeold "no" old_detect_done SetShellVarContext all ; use all user variables as opposed to current user push $R0 ; detect previous installation ReadRegStr $R0 HKLM "${PRODUCT_UNINST_KEY}" "UninstallString" StrCmp $R0 "" old_detect_done MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \ "${PRODUCT_NAME} is already installed. $\n$\nClick `OK` to remove the \ previous version or `Cancel` to continue anyway." \ /SD IDOK IDOK old_uninst ; Abort goto old_detect_done ; Run the old uninstaller old_uninst: ClearErrors IfSilent old_silent_uninst old_nosilent_uninst old_nosilent_uninst: ExecWait '$R0' goto old_uninst_continue old_silent_uninst: ExecWait '$R0 /S _?=$INSTDIR' old_uninst_continue: IfErrors old_no_remove_uninstaller ; You can either use Delete /REBOOTOK in the uninstaller or add some code ; here to remove to remove the uninstaller. Use a registry key to check ; whether the user has chosen to uninstall. If you are using an uninstaller ; components page, make sure all sections are uninstalled. old_no_remove_uninstaller: old_detect_done: ; old installation not found, all ok pop $R0 FunctionEnd ; detect GTK installation (any of available versions) Function AskForGtk SetShellVarContext all ; use all user variables as opposed to current user push $R0 ReadRegStr $R0 HKLM "SOFTWARE\GTK\2.0" "DllPath" StrCmp $R0 "" no_gtk have_gtk no_gtk: MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \ "GTK2-Runtime is not installed. This product needs it to function properly.$\n\ Please install GTK2-Runtime from http://gtk-win.sf.net/ first.$\n$\n\ Click 'Cancel' to abort the installation \ or 'OK' to continue anyway." \ /SD IDOK IDOK have_gtk ;Abort ; Abort has different meaning from onpage callbacks, so use Quit Quit goto end_gtk_check have_gtk: ; do nothing end_gtk_check: pop $R0 FunctionEnd ; Prevent running multiple instances of the installer Function PreventMultipleInstances Push $R0 System::Call 'kernel32::CreateMutexA(i 0, i 0, t ${PRODUCT_NAME}) ?e' Pop $R0 StrCmp $R0 0 +3 MessageBox MB_OK|MB_ICONEXCLAMATION "The installer is already running." /SD IDOK Abort Pop $R0 FunctionEnd gpick-gpick-0.2.6/res/000077500000000000000000000000001377073231300145065ustar00rootroot00000000000000gpick-gpick-0.2.6/res/falloff-cubic.svg000066400000000000000000000077731377073231300177410ustar00rootroot00000000000000 image/svg+xml gpick-gpick-0.2.6/res/falloff-exponential.svg000066400000000000000000000102021377073231300211570ustar00rootroot00000000000000 image/svg+xml gpick-gpick-0.2.6/res/falloff-linear.svg000066400000000000000000000101611377073231300201070ustar00rootroot00000000000000 image/svg+xml gpick-gpick-0.2.6/res/falloff-none.svg000066400000000000000000000074251377073231300176050ustar00rootroot00000000000000 image/svg+xml gpick-gpick-0.2.6/res/falloff-quadratic.svg000066400000000000000000000077651377073231300206320ustar00rootroot00000000000000 image/svg+xml gpick-gpick-0.2.6/res/gpick.svg000066400000000000000000000225551377073231300163350ustar00rootroot00000000000000 image/svg+xml gpick-gpick-0.2.6/res/gray-pattern.svg000066400000000000000000000075501377073231300176530ustar00rootroot00000000000000 image/svg+xml gpick-gpick-0.2.6/share/000077500000000000000000000000001377073231300150175ustar00rootroot00000000000000gpick-gpick-0.2.6/share/applications/000077500000000000000000000000001377073231300175055ustar00rootroot00000000000000gpick-gpick-0.2.6/share/applications/gpick.desktop000066400000000000000000000005221377073231300221740ustar00rootroot00000000000000[Desktop Entry] Version=1.0 Name=Gpick Comment=Color picker Comment[ru]=Пипетка для снятия цвета GenericName=Color picker Exec=gpick %u Icon=gpick StartupNotify=true MimeType=application/x-gpick-palette; Terminal=false Type=Application Categories=Graphics;GTK; Keywords=color picker;colorpick;palette;palette editing;gpick-gpick-0.2.6/share/doc/000077500000000000000000000000001377073231300155645ustar00rootroot00000000000000gpick-gpick-0.2.6/share/doc/gpick/000077500000000000000000000000001377073231300166615ustar00rootroot00000000000000gpick-gpick-0.2.6/share/doc/gpick/copyright000066400000000000000000000032661377073231300206230ustar00rootroot00000000000000gpick This package was debianized by Albertas Vyšniauskas The home page of Gpick is at: http://www.gpick.org Upstream Author: Albertas Vyšniauskas This software is copyright (c) 2009-2020 by Albertas Vyšniauskas. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. gpick-gpick-0.2.6/share/gpick/000077500000000000000000000000001377073231300161145ustar00rootroot00000000000000gpick-gpick-0.2.6/share/gpick/color_dictionary_0.txt000066400000000000000000000505011377073231300224400ustar00rootroot00000000000000! Source: http://xkcd.com/color/rgb.txt ! License: http://creativecommons.org/publicdomain/zero/1.0/ 172 194 217 cloudy blue 86 174 87 dark pastel green 178 153 110 dust 168 255 4 electric lime 105 216 79 fresh green 137 69 133 light eggplant 112 178 63 nasty green 212 255 255 really light blue 101 171 124 tea 149 46 143 warm purple 252 252 129 yellowish tan 165 163 145 cement 56 128 4 dark grass green 76 144 133 dusty teal 94 155 138 grey teal 239 180 53 macaroni and cheese 217 155 130 pinkish tan 10 95 56 spruce 12 6 247 strong blue 97 222 42 toxic green 55 120 191 windows blue 34 66 199 blue blue 83 60 198 blue with a hint of purple 155 181 60 booger 5 255 166 bright sea green 31 99 87 dark green blue 1 115 116 deep turquoise 12 181 119 green teal 255 7 137 strong pink 175 168 139 bland 8 120 127 deep aqua 221 133 215 lavender pink 166 200 117 light moss green 167 255 181 light seafoam green 194 183 9 olive yellow 231 142 165 pig pink 150 110 189 deep lilac 204 173 96 desert 172 134 168 dusty lavender 148 126 148 purpley grey 152 63 178 purply 255 99 233 candy pink 178 251 165 light pastel green 99 179 101 boring green 142 229 63 kiwi green 183 225 161 light grey green 255 111 82 orange pink 189 248 163 tea green 211 182 131 very light brown 255 252 196 egg shell 67 5 65 eggplant purple 255 178 208 powder pink 153 117 112 reddish grey 173 144 13 baby shit brown 196 142 253 liliac 80 123 156 stormy blue 125 113 3 ugly brown 255 253 120 custard 218 70 125 darkish pink 65 2 0 deep brown 201 209 121 greenish beige 255 250 134 manilla 86 132 174 off blue 107 124 133 battleship grey 111 108 10 browny green 126 64 113 bruise 0 147 55 kelley green 208 228 41 sickly yellow 255 249 23 sunny yellow 29 93 236 azul 5 73 7 darkgreen 181 206 8 green/yellow 143 182 123 lichen 200 255 176 light light green 253 222 108 pale gold 255 223 34 sun yellow 169 190 112 tan green 104 50 227 burple 253 177 71 butterscotch 199 172 125 toupe 255 243 154 dark cream 133 14 4 indian red 239 192 254 light lavendar 64 253 20 poison green 182 196 6 baby puke green 157 255 0 bright yellow green 60 65 66 charcoal grey 242 171 21 squash 172 79 6 cinnamon 196 254 130 light pea green 44 250 31 radioactive green 154 98 0 raw sienna 202 155 247 baby purple 135 95 66 cocoa 58 46 254 light royal blue 253 141 73 orangeish 139 49 3 rust brown 203 165 96 sand brown 105 131 57 swamp 12 220 115 tealish green 183 82 3 burnt siena 127 143 78 camo 38 83 141 dusk blue 99 169 80 fern 200 127 137 old rose 177 252 153 pale light green 255 154 138 peachy pink 246 104 142 rosy pink 118 253 168 light bluish green 83 254 92 light bright green 78 253 84 light neon green 160 254 191 light seafoam 123 242 218 tiffany blue 188 245 166 washed out green 202 107 2 browny orange 16 122 176 nice blue 33 56 171 sapphire 113 159 145 greyish teal 253 185 21 orangey yellow 254 252 175 parchment 252 246 121 straw 29 2 0 very dark brown 203 104 67 terracota 49 102 138 ugly blue 36 122 253 clear blue 255 255 182 creme 144 253 169 foam green 134 161 125 grey/green 253 220 92 light gold 120 209 182 seafoam blue 19 187 175 topaz 251 95 252 violet pink 32 249 134 wintergreen 255 227 110 yellow tan 157 7 89 dark fuchsia 58 24 177 indigo blue 194 255 137 light yellowish green 215 103 173 pale magenta 114 0 88 rich purple 255 218 3 sunflower yellow 1 192 141 green/blue 172 116 52 leather 1 70 0 racing green 153 0 250 vivid purple 2 6 111 dark royal blue 142 118 24 hazel 209 118 143 muted pink 150 180 3 booger green 253 255 99 canary 149 163 166 cool grey 127 104 78 dark taupe 117 25 115 darkish purple 8 148 4 true green 255 97 99 coral pink 89 133 86 dark sage 33 71 97 dark slate blue 60 115 168 flat blue 186 158 136 mushroom 2 27 249 rich blue 115 74 101 dirty purple 35 196 139 greenblue 143 174 34 icky green 230 242 162 light khaki 75 87 219 warm blue 217 1 102 dark hot pink 1 84 130 deep sea blue 157 2 22 carmine 114 143 2 dark yellow green 255 229 173 pale peach 78 5 80 plum purple 249 188 8 golden rod 255 7 58 neon red 199 121 134 old pink 214 255 254 very pale blue 254 75 3 blood orange 253 89 86 grapefruit 252 225 102 sand yellow 178 113 61 clay brown 31 59 77 dark blue grey 105 157 76 flat green 86 252 162 light green blue 251 85 129 warm pink 62 130 252 dodger blue 160 191 22 gross green 214 255 250 ice 79 115 142 metallic blue 255 177 154 pale salmon 92 139 21 sap green 84 172 104 algae 137 160 176 bluey grey 126 160 122 greeny grey 27 252 6 highlighter green 202 255 251 light light blue 182 255 187 light mint 167 94 9 raw umber 21 46 255 vivid blue 141 94 183 deep lavender 95 158 143 dull teal 99 247 180 light greenish blue 96 102 2 mud green 252 134 170 pinky 140 0 52 red wine 117 128 0 shit green 171 126 76 tan brown 3 7 100 darkblue 254 134 164 rosa 213 23 78 lipstick 254 208 252 pale mauve 104 0 24 claret 254 223 8 dandelion 254 66 15 orangered 111 124 0 poop green 202 1 71 ruby 27 36 49 dark 0 251 176 greenish turquoise 219 88 86 pastel red 221 214 24 piss yellow 65 253 254 bright cyan 207 82 78 dark coral 33 195 111 algae green 169 3 8 darkish red 110 16 5 reddy brown 254 130 140 blush pink 75 97 19 camouflage green 77 164 9 lawn green 190 174 138 putty 3 57 248 vibrant blue 168 143 89 dark sand 93 33 208 purple/blue 254 178 9 saffron 78 81 139 twilight 150 78 2 warm brown 133 163 178 bluegrey 255 105 175 bubble gum pink 195 251 244 duck egg blue 42 254 183 greenish cyan 0 95 106 petrol 12 23 147 royal 255 255 129 butter 240 131 58 dusty orange 241 243 63 off yellow 177 210 123 pale olive green 252 130 74 orangish 113 170 52 leaf 183 201 226 light blue grey 75 1 1 dried blood 165 82 230 lightish purple 175 47 13 rusty red 139 136 248 lavender blue 154 247 100 light grass green 166 251 178 light mint green 255 197 18 sunflower 117 8 81 velvet 193 74 9 brick orange 254 47 74 lightish red 2 3 226 pure blue 10 67 122 twilight blue 165 0 85 violet red 174 139 12 yellowy brown 253 121 143 carnation 191 172 5 muddy yellow 62 175 118 dark seafoam green 199 71 103 deep rose 185 72 78 dusty red 100 125 142 grey/blue 191 254 40 lemon lime 215 37 222 purple/pink 178 151 5 brown yellow 103 58 63 purple brown 168 125 194 wisteria 250 254 75 banana yellow 192 2 47 lipstick red 14 135 204 water blue 141 132 104 brown grey 173 3 222 vibrant purple 140 255 158 baby green 148 172 2 barf green 196 255 247 eggshell blue 253 238 115 sandy yellow 51 184 100 cool green 255 249 208 pale 117 141 163 blue/grey 245 4 201 hot magenta 119 161 181 greyblue 135 86 228 purpley 136 151 23 baby shit green 194 126 121 brownish pink 1 115 113 dark aquamarine 159 131 3 diarrhea 247 213 96 light mustard 189 246 254 pale sky blue 117 184 79 turtle green 156 187 4 bright olive 41 70 91 dark grey blue 105 96 6 greeny brown 173 248 2 lemon green 193 198 252 light periwinkle 53 173 107 seaweed green 255 253 55 sunshine yellow 164 66 160 ugly purple 243 97 150 medium pink 148 119 6 puke brown 255 244 242 very light pink 30 145 103 viridian 181 195 6 bile 254 255 127 faded yellow 207 253 188 very pale green 10 221 8 vibrant green 135 253 5 bright lime 30 248 118 spearmint 123 253 199 light aquamarine 188 236 172 light sage 187 249 15 yellowgreen 171 144 4 baby poo 31 181 122 dark seafoam 0 85 90 deep teal 164 132 172 heather 196 85 8 rust orange 63 130 157 dirty blue 84 141 68 fern green 201 94 251 bright lilac 58 229 127 weird green 1 103 149 peacock blue 135 169 34 avocado green 240 148 77 faded orange 93 20 81 grape purple 37 255 41 hot green 208 254 29 lime yellow 255 166 43 mango 1 180 76 shamrock 255 108 181 bubblegum 107 66 71 purplish brown 199 193 12 vomit yellow 183 255 250 pale cyan 174 255 110 key lime 236 45 1 tomato red 118 255 123 lightgreen 115 0 57 merlot 4 3 72 night blue 223 78 200 purpleish pink 110 203 60 apple 143 152 5 baby poop green 94 220 31 green apple 217 79 245 heliotrope 200 253 61 yellow/green 7 13 13 almost black 73 132 184 cool blue 81 183 59 leafy green 172 126 4 mustard brown 78 84 129 dusk 135 110 75 dull brown 88 188 8 frog green 47 239 16 vivid green 45 254 84 bright light green 10 255 2 fluro green 156 239 67 kiwi 24 209 123 seaweed 53 83 10 navy green 24 5 219 ultramarine blue 98 88 196 iris 255 150 79 pastel orange 255 171 15 yellowish orange 143 140 231 perrywinkle 36 188 168 tealish 63 1 44 dark plum 203 248 95 pear 255 114 76 pinkish orange 40 1 55 midnight purple 179 111 246 light urple 72 192 114 dark mint 188 203 122 greenish tan 168 65 91 light burgundy 6 177 196 turquoise blue 205 117 132 ugly pink 241 218 122 sandy 255 4 144 electric pink 128 91 135 muted purple 80 167 71 mid green 168 164 149 greyish 207 255 4 neon yellow 255 255 126 banana 255 127 167 carnation pink 239 64 38 tomato 60 153 146 sea 136 104 6 muddy brown 4 244 137 turquoise green 254 246 158 buff 207 175 123 fawn 59 113 159 muted blue 253 193 197 pale rose 32 192 115 dark mint green 155 95 192 amethyst 15 155 142 blue/green 116 40 2 chestnut 157 185 44 sick green 164 191 32 pea 205 89 9 rusty orange 173 165 135 stone 190 1 60 rose red 184 255 235 pale aqua 220 77 1 deep orange 162 101 62 earth 99 139 39 mossy green 65 156 3 grassy green 177 255 101 pale lime green 157 188 212 light grey blue 253 253 254 pale grey 119 171 86 asparagus 70 65 150 blueberry 153 1 71 purple red 190 253 115 pale lime 50 191 132 greenish teal 175 111 9 caramel 160 2 92 deep magenta 255 216 177 light peach 127 78 30 milk chocolate 191 155 12 ocher 107 163 83 off green 240 117 230 purply pink 123 200 246 lightblue 71 95 148 dusky blue 245 191 3 golden 255 254 182 light beige 255 253 116 butter yellow 137 91 123 dusky purple 67 107 173 french blue 208 193 1 ugly yellow 198 248 8 greeny yellow 244 54 5 orangish red 2 193 77 shamrock green 178 95 3 orangish brown 42 126 25 tree green 73 6 72 deep violet 83 98 103 gunmetal 90 6 239 blue/purple 207 2 52 cherry 196 166 97 sandy brown 151 138 132 warm grey 31 9 84 dark indigo 3 1 45 midnight 43 177 121 bluey green 195 144 155 grey pink 166 111 181 soft purple 119 0 1 blood 146 43 5 brown red 125 127 124 medium grey 153 15 75 berry 143 115 3 poo 200 60 185 purpley pink 254 169 147 light salmon 172 187 13 snot 192 113 254 easter purple 204 253 127 light yellow green 0 2 46 dark navy blue 130 131 68 drab 255 197 203 light rose 171 18 57 rouge 176 5 75 purplish red 153 204 4 slime green 147 124 0 baby poop 1 149 41 irish green 239 29 231 pink/purple 0 4 53 dark navy 66 179 149 greeny blue 157 87 131 light plum 200 172 169 pinkish grey 200 118 6 dirty orange 170 39 4 rust red 228 203 255 pale lilac 250 66 36 orangey red 8 4 249 primary blue 92 178 0 kermit green 118 66 78 brownish purple 108 122 14 murky green 251 221 126 wheat 42 1 52 very dark purple 4 74 5 bottle green 253 70 89 watermelon 13 117 248 deep sky blue 254 0 2 fire engine red 203 157 6 yellow ochre 251 125 7 pumpkin orange 185 204 129 pale olive 237 200 255 light lilac 97 225 96 lightish green 138 184 254 carolina blue 146 10 78 mulberry 254 2 162 shocking pink 154 48 1 auburn 101 254 8 bright lime green 190 253 183 celadon 177 114 97 pinkish brown 136 95 1 poo brown 2 204 254 bright sky blue 193 253 149 celery 131 101 57 dirt brown 251 41 67 strawberry 132 183 1 dark lime 182 99 37 copper 127 81 18 medium brown 95 160 82 muted green 109 237 253 robin's egg 11 249 234 bright aqua 199 96 255 bright lavender 255 255 203 ivory 246 206 252 very light purple 21 80 132 light navy 245 5 79 pink red 100 84 3 olive brown 122 89 1 poop brown 168 181 4 mustard green 61 153 115 ocean green 0 1 51 very dark blue 118 169 115 dusty green 46 90 136 light navy blue 11 247 125 minty green 189 108 72 adobe 172 29 184 barney 43 175 106 jade green 38 247 253 bright light blue 174 253 108 light lime 155 143 85 dark khaki 255 173 1 orange yellow 198 156 4 ocre 244 208 84 maize 222 157 172 faded pink 5 72 13 british racing green 201 174 116 sandstone 96 70 15 mud brown 152 246 176 light sea green 138 241 254 robin egg blue 46 232 187 aqua marine 17 135 93 dark sea green 253 176 192 soft pink 177 96 2 orangey brown 247 2 42 cherry red 213 171 9 burnt yellow 134 119 95 brownish grey 198 159 89 camel 122 104 127 purplish grey 4 46 96 marine 200 141 148 greyish pink 165 251 213 pale turquoise 255 254 113 pastel yellow 98 65 199 bluey purple 255 254 64 canary yellow 211 73 78 faded red 152 94 43 sepia 166 129 76 coffee 255 8 232 bright magenta 157 118 81 mocha 254 255 202 ecru 152 86 141 purpleish 158 0 58 cranberry 40 124 55 darkish green 185 105 2 brown orange 186 104 115 dusky rose 255 120 85 melon 148 178 28 sickly green 197 201 199 silver 102 26 238 purply blue 97 64 239 purpleish blue 155 229 170 hospital green 123 88 4 shit brown 39 106 179 mid blue 254 179 8 amber 140 253 126 easter green 100 136 234 soft blue 5 110 238 cerulean blue 178 122 1 golden brown 15 254 249 bright turquoise 250 42 85 red pink 130 7 71 red purple 122 106 79 greyish brown 244 50 12 vermillion 161 57 5 russet 111 130 138 steel grey 165 90 244 lighter purple 173 10 253 bright violet 0 69 119 prussian blue 101 141 109 slate green 202 123 128 dirty pink 0 82 73 dark blue green 43 93 52 pine 191 241 40 yellowy green 181 148 16 dark gold 41 118 187 bluish 1 65 130 darkish blue 187 63 63 dull red 252 38 71 pinky red 168 121 0 bronze 130 203 178 pale teal 102 124 62 military green 254 70 165 barbie pink 254 131 204 bubblegum pink 148 166 23 pea soup green 168 137 5 dark mustard 127 95 0 shit 158 67 162 medium purple 6 46 3 very dark green 138 110 69 dirt 204 122 139 dusky pink 158 1 104 red violet 253 255 56 lemon yellow 192 250 139 pistachio 238 220 91 dull yellow 126 189 1 dark lime green 59 91 146 denim blue 1 136 159 teal blue 61 122 253 lightish blue 95 52 231 purpley blue 109 90 207 light indigo 116 133 0 swamp green 112 108 17 brown green 60 0 8 dark maroon 203 0 245 hot purple 0 45 4 dark forest green 101 140 187 faded blue 116 149 81 drab green 185 255 102 light lime green 157 193 0 snot green 250 238 102 yellowish 126 251 179 light blue green 123 0 44 bordeaux 194 146 161 light mauve 1 123 146 ocean 252 192 6 marigold 101 116 50 muddy green 216 134 59 dull orange 115 133 149 steel 170 35 255 electric purple 8 255 8 fluorescent green 155 122 1 yellowish brown 242 158 142 blush 111 194 118 soft green 255 91 0 bright orange 253 255 82 lemon 134 111 133 purple grey 143 254 9 acid green 238 207 254 pale lavender 81 10 201 violet blue 79 145 83 light forest green 159 35 5 burnt red 114 134 57 khaki green 222 12 98 cerise 145 110 153 faded purple 255 177 109 apricot 60 77 3 dark olive green 127 112 83 grey brown 119 146 111 green grey 1 15 204 true blue 206 174 250 pale violet 143 153 251 periwinkle blue 198 252 255 light sky blue 85 57 204 blurple 84 78 3 green brown 1 122 121 bluegreen 1 249 198 bright teal 201 176 3 brownish yellow 146 153 1 pea soup 11 85 9 forest 160 4 152 barney purple 32 0 177 ultramarine 148 86 140 purplish 194 190 14 puke yellow 116 139 151 bluish grey 102 95 209 dark periwinkle 156 109 165 dark lilac 196 66 64 reddish 162 72 87 light maroon 130 95 135 dusty purple 201 100 59 terra cotta 144 177 52 avocado 1 56 106 marine blue 37 163 111 teal green 89 101 109 slate grey 117 253 99 lighter green 33 252 13 electric green 90 134 173 dusty blue 254 198 21 golden yellow 255 253 1 bright yellow 223 197 254 light lavender 178 100 0 umber 127 94 0 poop 222 126 93 dark peach 4 130 67 jungle green 255 255 212 eggshell 59 99 140 denim 183 148 0 yellow brown 132 89 126 dull purple 65 25 0 chocolate brown 123 3 35 wine red 4 217 255 neon blue 102 126 44 dirty green 251 238 172 light tan 215 255 254 ice blue 78 116 150 cadet blue 135 76 98 dark mauve 213 255 255 very light blue 130 109 140 grey purple 255 186 205 pastel pink 209 255 189 very light green 68 142 228 dark sky blue 5 71 42 evergreen 213 134 157 dull pink 61 7 52 aubergine 74 1 0 mahogany 248 72 28 reddish orange 2 89 15 deep green 137 162 3 vomit green 224 63 216 purple pink 213 138 148 dusty pink 123 178 116 faded green 82 101 37 camo green 201 76 190 pinky purple 219 75 218 pink purple 158 54 35 brownish red 181 72 93 dark rose 115 92 18 mud 156 109 87 brownish 2 143 30 emerald green 177 145 110 pale brown 73 117 156 dull blue 160 69 14 burnt umber 57 173 72 medium green 182 106 80 clay 140 255 219 light aqua 164 190 92 light olive green 203 119 35 brownish orange 5 105 107 dark aqua 206 93 174 purplish pink 200 90 83 dark salmon 150 174 141 greenish grey 31 167 116 jade 122 151 3 ugly green 172 147 98 dark beige 1 160 73 emerald 217 84 77 pale red 250 95 247 light magenta 130 202 252 sky 172 255 252 light cyan 252 176 1 yellow orange 145 9 81 reddish purple 254 44 84 reddish pink 200 117 196 orchid 205 197 10 dirty yellow 253 65 30 orange red 154 2 0 deep red 190 100 0 orange brown 3 10 167 cobalt blue 254 1 154 neon pink 247 135 154 rose pink 136 113 145 greyish purple 176 1 73 raspberry 18 225 147 aqua green 254 123 124 salmon pink 255 148 8 tangerine 106 110 9 brownish green 139 46 22 red brown 105 97 18 greenish brown 225 119 1 pumpkin 10 72 30 pine green 52 56 55 charcoal 255 183 206 baby pink 106 121 247 cornflower 93 6 233 blue violet 61 28 2 chocolate 130 166 125 greyish green 190 1 25 scarlet 201 255 39 green yellow 55 62 2 dark olive 169 86 30 sienna 202 160 255 pastel purple 202 102 65 terracotta 2 216 233 aqua blue 136 179 120 sage green 152 0 2 blood red 203 1 98 deep pink 92 172 45 grass 118 153 88 moss 162 191 254 pastel blue 16 166 116 bluish green 6 180 139 green blue 175 136 74 dark tan 11 139 135 greenish blue 255 167 86 pale orange 162 164 21 vomit 21 68 6 forrest green 133 103 152 dark lavender 52 1 63 dark violet 99 45 233 purple blue 10 136 138 dark cyan 111 118 50 olive drab 212 106 126 pinkish 30 72 143 cobalt 188 19 254 neon purple 126 244 204 light turquoise 118 205 38 apple green 116 166 98 dull green 128 1 63 wine 177 209 252 powder blue 255 255 228 off white 6 82 255 electric blue 4 92 90 dark turquoise 87 41 206 blue purple 6 154 243 azure 255 0 13 bright red 241 12 69 pinkish red 81 112 215 cornflower blue 172 191 105 light olive 108 52 97 grape 94 129 157 greyish blue 96 30 249 purplish blue 176 221 22 yellowish green 205 253 2 greenish yellow 44 111 187 medium blue 192 115 122 dusty rose 214 180 252 light violet 2 0 53 midnight blue 112 59 231 bluish purple 253 60 6 red orange 150 0 86 dark magenta 64 163 104 greenish 3 113 156 ocean blue 252 90 80 coral 255 255 194 cream 127 43 10 reddish brown 176 78 15 burnt sienna 160 54 35 brick 135 174 115 sage 120 155 115 grey green 255 255 255 white 152 239 249 robin's egg blue 101 139 56 moss green 90 125 154 steel blue 56 8 53 eggplant 255 254 122 light yellow 92 169 4 leaf green 216 220 214 light grey 165 165 2 puke 214 72 215 pinkish purple 4 116 149 sea blue 183 144 212 pale purple 91 124 153 slate blue 96 124 142 blue grey 11 64 8 hunter green 237 13 217 fuchsia 140 0 15 crimson 255 255 132 pale yellow 191 144 5 ochre 210 189 10 mustard yellow 255 71 76 light red 4 133 209 cerulean 255 207 220 pale pink 4 2 115 deep blue 168 60 9 rust 144 228 193 light teal 81 101 114 slate 250 194 5 goldenrod 213 182 10 dark yellow 54 55 55 dark grey 75 93 22 army green 107 139 164 grey blue 128 249 173 seafoam 165 126 82 puce 169 249 113 spring green 198 81 2 dark orange 226 202 118 sand 176 255 157 pastel green 159 254 176 mint 253 170 72 light orange 254 1 177 bright pink 193 248 10 chartreuse 54 1 63 deep purple 52 28 2 dark brown 185 162 129 taupe 142 171 18 pea green 154 174 7 puke green 2 171 46 kelly green 122 249 171 seafoam green 19 126 109 blue green 170 166 98 khaki 97 0 35 burgundy 1 77 78 dark teal 143 20 2 brick red 75 0 110 royal purple 88 15 65 plum 143 255 159 mint green 219 180 12 gold 162 207 254 baby blue 192 251 45 yellow green 190 3 253 bright purple 132 0 0 dark red 208 254 254 pale blue 63 155 11 grass green 1 21 62 navy 4 216 178 aquamarine 192 78 1 burnt orange 12 255 12 neon green 1 101 252 bright blue 207 98 117 rose 255 209 223 light pink 206 179 1 mustard 56 2 130 indigo 170 255 50 lime 83 252 161 sea green 142 130 254 periwinkle 203 65 107 dark pink 103 122 4 olive green 255 176 124 peach 199 253 181 pale green 173 129 80 light brown 255 2 141 hot pink 0 0 0 black 206 162 253 lilac 0 17 70 navy blue 5 4 170 royal blue 230 218 166 beige 255 121 108 salmon 110 117 14 olive 101 0 33 maroon 1 255 7 bright green 53 6 62 dark purple 174 113 129 mauve 6 71 12 forest green 19 234 201 aqua 0 255 255 cyan 209 178 111 tan 0 3 91 dark blue 199 159 239 lavender 6 194 172 turquoise 3 53 0 dark green 154 14 234 violet 191 119 246 light purple 137 254 5 lime green 146 149 145 grey 117 187 253 sky blue 255 255 20 yellow 194 0 120 magenta 150 249 123 light green 249 115 6 orange 2 147 134 teal 149 208 252 light blue 229 0 0 red 101 55 0 brown 255 129 192 pink 3 67 223 blue 21 176 26 green 126 30 156 purple gpick-gpick-0.2.6/share/gpick/converters.lua000066400000000000000000000161141377073231300210140ustar00rootroot00000000000000local gpick = require('gpick') local color = require('gpick/color') local helpers = require('helpers') local _ = gpick._ local round = helpers.round local options = require('options') local serializeWebHex = function(colorObject) if not colorObject then return nil end local c = colorObject:getColor() if options.upperCase then return '#' .. string.format('%02X%02X%02X', round(c:red() * 255), round(c:green() * 255), round(c:blue() * 255)) else return '#' .. string.format('%02x%02x%02x', round(c:red() * 255), round(c:green() * 255), round(c:blue() * 255)) end end local deserializeWebHex = function(text, colorObject) local c = color:new() local findStart, findEnd, red, green, blue = string.find(text, '#([%x][%x])([%x][%x])([%x][%x])[^%x]?') if findStart ~= nil then red = tonumber(red, 16) green = tonumber(green, 16) blue = tonumber(blue, 16) c:red(red / 255) c:green(green / 255) c:blue(blue / 255) colorObject:setColor(c) return 1 - (math.atan(findStart - 1) / math.pi) - (math.atan(string.len(text) - findEnd) / math.pi) else return -1 end end local serializeWebHexNoHash = function(colorObject) if not colorObject then return nil end local c = colorObject:getColor() if options.upperCase then return string.format('%02X%02X%02X', round(c:red() * 255), round(c:green() * 255), round(c:blue() * 255)) else return string.format('%02x%02x%02x', round(c:red() * 255), round(c:green() * 255), round(c:blue() * 255)) end end local deserializeWebHexNoHash = function(text, colorObject) local c = color:new() local findStart, findEnd, red, green, blue = string.find(text, '([%x][%x])([%x][%x])([%x][%x])[^%x]?') if findStart ~= nil then red = tonumber(red, 16) green = tonumber(green, 16) blue = tonumber(blue, 16) c:red(red / 255) c:green(green / 255) c:blue(blue / 255) colorObject:setColor(c) return 1 - (math.atan(findStart - 1) / math.pi) - (math.atan(string.len(text) - findEnd) / math.pi) else return -1 end end local serializeWebHex3Digit = function(colorObject) if not colorObject then return nil end local c = colorObject:getColor() if options.upperCase then return '#' .. string.format('%01X%01X%01X', round(c:red() * 15), round(c:green() * 15), round(c:blue() * 15)) else return '#' .. string.format('%01x%01x%01x', round(c:red() * 15), round(c:green() * 15), round(c:blue() * 15)) end end local deserializeWebHex3Digit = function(text, colorObject) local c = color:new() local findStart, findEnd, red, green, blue = string.find(text, '#([%x])([%x])([%x])[^%x]?') if findStart ~= nil then red = tonumber(red, 16) green = tonumber(green, 16) blue = tonumber(blue, 16) c:red(red / 15) c:green(green / 15) c:blue(blue / 15) colorObject:setColor(c) return 1 - (math.atan(findStart - 1) / math.pi) - (math.atan(string.len(text) - findEnd) / math.pi) else return -1 end end local serializeCssHsl = function(colorObject) local c = colorObject:getColor() c = c:rgbToHsl() return 'hsl(' .. string.format('%d, %d%%, %d%%', round(c:hue() * 360), round(c:saturation() * 100), round(c:lightness() * 100)) .. ')' end local serializeCssRgb = function(colorObject) local c = colorObject:getColor() return 'rgb(' .. string.format('%d, %d, %d', round(c:red() * 255), round(c:green() * 255), round(c:blue() * 255)) .. ')' end local serializeColorCssBlock = function(colorObject, position) if not colorObject then return nil end local c = colorObject:getColor() local hsl = c:rgbToHsl() local result = ''; if position.first then result = '/**\n * Generated by Gpick ' .. gpick.version .. '\n' end local name = colorObject:getName() if not name then name = '' end result = result .. ' * ' .. name .. ': ' if options.upperCase then result = result .. '#' .. string.format('%02X%02X%02X', round(c:red() * 255), round(c:green() * 255), round(c:blue() * 255)) else result = result .. '#' .. string.format('%02x%02x%02x', round(c:red() * 255), round(c:green() * 255), round(c:blue() * 255)) end result = result .. ', rgb(' .. string.format('%d, %d, %d', round(c:red() * 255), round(c:green() * 255), round(c:blue() * 255)) .. '), hsl(' .. string.format('%d, %d%%, %d%%', round(c:hue() * 360), round(c:saturation() * 100), round(c:lightness() * 100)) .. ')' if position.last then result = result .. '\n */' end return result end local deserializeCssRgb = function(text, colorObject) local c = color:new() local findStart, findEnd, red, green, blue = string.find(text, 'rgb%(([%d]*)[%s]*,[%s]*([%d]*)[%s]*,[%s]*([%d]*)%)') if findStart ~= nil then c:rgb(math.min(1, red / 255), math.min(1, green / 255), math.min(1, blue / 255)) colorObject:setColor(c) return 1 - (math.atan(findStart - 1) / math.pi) - (math.atan(string.len(text) - findEnd) / math.pi) else return -1 end end local serializeCssColorHex = function(colorObject) return 'color: ' .. serializeWebHex(colorObject) end local serializeCssBackgroundColorHex = function(colorObject) return 'background-color: ' .. serializeWebHex(colorObject) end local serializeCssBorderColorHex = function(colorObject) return 'border-color: ' .. serializeWebHex(colorObject) end local serializeCssBorderTopColorHex = function(colorObject) return 'border-top-color: ' .. serializeWebHex(colorObject) end local serializeCssBorderRightColorHex = function(colorObject) return 'border-right-color: ' .. serializeWebHex(colorObject) end local serializeCssBorderBottomColorHex = function(colorObject) return 'border-bottom-color: ' .. serializeWebHex(colorObject) end local serializeCssBorderLeftHex = function(colorObject) return 'border-left-color: ' .. serializeWebHex(colorObject) end local serializeColorCsv = function(colorObject) local c = colorObject:getColor() os.setlocale("C", "numeric") local r = string.format('%f\t%f\t%f', c:red(), c:green(), c:blue()) os.setlocale("", "numeric") return r end gpick:addConverter('color_web_hex', _("Web: hex code"), serializeWebHex, deserializeWebHex) gpick:addConverter('color_web_hex_3_digit', _("Web: hex code (3 digits)"), serializeWebHex3Digit, deserializeWebHex3Digit) gpick:addConverter('color_web_hex_no_hash', _("Web: hex code (no hash symbol)"), serializeWebHexNoHash, deserializeWebHexNoHash) gpick:addConverter('color_css_hsl', _("CSS: hue saturation lightness"), serializeCssHsl) gpick:addConverter('color_css_rgb', _("CSS: red green blue"), serializeCssRgb, deserializeCssRgb) gpick:addConverter('css_color_hex', 'CSS(color)', serializeCssColorHex) gpick:addConverter('css_background_color_hex', 'CSS(background-color)', serializeCssBackgroundColorHex) gpick:addConverter('css_border_color_hex', 'CSS(border-color)', serializeCssBorderColorHex) gpick:addConverter('css_border_top_color_hex', 'CSS(border-top-color)', serializeCssBorderTopColorHex) gpick:addConverter('css_border_right_color_hex', 'CSS(border-right-color)', serializeCssBorderRightColorHex) gpick:addConverter('css_border_bottom_color_hex', 'CSS(border-bottom-color)', serializeCssBorderBottomColorHex) gpick:addConverter('css_border_left_hex', 'CSS(border-left-color)', serializeCssBorderLeftHex) gpick:addConverter('color_csv', 'CSV', serializeColorCsv) gpick:addConverter('color_css_block', 'CSS block', serializeColorCssBlock) return {} gpick-gpick-0.2.6/share/gpick/gpick-falloff-cubic.png000066400000000000000000000027421377073231300224160ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<_IDATX[lE3{vn/ҋjH9MD wB 6Ӡ@@P^%/@DC`Z6-֞r Җn0SZdrforsFT*Z<O>``+Xy涾>̛7ovQQDII_ZZ)**-..[SSӞ?)A9shH&ڵk/-\pd2y&RBJ|Æ 277Wr%Y:{_?}#eX4\afOC^= `F֭[7e˖uuuGg+@XGylWDC#]Zt:=Uno۶)q CpNdc!Xݷ7e=NmƁ~Ylf09i9FjlPPBFKnz:ojj|lҥ/ سgƕ q H0=gj >&$Hڣ?Pvq ٩o:]]]d2.4B2}]Es ɘp-)n7NHR뺋jkk`Z|'DJp)1k!TU2_U7[/\##I$K^ Lx‚'mx2,eqx ܕz6i“֤-dlb5W>00P  i%S O5*0&]hUUU⾾? /4kvdÓVŚTF҂'bUwH8ڜޭrLB ^#+05C&1U)6G,p u8:t~xxxM6Krǂ  A D ĢN9 ;Wky^bJ+zkV (4@F"Z\+!j. Q5q˖N ޜLmspNo#jIENDB`gpick-gpick-0.2.6/share/gpick/gpick-falloff-exponential.png000066400000000000000000000023571377073231300236610ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<lIDATXoLuݵwɠt5flA[ƀDقD1107آ25j4dpJ1bBVdnSF(c -ݸ{|qmqD ŞIr}>ߟ#"d+&F p%WAYCC7KKK<%%%o[r M%4< HeKKca W25c( !V D0Dh{gXDPWW9@8@ ,ؚ_v^$D"n|d@4]F4fXi} O={voF|[ IЌ ]Y~^ƌ,ѓt Ds^ L|oо;n'hjj =3+Kf` ,oڏ컒"BMMMOB @4ݒ\ 60# ,!B#+d&UU.nkk_hj  88 nQIqZ9y?2uww]v#̭_#:ƙI.1bI@(B Ab(!nքsbb,lۺ%g~]^7r/,,< .\PвD!4FqV(wtuO䣟u +77n.-}U˲|4o[-P($_EfB EL}5bዮ]{4-ٲX&cʱ `@" 2lHdNX%$uhx>{SUֳ<0nUv\K yD$"\w#n7+%T}fS>IENDB`gpick-gpick-0.2.6/share/gpick/gpick-falloff-linear.png000066400000000000000000000024501377073231300225770ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDATX[lUݙ-e{׶)6RDDPp@(bDbb ">(,Z@@ Z 5$B&\ZD -p邰`R]97fXDdr;NfhћA{n&x<ߛT {C ZBN=px;ݷ hzʓn۶m:F& U777/Z' EBaMH pr ZNU2m񹯕*Jid F֙{ ?PXTi|Uk؏?XnQWPW'V"`Q ppb4m ROA4,ԆID,aJfu-՜9bcF -**|pQB* E 6R"R(PHMN0讖}$r8ͣP)W\C,b;B23+?%aq}&OHJv5 =liAAAn'/aRv;90+$ekjÆo qoΝ3 l  $N3(M { nN&RCmr9?m=ơÿuuuwX>} @\GwJO윐ΛhZAF"|z`"ݭJ;5\ ]?η6L 5TY?L%Cbێ?_3gd2 ]GH!` ٰr P*) J ulwP[ly7#&j 1E{\z&ʋ!*|i1iQqΗ^Ĕ8ss@ˌuz" @ !aoM_p o iIENDB`gpick-gpick-0.2.6/share/gpick/gpick-falloff-none.png000066400000000000000000000004711377073231300222650ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDATX1 0"JG+x)/E:9T `!H^HB9jizc388$H@if$i$sg Mp &a!L)S kGN2~Ā٩w] w}^y P;Z-Ǥ @ ZIENDB`gpick-gpick-0.2.6/share/gpick/gpick-falloff-quadratic.png000066400000000000000000000027041377073231300233040ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<AIDATX[lUƿs;eiݶ-lmZ.+4F/Q1@44iRE#Ei6U!hA#-KCXae;{߇hI̙ߞgfr}]TUp$6s qh4*OقOp78"HLc*++iӦM:4844}w4@CCR8p8L^@#G#;HYJS\),ʉMIKhC/S.xz|>Z[[F"+V q;pn{GI€ bI< { }†h"~5&vPHܹDEE pv?`OP܇30X" (|آ |^m_7kjj^pe%88sOOMʹ-%HǏ7k oift-gIJ=ņ[|۲}%%% I)4ÄS0<μݹ, ~א1>=J6@RE:,XB%5XREG=O+Ǯm݌{/X,k.@:.9@sb 2X&'9R:{Ț41L|13?p“o߰5?0Va zf;J6k3ϵ(Dw>nݺՆaLki'Ya /Jp ΅i0lgM\4>|x.?4tlfSX T7X›XRʁԝϩj-(?Of<@^D,5dr9HrkXF-'A-[lG\0[|4"@<HJ9!%dc l_*\^Ej} B1 L!ysH!` %!6 0R!eg'^{܏ŋp)£?9s !aHP0)RT7hHPwNdvVu$32u~~GmKJtW`I,I²=b^Xa OVa&99:LuJZmڞsrr!L[\P%jCH BC6!8)KTHfC RavKdE`ɄzYҁi}X477݌d_p`~DgIENDB`gpick-gpick-0.2.6/share/gpick/gpick-gray-pattern.png000066400000000000000000000003551377073231300223350ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<jIDATXԱ 0 DяG+K+@tVzZ~<#IU(UPBePgf/2ʸ;`v;`~C|+IENDB`gpick-gpick-0.2.6/share/gpick/gpick-tray.png000066400000000000000000000032231377073231300206740ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<IDATh}leǿ׻׭^ `V& F4'f!IJL!,,B?L$1CLKvw? [a>{><;`I "w0z677׮B===p8$I6f\EEبuuujYYd2v+,,lʙ3g?#GyzD"\r^L&AnLӧOo]vi(I@% ^D"gbPɰbX~7Lؾ};<h&/"E!H/n4)͆JAyUU!I(Gřs\YZZjؽ{7\.0yQ'k,/G`Y$VUSU( CQQѼ'O㞕$ @@ew(2Lf EQE( I4MP(~a)ԧ.(1LF둒B1B /ޑ"HNPU4  Aq``B$IeY6*j}TJ1008G]<ϯ}*e:JzwwwjyC>.//㸿Z[[7 F~/,fFFƭljF ëɒBݴi^Z1R;kF%Ȳl/0E< ;v8'N_;a ̚8Ց쫩zח`>{lZzѯ[<ź, >%8;[aanYӈCP0e|w瑐uシq܌cx9 NUVW02;Fp:ۡizNnsc瞅v|s(|C}y}e SuM%؜{om2L}"!<̻{B6s^1({Ot\W#ѧȱbyj}%.N zvM ]jfu6dDIGӌZ iR?DԚvd$ m^v^UQAd %Ƃ%-by9Zˍ3ƈBmC2VotF3g0 \W/N#p[ GalS K`_ l/ݼ0ʟI&D{hS^=IENDB`gpick-gpick-0.2.6/share/gpick/gpick-tray.svg000066400000000000000000000165171377073231300207210ustar00rootroot00000000000000 image/svg+xml gpick-gpick-0.2.6/share/gpick/helpers.lua000066400000000000000000000005601377073231300202620ustar00rootroot00000000000000local function suggest(filename) local function p_require() require(filename) end local function supress_error(err) print(err) end return xpcall(p_require, supress_error) end local function round(number) if number - math.floor(number) >= 0.5 then return math.ceil(number) else return math.floor(number) end end return { suggest = suggest, round = round, } gpick-gpick-0.2.6/share/gpick/init.lua000066400000000000000000000024011377073231300175570ustar00rootroot00000000000000local gpick = require('gpick') local color = require('gpick/color') local helpers = require('helpers') local _ = gpick._ local round = helpers.round local componentToText = function(componentType, color) if componentType == 'rgb' then return {round(color:red() * 255) .. '', round(color:green() * 255) .. '', round(color:blue() * 255) .. ''} end if componentType == 'hsl' then return {round(color:hue() * 360) .. '', round(color:saturation() * 100) .. '', round(color:lightness() * 100) .. ''} end if componentType == 'hsv' then return {round(color:hue() * 360) .. '', round(color:saturation() * 100) .. '', round(color:value() * 100) .. ''} end if componentType == 'cmyk' then return {round(color:cyan() * 255) .. '', round(color:magenta() * 255) .. '', round(color:yellow() * 255) .. '', round(color:key_black() * 255) .. ''} end if componentType == 'lab' then return {round(color:labLightness()) .. '', round(color:labA()) .. '', round(color:labB()) .. ''} end if componentType == 'lch' then return {round(color:lchLightness()) .. '', round(color:lchChroma()) .. '', round(color:lchHue()) .. ''} end return {} end gpick:setComponentToTextCallback(componentToText) require('options') require('layouts') require('converters') helpers.suggest('user_init') gpick-gpick-0.2.6/share/gpick/layouts.lua000066400000000000000000000165331377073231300203270ustar00rootroot00000000000000local gpick = require('gpick') local color = require('gpick/color') local layout = require('gpick/layout') local _ = gpick._ local makeHelper = function(container) container:helperOnly(true) return container end local makeLocked = function(container) container:locked(true) return container end local addText = function(container, lines, style) local text = color:new() for i = 0, lines - 1 do container:add(layout:newText("content_text", 0.02, i * 0.06 + 0.01, 0.96, 0.06, style, _("The quick brown fox jumps over the lazy dog"))) end return container end local addButtons = function(container, buttons, percentage, buttonStyle, textStyle, spacing) local root = layout:newBox('', spacing , spacing, 1 - spacing * 2, percentage - spacing * 2) container:add(root) local size = 1 / buttons local padding = size / 8 local styleCount = #buttonStyle local styleTextCount = #textStyle local texts = {_("Homepage"), _("About us"), _("Links to us"), _("Privacy"), _("Terms"), _("Contact us"), _("RSS")} for i = 0, buttons - 1 do local button = layout:newFill("button", padding, i * size + padding, 1 - padding * 2, size - padding, buttonStyle[i % styleCount + 1]) button:add(makeHelper(layout:newText("button_text", 0.25, 0.65, 0.5, 0.3, textStyle[i % styleTextCount + 1], buttonStyle[i % styleCount + 1]:label()))) button:add(layout:newText("button_text", 0.25, 0.25, 0.5, 0.5, textStyle[i % styleTextCount + 1], texts[i % #texts + 1])) root:add(button) end return container end gpick:addLayout('std_layout_brightness_darkness', _("Brightness-Darkness"), function(system) local styles = { main = layout:newStyle("main:" .. _("main"), color:new(0.7, 0.7, 0.7)), bvar1 = layout:newStyle("b1:b1", color:new(0.3, 0.3, 0.3)), bvar2 = layout:newStyle("b2:b2", color:new(0.3, 0.3, 0.3)), bvar3 = layout:newStyle("b3:b3", color:new(0.3, 0.3, 0.3)), bvar4 = layout:newStyle("b4:b4", color:new(0.3, 0.3, 0.3)), cvar1 = layout:newStyle("c1:c1", color:new(0.3, 0.3, 0.3)), cvar2 = layout:newStyle("c2:c2", color:new(0.3, 0.3, 0.3)), cvar3 = layout:newStyle("c3:c3", color:new(0.3, 0.3, 0.3)), cvar4 = layout:newStyle("c4:c4", color:new(0.3, 0.3, 0.3)), } local stylesOrder = {'cvar4', 'cvar3', 'cvar2','cvar1', 'main', 'bvar1', 'bvar2', 'bvar3', 'bvar4'} for i, v in ipairs(stylesOrder) do system:addStyle(styles[v]) end local root = layout:newBox("root", 0, 0, 320, 128) system:setBox(root) root:add(makeLocked(layout:newFill("b1", 0.00, 0.00, 0.30, 0.25, styles['bvar1']))) root:add(makeLocked(layout:newFill("b2", 0.00, 0.25, 0.30, 0.25, styles['bvar2']))) root:add(makeLocked(layout:newFill("b3", 0.00, 0.50, 0.30, 0.25, styles['bvar3']))) root:add(makeLocked(layout:newFill("b4", 0.00, 0.75, 0.30, 0.25, styles['bvar4']))) root:add(makeLocked(layout:newFill("c1", 0.70, 0.00, 0.30, 0.25, styles['cvar1']))) root:add(makeLocked(layout:newFill("c2", 0.70, 0.25, 0.30, 0.25, styles['cvar2']))) root:add(makeLocked(layout:newFill("c3", 0.70, 0.50, 0.30, 0.25, styles['cvar3']))) root:add(makeLocked(layout:newFill("c4", 0.70, 0.75, 0.30, 0.25, styles['cvar4']))) root:add(layout:newFill("main", 0.30, 0.00, 0.40, 1.00, styles['main'])) end, 1) gpick:addLayout('std_layout_webpage_1', _("Webpage"), function(system) local styles = { header = layout:newStyle("header_b:" .. _("Header"), color:new(0.2, 0.2, 0.2)), header_text = layout:newStyle("header_t:" .. _("Header text"), color:new(1.0, 1.0, 1.0), 1.0), content = layout:newStyle("content_b:" .. _("Content"), color:new(0.6, 0.6, 0.6)), content_text = layout:newStyle("content_t:" .. _("Content text"), color:new(0.1, 0.1, 0.1), 0.6), sidebar = layout:newStyle("sidebar_b:" .. _("Sidebar"), color:new(0.7, 0.7, 0.7)), button = layout:newStyle("navitem_b:" .. _("Button"), color:new(0.3, 0.3, 0.3)), button_hover = layout:newStyle("navitem_bh:" .. _("Button (hover)"), color:new(0.35, 0.35, 0.35)), button_text = layout:newStyle("navitem_t:" .. _("Button text"), color:new(0.8, 0.8, 0.8), 0.95), button_text_hover = layout:newStyle("navitem_th:" .. _("Button text (hover)"), color:new(0.9, 0.9, 0.9), 0.95), footer = layout:newStyle("footer_b:" .. _("Footer"), color:new(0.1, 0.1, 0.1)), } for i, v in pairs(styles) do system:addStyle(v) end local root = layout:newBox("root", 0, 0, 640, 480) system:setBox(root) root:add(layout:newFill("header", 0, 0, 1, 0.15, styles['header']):add(layout:newText("header_text", 0.25, 0.25, 0.5, 0.5, styles['header_text'], _("Header")))) root:add(addButtons(layout:newFill("sidebar", 0, 0.15, 0.25, 0.8, styles['sidebar']), 6, 0.7, { styles['button'], styles['button'], styles['button_hover'] }, { styles['button_text'], styles['button_text'], styles['button_text_hover'] }, 0, 0)) root:add(addText(layout:newFill("content", 0.25, 0.15, 0.75, 0.8, styles['content']), 10, styles['content_text'])) root:add(layout:newFill("footer", 0, 0.95, 1, 0.05, styles['footer']):add(makeHelper(layout:newText("footer_text", 0.25, 0.5, 0.5, 0.45, nil, styles['footer']:label())))) end) gpick:addLayout('std_layout_menu_1', _("Menu"), function(system) local styles = { menu = layout:newStyle("menu_b:" .. _("Menu"), color:new(0.7, 0.7, 0.7)), button = layout:newStyle("navitem_b:" .. _("Button"), color:new(0.3, 0.3, 0.3)), button_hover = layout:newStyle("navitem_bh:" .. _("Button (hover)"), color:new(0.3, 0.3, 0.3)), button_text = layout:newStyle("navitem_t:" .. _("Button text"), color:new(0.8, 0.8, 0.8), 1.0), button_text_hover = layout:newStyle("navitem_th:" .. _("Button text (hover)"), color:new(0.8, 0.8, 0.8), 1.0), } for i, v in pairs(styles) do system:addStyle(v) end local root = layout:newBox("root", 0, 0, 300, 400) system:setBox(root) root:add(addButtons(layout:newFill("menu", 0, 0, 1, 1, styles['menu']), 7, 1, { styles['button'], styles['button'], styles['button_hover'] }, { styles['button_text'], styles['button_text'], styles['button_text_hover'] }, 0.1)) end) gpick:addLayout('std_layout_grid_1', _("Grid (4x3)"), function(system) local root = layout:newBox("root", 0, 0, 400, 300) system:setBox(root) for j = 0, 2 do for i = 0, 3 do local itemIndex = 1 + (i + j * 4) local style = layout:newStyle("item" .. itemIndex .. ":" .. _("Item") .. itemIndex, color:new(0.8, 0.8, 0.8), 1.0) local styleText = layout:newStyle("item" .. itemIndex .. "_text:" .. _("Item text") .. itemIndex, color:new(0.2, 0.2, 0.2), 0.5) system:addStyle(style) system:addStyle(styleText) local fill = layout:newFill("b" .. itemIndex, (1 / 4) * i, (1 / 3) * j, (1 / 4) * 0.95, (1 / 3) * 0.95, style) fill:add(layout:newText("item_text".. itemIndex, 0, 0.25, 1, 0.5, styleText, _("Item") .. itemIndex)) root:add(fill) end end end) gpick:addLayout('std_layout_grid_2', _("Grid (5x4)"), function(system) local root = layout:newBox("root", 0, 0, 500, 400) system:setBox(root) for j = 0, 3 do for i = 0, 4 do local itemIndex = 1 + (i + j * 5) local style = layout:newStyle("item" .. itemIndex .. ":" .. _("Item") .. itemIndex, color:new(0.8, 0.8, 0.8), 1.0) local styleText = layout:newStyle("item" .. itemIndex .. "_text:" .. _("Item text") .. itemIndex, color:new(0.2, 0.2, 0.2), 0.5) system:addStyle(style) system:addStyle(styleText) local fill = layout:newFill("b" .. itemIndex, (1 / 5) * i, (1 / 4) * j, (1 / 5) * 0.95, (1 / 4) * 0.95, style) fill:add(layout:newText("item_text".. itemIndex, 0, 0.25, 1, 0.5, styleText, _("Item") .. itemIndex)) root:add(fill) end end end) return {} gpick-gpick-0.2.6/share/gpick/logo.png000066400000000000000000000136401377073231300175660ustar00rootroot00000000000000PNG  IHDRZZ8AgIDATx{e}g&3d$BH$ pPEO-Zh)VTnGpb*!Deua=r@zŃʩ Cg~~{v.\ wwe^Y'>wfzCL ueyc3fttIoy衇TԧN~><ϫ8\$]+ƍ?GcH_]W^y;|߿R70( ?Zw`+ Q-zywJ9r9]10!d5OXлsdT)J2kqZ c RPJH/}_8>Id Q]xoqϻ7 ˕ 8]{BB@45AI _6?;vM5x*\EPJAk m,R}I[4kv$t;|Ocv15,%mZ(8D;WQ zѢES8wr @yM(bRJk<\w {C}0 U@.( Y) TRB "hTcN]uUaH0|b̓: ;y!dZBs{ %KzcyRD(z]O (iو 4zE/YruyAWZ.d19͸=UjK,_<~ITAt!~Uwu B y4hle0ց3rdÆ5٣:ڐ՞]^*xE ʓRB.,GBA8H1YWxbkDQ Z >} 9lPoPڂRrl=P,5Geh"9swazd ]%7[-6RHi@C:R^še*ꫯfyғ1YUGGG7͗3Q4SJɿNjO% BYV+h-A.4(mC_|5O Is~.cRJ.sQjm]_.x__AX76qR* mjY.P"DQSpK&{w?V8}sy c ZH)1FFFsW*ԏI}1{l '=!7[1vUHr" #K*9V?oq-^9 <ϣw!SJAAA#2I4M9R{FOم:n%7dpa\^֭~bַo4d$$sXk>|rι)O)(BR s$IRBJMnOq`D+.@v\z׻q/gy_eټ1omZ(}vι­18,dJqy#M4[9|GO< J/^GgpY)vcLWEj5 appc&OFUQk')JQ?2H zQ)c-zp?nSOa…s5 @kV,K!;h{lR`Bd(QĥZ 8pREԷlz){ă 8 `6m¦M9GZ#O=pCRJ1T 2dY8ɐ$`R1/8@>@Y8$1$2G8FZEQ( I86f#cMi!I%r(ƶJl<ݐ /]t '9BȀyzi)Z&o 9|GQ,8m~dh&0 RR9>bqzzxxxƍ/=60E]4pB h5[ر}ֈ2ւsclJ J 0ۣu1vy`{܁p`B6ZV|?(*X| ! L2 CJ=bmrF?Z9Ge[4("pletVsD4 ưr\x{\XkQbVGmg]Gs SpI'b9>}z{!;?_,W4MCi'6֠($l\aS;\hb?}xw>$xem1F[x@ z;,A̘y*<r 3`ҥyOs=1vʕ+ԩS?'<1A<Qg݇{sلo氟;{{΋z"!jeQ4JB4zm/qi(YnIbqF42ikbm.꤁O~1vܹr !wmxUdž /h/uRo 9D_F%/8TZ7ka1 YEawA.r1gϬ~~=D2QC+P)[HW&X p[EdA*p񧽸/N3D? ע3-Wb݁e RRZ¢( x rZXyżyoߺk֏yˣkA 5g+L ]yI Ah 4[YnQX0ݵ,=c7:!rK1<$l G+a iۅrem%.PP 4o^/wlQ4:i3OlZ!$3P]p!%m^R2̟gj~އp~'!#!̜aD9m߾7B9QYfijiaPH\ 6_Ʊ^pCj?}~07e칿+P؅8):'Ya ;`p!}f>TO/3İQrqhM _ 4ñǞ8x'}&{衱iaĿi}}'ccG@mO{cJdyE/_~O? G?O |z[T띇N8+d)jU:6tw,Fuޞi?[?a41*{{>,ᬞ{˅}'kV Z75򘒓8K. Lb`Y4?g8 B(9ry%"NՠeJjV5hM݅(kO|JS$HQ6L`æ_>{wm|  7̃1Gʑs r PUY5Av^E'J*nzI>[6?[5E1< (UyeѺ$^vBkֆv|yO*95H Ŭg4FF6}]q\![E >bOх,dZHڰn;Hٽf93}˗|Ϗ9Cux<(R) rZ)B[XmS_ ĩgez_#ܣscԓՄu(YGZ!7jQݝčc-\b:%3lj%_WG}덓%}|QXV5HQC,k9npRt|ww ǝ~9r̚aeuh}A3&9`~[VXD1!w3!'{B4<Ō;?{yGP7hg]q@l QƸ6h N- R O=OoIJǑ5ю(}MXRnC#L|BǟK=>FCP.˕}RohC@@wlc2>ڞ' &RihŲ|O~*oqRɫ szL~3$Ir C` oIl>4*艔LIFÐGQy{8)Slްau8ko 3/*Ź ' ٱbw'cὂS0e-|4<.'ldBqblj+=CgjXחO_9oYGa1ᫌ3(D[IdDZ1 u\݀G9kq2snDecM_G1a*}nIa!;S*rpJJmoM7?Iw}vIENDB`gpick-gpick-0.2.6/share/gpick/options.lua000066400000000000000000000003551377073231300203150ustar00rootroot00000000000000local gpick = require('gpick') local options = {} local optionsUpdate = function(params) options.upperCase = params:getString('gpick.options.hex_case', 'upper') == 'upper' end gpick:setOptionChangeCallback(optionsUpdate) return options gpick-gpick-0.2.6/share/icons/000077500000000000000000000000001377073231300161325ustar00rootroot00000000000000gpick-gpick-0.2.6/share/icons/hicolor/000077500000000000000000000000001377073231300175715ustar00rootroot00000000000000gpick-gpick-0.2.6/share/icons/hicolor/48x48/000077500000000000000000000000001377073231300203705ustar00rootroot00000000000000gpick-gpick-0.2.6/share/icons/hicolor/48x48/apps/000077500000000000000000000000001377073231300213335ustar00rootroot00000000000000gpick-gpick-0.2.6/share/icons/hicolor/48x48/apps/gpick.png000066400000000000000000000033411377073231300231370ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<^IDAThmlTerܙig,3mm ZaqaĪՍDLQ]Q1 Uf YdhRiE` ڈFАmS;eZw;N&_~1)k蹉"++Kz(~1Ƣyyy2 IRyJ#TU= KsޣiӡPHI0le)?pP(j"ȉp8ᅯX(& %Q{" -眳.Wh4"] p8䄁x<MC0Dccc oDhyy>M$) Vv Ϸ,\cUV=ֶMQMAMӒ&A0b6Lj^^|w p8xҥ Ec4 $Fqˬx|u |[ @@(2^\\-ÌNvoڴt9sfDxxl6`۽<'''.I҆|g۶m<OשS~? |1&V5eyq \wΝ)yɚIab,/~ $:wFEQ>z#Ź^|""!Ojw쮺tx H7O=|QwkTlb{Z^0ZA |ﱀWUr_a" +?K,` )}=G v1 "qG4T--QT/ =2g_v/PnE`R>kU 9~m{\)Q4-_Xe7#2I5gp4 ~?b̶8R{WSiV9V?79Nx[To= BDT7;9%c}.cao<9w95L ̳_Α  >Vڧ**7+fox`&ʿ~w>FD7w  [[YRJ%/`*v<McFMWȴвj'IENDB`gpick-gpick-0.2.6/share/icons/hicolor/scalable/000077500000000000000000000000001377073231300213375ustar00rootroot00000000000000gpick-gpick-0.2.6/share/icons/hicolor/scalable/apps/000077500000000000000000000000001377073231300223025ustar00rootroot00000000000000gpick-gpick-0.2.6/share/icons/hicolor/scalable/apps/gpick.svg000066400000000000000000000226251377073231300241270ustar00rootroot00000000000000 image/svg+xml gpick-gpick-0.2.6/share/locale/000077500000000000000000000000001377073231300162565ustar00rootroot00000000000000gpick-gpick-0.2.6/share/locale/cs/000077500000000000000000000000001377073231300166635ustar00rootroot00000000000000gpick-gpick-0.2.6/share/locale/cs/LC_MESSAGES/000077500000000000000000000000001377073231300204505ustar00rootroot00000000000000gpick-gpick-0.2.6/share/locale/cs/LC_MESSAGES/gpick.po000066400000000000000000000705771377073231300221250ustar00rootroot00000000000000# Pavel Fric , 2013. msgid "" msgstr "" "Project-Id-Version: gpick 0.2.5rc1\n" "POT-Creation-Date: 2013-01-05 16:16+0200\n" "PO-Revision-Date: 2013-06-25 18:37+0200\n" "Last-Translator: Pavel Fric \n" "Language-Team: Czech \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Language: cs\n" "X-Generator: Lokalize 1.5\n" #: source/BlendColors.cpp:114 source/BlendColors.cpp:116 msgid "blend node" msgstr "Uzel míchání" #: source/BlendColors.cpp:119 msgid "blend" msgstr "Míchání" #: source/BlendColors.cpp:308 source/BrightnessDarkness.cpp:260 #: source/ColorMixer.cpp:321 source/ColorPicker.cpp:367 #: source/GenerateScheme.cpp:444 source/LayoutPreview.cpp:405 #: source/Variations.cpp:331 source/uiDialogOptions.cpp:215 #: source/uiDialogOptions.cpp:234 msgid "_Add to palette" msgstr "_Přidat do palety" #: source/BlendColors.cpp:314 source/BrightnessDarkness.cpp:265 #: source/ColorMixer.cpp:326 source/ColorPicker.cpp:371 #: source/GenerateScheme.cpp:449 source/LayoutPreview.cpp:410 #: source/Variations.cpp:336 msgid "A_dd all to palette" msgstr "Při_dat všedo palety" #: source/BlendColors.cpp:320 source/BrightnessDarkness.cpp:271 #: source/ColorMixer.cpp:333 source/ColorPicker.cpp:377 #: source/GenerateScheme.cpp:456 source/LayoutPreview.cpp:416 #: source/Variations.cpp:343 source/uiDialogOptions.cpp:220 #: source/uiDialogOptions.cpp:239 msgid "_Copy to clipboard" msgstr "_Kopírovat do schránky" #: source/BlendColors.cpp:374 source/GenerateScheme.cpp:485 msgid "_Reset" msgstr "_Nastavit znovu" #: source/BlendColors.cpp:517 msgid "Start:" msgstr "Začátek:" #: source/BlendColors.cpp:533 msgid "Middle:" msgstr "Střed:" #: source/BlendColors.cpp:551 msgid "End:" msgstr "Konec:" #: source/BlendColors.cpp:568 source/GenerateScheme.cpp:875 #: source/uiDialogGenerate.cpp:237 source/uiDialogMix.cpp:249 #: source/transformation/ColorVisionDeficiency.cpp:363 msgid "Type:" msgstr "Typ:" #: source/BlendColors.cpp:570 source/ColorWheelType.cpp:56 #: source/uiDialogMix.cpp:251 msgid "RGB" msgstr "RGB" #: source/BlendColors.cpp:571 source/uiDialogMix.cpp:252 msgid "HSV" msgstr "HSV" #: source/BlendColors.cpp:572 source/uiDialogMix.cpp:253 msgid "HSV shortest hue distance" msgstr "Nejkratší vzdálenost odstínu HSV" #: source/BlendColors.cpp:573 source/uiDialogMix.cpp:254 msgid "LAB" msgstr "LAB" #: source/BlendColors.cpp:582 msgid "Start steps:" msgstr "Kroky:" #: source/BlendColors.cpp:590 msgid "End steps:" msgstr "Kroky:" #: source/BlendColors.cpp:627 msgid "Blend colors" msgstr "Míchat barvy" #: source/BrightnessDarkness.cpp:86 msgid "brightness darkness" msgstr "jas tma" #: source/BrightnessDarkness.cpp:287 source/ColorMixer.cpp:373 #: source/ColorPicker.cpp:387 source/GenerateScheme.cpp:469 #: source/LayoutPreview.cpp:430 source/Variations.cpp:383 msgid "_Edit..." msgstr "_Upravit..." #: source/BrightnessDarkness.cpp:292 source/ColorMixer.cpp:378 #: source/ColorPicker.cpp:391 source/GenerateScheme.cpp:474 #: source/LayoutPreview.cpp:435 source/Variations.cpp:388 msgid "_Paste" msgstr "_Vložit" #: source/BrightnessDarkness.cpp:385 msgid "Brightness" msgstr "Jas" #: source/BrightnessDarkness.cpp:385 msgid "Darkness" msgstr "Tma" #: source/BrightnessDarkness.cpp:431 msgid "Brightness Darkness" msgstr "Jas - Tma" #: source/ColorMixer.cpp:66 msgid "Normal" msgstr "Normální" #: source/ColorMixer.cpp:67 msgid "Multiply" msgstr "Násobit" #: source/ColorMixer.cpp:68 msgid "Add" msgstr "Přidat" #: source/ColorMixer.cpp:69 msgid "Difference" msgstr "Rozdíl" #: source/ColorMixer.cpp:70 source/ColorPicker.cpp:1180 #: source/ColorPicker.cpp:1194 source/ColorSpaceType.cpp:30 #: source/ColorSpaceType.cpp:37 source/Variations.cpp:66 msgid "Hue" msgstr "Odstín" #: source/ColorMixer.cpp:71 source/ColorPicker.cpp:1180 #: source/ColorPicker.cpp:1194 source/ColorSpaceType.cpp:31 #: source/ColorSpaceType.cpp:38 source/Variations.cpp:67 msgid "Saturation" msgstr "Sytost" #: source/ColorMixer.cpp:72 source/ColorPicker.cpp:1194 #: source/ColorPicker.cpp:1236 source/ColorPicker.cpp:1250 #: source/ColorSpaceType.cpp:39 source/ColorSpaceType.cpp:59 #: source/ColorSpaceType.cpp:66 source/Variations.cpp:68 msgid "Lightness" msgstr "Světlost" #: source/ColorMixer.cpp:114 msgid "color mixer" msgstr "Mísič barev" #: source/ColorMixer.cpp:234 msgid "secondary" msgstr "Doplňkový" #: source/ColorMixer.cpp:238 source/Variations.cpp:229 #, c-format msgid "primary %d" msgstr "Základní %d" #: source/ColorMixer.cpp:244 #, c-format msgid "result %d" msgstr "Výsledek %d" #: source/ColorMixer.cpp:704 msgid "Opacity:" msgstr "Neprůhlednost:" #: source/ColorMixer.cpp:732 msgid "Color mixer" msgstr "Mísič barev" #: source/ColorPicker.cpp:424 msgid "Press Spacebar to sample color under mouse pointer" msgstr "" "Stisknout mezerník pro odebrání vzorku zachycením barvy pod ukazovátkem myši" #: source/ColorPicker.cpp:699 source/uiConverter.cpp:163 msgid "Copy" msgstr "Kopírovat" #: source/ColorPicker.cpp:703 source/uiConverter.cpp:172 msgid "Paste" msgstr "Vložit" #: source/ColorPicker.cpp:709 source/uiColorInput.cpp:119 msgid "Edit" msgstr "Upravit" #: source/ColorPicker.cpp:771 source/uiApp.cpp:1012 #: source/uiDialogSort.cpp:222 msgid "None" msgstr "Žádný" #: source/ColorPicker.cpp:772 msgid "Linear" msgstr "Lineární" #: source/ColorPicker.cpp:773 msgid "Quadratic" msgstr "Kvadratický" #: source/ColorPicker.cpp:774 msgid "Cubic" msgstr "Kubický" #: source/ColorPicker.cpp:775 msgid "Exponential" msgstr "Exponenciální" #: source/ColorPicker.cpp:951 msgid "Click on swatch area to begin adding colors to palette" msgstr "Klepnout na oblast se vzorky pro započetí s přidáváním barev do palety" #: source/ColorPicker.cpp:1143 msgid "Settings" msgstr "Nastavení" #: source/ColorPicker.cpp:1153 msgid "Oversample:" msgstr "Oblast vzorku:" #: source/ColorPicker.cpp:1160 msgid "Falloff:" msgstr "Pokles:" #: source/ColorPicker.cpp:1167 msgid "Zoom:" msgstr "Zvětšení:" #: source/ColorPicker.cpp:1180 source/ColorSpaceType.cpp:32 msgid "Value" msgstr "Hodnota" #: source/ColorPicker.cpp:1208 source/ColorSpaceType.cpp:44 msgid "Red" msgstr "Červená" #: source/ColorPicker.cpp:1208 source/ColorSpaceType.cpp:45 msgid "Green" msgstr "Zelená" #: source/ColorPicker.cpp:1208 source/ColorSpaceType.cpp:46 msgid "Blue" msgstr "Modrá" #: source/ColorPicker.cpp:1222 source/ColorSpaceType.cpp:51 msgid "Cyan" msgstr "Azurová" #: source/ColorPicker.cpp:1222 source/ColorSpaceType.cpp:52 msgid "Magenta" msgstr "Purpurová" #: source/ColorPicker.cpp:1222 source/ColorSpaceType.cpp:53 msgid "Yellow" msgstr "Žlutá" #: source/ColorPicker.cpp:1222 source/ColorSpaceType.cpp:54 msgid "Key" msgstr "Černá (key)" #: source/ColorPicker.cpp:1258 msgid "Info" msgstr "Informace" #: source/ColorPicker.cpp:1267 msgid "Color name:" msgstr "Název barvy:" #: source/ColorPicker.cpp:1280 msgid "Contrast:" msgstr "Kontrast:" #: source/ColorPicker.cpp:1285 source/ColorPicker.cpp:1291 msgid "Sample" msgstr "Vzorek" #: source/ColorPicker.cpp:1324 msgid "Color picker" msgstr "Kapátko" #: source/ColorWheelType.cpp:57 msgid "RYB v1" msgstr "RYB v1" #: source/ColorWheelType.cpp:58 msgid "RYB v2" msgstr "RYB v2" #: source/GenerateScheme.cpp:90 msgid "Complementary" msgstr "Doplňkový" #: source/GenerateScheme.cpp:91 msgid "Analogous" msgstr "Analogový" #: source/GenerateScheme.cpp:92 msgid "Triadic" msgstr "Trojičný" #: source/GenerateScheme.cpp:93 msgid "Split-Complementary" msgstr "Rozdělit - doplňkový" #: source/GenerateScheme.cpp:94 msgid "Rectangle (tetradic)" msgstr "Obdélník (čtverný)" #: source/GenerateScheme.cpp:95 msgid "Square" msgstr "Čtverec" #: source/GenerateScheme.cpp:96 msgid "Neutral" msgstr "Neutrální" #: source/GenerateScheme.cpp:97 msgid "Clash" msgstr "Doplňkový - střetnutí" #: source/GenerateScheme.cpp:98 msgid "Five-Tone" msgstr "Pět tónů" #: source/GenerateScheme.cpp:99 msgid "Six-Tone" msgstr "Šest tónů" #: source/GenerateScheme.cpp:119 source/uiDialogGenerate.cpp:76 msgid "scheme" msgstr "Sada" #: source/GenerateScheme.cpp:292 msgid "_Locked" msgstr "_Uzamknuto" #: source/GenerateScheme.cpp:299 msgid "_Reset scheme" msgstr "_Nastavit sadu znovu" #: source/GenerateScheme.cpp:851 msgid "Hue:" msgstr "Odstín:" #: source/GenerateScheme.cpp:858 source/uiDialogVariations.cpp:171 msgid "Saturation:" msgstr "Sytost:" #: source/GenerateScheme.cpp:866 source/uiDialogVariations.cpp:156 msgid "Lightness:" msgstr "Světlost:" #: source/GenerateScheme.cpp:885 source/uiDialogGenerate.cpp:246 msgid "Color wheel:" msgstr "Kolo barev:" #: source/GenerateScheme.cpp:919 msgid "Scheme generation" msgstr "Vytvoření sady" #: source/LayoutPreview.cpp:78 msgid "layout preview" msgstr "Náhled na rozvržení" #: source/LayoutPreview.cpp:153 msgid "Style item" msgstr "Položka stylu" #: source/LayoutPreview.cpp:162 msgid "CSS selector" msgstr "Volič CSS" #: source/LayoutPreview.cpp:184 msgid "Assign CSS selectors" msgstr "Přiřadit voliče CSS" #: source/LayoutPreview.cpp:547 source/LayoutPreview.cpp:595 #: source/uiApp.cpp:690 source/uiApp.cpp:711 msgid "File could not be saved" msgstr "Soubor se nepodařilo uložit" #: source/LayoutPreview.cpp:558 source/uiExport.cpp:457 #: source/uiExport.cpp:523 msgid "Export" msgstr "Vyvést" #: source/LayoutPreview.cpp:572 msgid "Cascading Style Sheets *.css" msgstr "Listy s kaskádovými styly *.css" #: source/LayoutPreview.cpp:666 msgid "Layout:" msgstr "Rozvržení:" #: source/LayoutPreview.cpp:672 msgid "Export CSS File" msgstr "Vyvést soubor CSS" #: source/LayoutPreview.cpp:673 msgid "Export CSS file" msgstr "Vyvést soubor CSS" #: source/LayoutPreview.cpp:682 msgid "_Export CSS File As..." msgstr "_Vyvést soubor CSS jako..." #: source/LayoutPreview.cpp:686 msgid "_Assign CSS Selectors..." msgstr "_Přiřadit voliče CSS..." #: source/LayoutPreview.cpp:759 msgid "Layout preview" msgstr "Náhled na rozvržení" #: source/ToolColorNaming.cpp:25 msgid "_Empty" msgstr "_Prázdný" #: source/ToolColorNaming.cpp:26 msgid "_Automatic name" msgstr "_Automatický název" #: source/ToolColorNaming.cpp:27 msgid "_Tool specific" msgstr "Zvláštní _nástroj" #: source/Variations.cpp:69 msgid "Lightness (Lab)" msgstr "Světlost (Lab)" #: source/Variations.cpp:110 msgid "variations" msgstr "Obměny" #: source/Variations.cpp:225 msgid "all colors" msgstr "Všechny barvy" #: source/Variations.cpp:239 #, c-format msgid "result %d line %d" msgstr "Výsledek %d řádek %d" #: source/Variations.cpp:717 #: source/transformation/ColorVisionDeficiency.cpp:386 msgid "Strength:" msgstr "Síla:" #: source/Variations.cpp:745 source/uiDialogVariations.cpp:142 msgid "Variations" msgstr "Obměny" #: source/uiAbout.cpp:88 msgid "About Gpick" msgstr "O programu Gpick" #: source/uiAbout.cpp:121 msgid "Advanced color picker" msgstr "Pokročilý sběrač barev" #: source/uiAbout.cpp:126 msgid "Copyrights © 2009-2013, Albertas Vyšniauskas and Gpick development team" msgstr "" "Autorské právo © 2009-2013, Albertas Vyšniauskas a vývojářská skupina pro" "Gpick" #: source/uiAbout.cpp:141 msgid "License" msgstr "Povolení" #: source/uiAbout.cpp:142 msgid "Credits" msgstr "Zásluhy" #: source/uiAbout.cpp:143 msgid "Expat License" msgstr "Licence Expat" #: source/uiAbout.cpp:144 msgid "Lua License" msgstr "Licence Lua" #: source/uiApp.cpp:354 msgid "New palette" msgstr "Nová paleta" #: source/uiApp.cpp:360 msgid "(Imported)" msgstr "(Zavedeno)" #: source/uiApp.cpp:530 source/uiApp.cpp:545 source/uiApp.cpp:563 #: source/uiApp.cpp:641 msgid "File could not be opened" msgstr "Soubor se nepodařilo otevřít" #: source/uiApp.cpp:531 source/uiApp.cpp:546 source/uiApp.cpp:564 #: source/uiApp.cpp:642 msgid "Open" msgstr "Otevřít" #: source/uiApp.cpp:576 source/uiExport.cpp:473 source/uiExport.cpp:587 msgid "Gpick Palette (*.gpa)" msgstr "Paleta Gpick (*.gpa)" #: source/uiApp.cpp:577 source/uiExport.cpp:474 source/uiExport.cpp:588 msgid "GIMP/Inkscape Palette (*.gpl)" msgstr "Paleta GIMP/Inkscape (*.gpl)" #: source/uiApp.cpp:578 source/uiExport.cpp:476 source/uiExport.cpp:589 msgid "Adobe Swatch Exchange (*.ase)" msgstr "Adobe Swatch Exchange (*.ase)" #: source/uiApp.cpp:584 source/uiExport.cpp:598 #: source/tools/PaletteFromImage.cpp:548 msgid "All files" msgstr "Všechny soubory" #: source/uiApp.cpp:589 source/uiExport.cpp:607 msgid "All supported formats" msgstr "Všechny podporované formáty" #: source/uiApp.cpp:610 msgid "Open File" msgstr "Otevřít soubor" #: source/uiApp.cpp:659 source/uiApp.cpp:691 msgid "Save As" msgstr "Uložit jako" #: source/uiApp.cpp:712 msgid "Save" msgstr "Uložit" #: source/uiApp.cpp:771 msgid "Open Last File" msgstr "Otevřít poslední soubor" #: source/uiApp.cpp:916 msgid "Recent _files" msgstr "_Nedávné soubory" #: source/uiApp.cpp:946 msgid "Ex_port..." msgstr "Vy_vést..." #: source/uiApp.cpp:954 msgid "Expo_rt Selected..." msgstr "Vy_vést vybrané..." #: source/uiApp.cpp:962 msgid "_Import..." msgstr "_Zavést..." #: source/uiApp.cpp:977 msgid "_File" msgstr "_Soubor" #: source/uiApp.cpp:985 msgid "Edit _Converters..." msgstr "Upravit _převodníky..." #: source/uiApp.cpp:989 msgid "Display _Filters..." msgstr "Zobrazit _filtry..." #: source/uiApp.cpp:1001 msgid "_Edit" msgstr "Úp_ravy" #: source/uiApp.cpp:1037 msgid "_Secondary View" msgstr "_Doplňkový pohled" #: source/uiApp.cpp:1043 msgid "Palette" msgstr "Paleta" #: source/uiApp.cpp:1049 msgid "_View" msgstr "_Pohled" #: source/uiApp.cpp:1055 msgid "Palette From _Image..." msgstr "Paleta z _obrázku..." #: source/uiApp.cpp:1063 msgid "_Tools" msgstr "_Nástroje" #: source/uiApp.cpp:1078 msgid "_Help" msgstr "Nápo_věda" #: source/uiApp.cpp:1386 msgid "_Copy to Clipboard" msgstr "_Kopírovat do schránky" #: source/uiApp.cpp:1402 msgid "_Mix Colors..." msgstr "_Smíchat barvy..." #: source/uiApp.cpp:1407 msgid "_Variations..." msgstr "_Obměny..." #: source/uiApp.cpp:1412 msgid "_Generate..." msgstr "Vy_tvořit..." #: source/uiApp.cpp:1421 msgid "C_lear names" msgstr "_Smazat názvy" #: source/uiApp.cpp:1427 msgid "Autona_me" msgstr "Po_jmenovat automaticky" #: source/uiApp.cpp:1433 msgid "Auto_number..." msgstr "Čís_lovat automaticky" #: source/uiApp.cpp:1441 msgid "R_everse" msgstr "_Obrátit" #: source/uiApp.cpp:1447 msgid "Group and _sort..." msgstr "Seskupit a třídit" #: source/uiApp.cpp:1455 msgid "_Remove" msgstr "O_dstranit" #: source/uiApp.cpp:1461 msgid "Remove _All" msgstr "Odstranit _vše" #: source/uiApp.cpp:1869 msgid "Color pic_ker" msgstr "Volič _barvy" #: source/uiApp.cpp:1878 msgid "Scheme _generation" msgstr "_Vytvoření sady" #: source/uiApp.cpp:1897 msgid "Lay_out preview" msgstr "Náhled na _rozvržení" #: source/uiApp.cpp:1947 msgid "Pick colors (Ctrl+P)" msgstr "Zvolit si barvu (CTRL+P)" #: source/uiApp.cpp:1956 msgid "" "File is currently in a non-native format, possible loss of precision and/or " "metadata." msgstr "" "Soubor je v současnosti v nenativním formátu. Je možná ztráta přesnosti " "a/nebo popisných dat." #: source/uiColorInput.cpp:45 msgid "Edit color" msgstr "Upravit barvu" #: source/uiColorInput.cpp:69 msgid "Color:" msgstr "Barva:" #: source/uiConverter.cpp:56 msgid "Test color" msgstr "Vyzkoušet barvu" #: source/uiConverter.cpp:74 msgid "error" msgstr "Chyba" #: source/uiConverter.cpp:145 msgid "Function name" msgstr "Název funkce" #: source/uiConverter.cpp:154 msgid "Example" msgstr "Příklad" #: source/uiConverter.cpp:196 msgid "Converters" msgstr "Převodníky" #: source/uiConverter.cpp:224 msgid "Displays:" msgstr "Zobrazení:" #: source/uiConverter.cpp:230 msgid "Color list:" msgstr "Seznam barev:" #: source/uiDialogAutonumber.cpp:108 msgid "Autonumber colors" msgstr "Automatické číslování barev" #: source/uiDialogAutonumber.cpp:122 msgid "Name:" msgstr "Název:" #: source/uiDialogAutonumber.cpp:132 msgid "Decimal places:" msgstr "Desetinná místa:" #: source/uiDialogAutonumber.cpp:139 msgid "Starting number:" msgstr "Počáteční číslo:" #: source/uiDialogAutonumber.cpp:146 msgid "_Decreasing" msgstr "_Klesající" #: source/uiDialogAutonumber.cpp:152 msgid "_Append" msgstr "_Připojit" #: source/uiDialogAutonumber.cpp:158 msgid "Sample:" msgstr "Vzorek:" #: source/uiDialogGenerate.cpp:216 msgid "Generate colors" msgstr "Vytvořit barvy" #: source/uiDialogGenerate.cpp:230 source/tools/PaletteFromImage.cpp:599 msgid "Colors:" msgstr "Barvy:" #: source/uiDialogGenerate.cpp:257 msgid "Chaos:" msgstr "Chaos:" #: source/uiDialogGenerate.cpp:263 msgid "Seed:" msgstr "Semeno:" #: source/uiDialogGenerate.cpp:271 msgid "_Reverse" msgstr "__Otočit" #: source/uiDialogMix.cpp:76 source/uiDialogMix.cpp:78 msgid "mix node" msgstr "Uzel směsi" #: source/uiDialogMix.cpp:81 msgid "mix" msgstr "Směs" #: source/uiDialogMix.cpp:235 msgid "Mix colors" msgstr "Smíchat barvy" #: source/uiDialogMix.cpp:262 source/uiDialogVariations.cpp:186 msgid "Steps:" msgstr "Kroky:" #: source/uiDialogMix.cpp:270 msgid "_Include Endpoints" msgstr "_Zahrnout koncové body" #: source/uiDialogOptions.cpp:117 source/tools/PaletteFromImage.cpp:589 msgid "Options" msgstr "Volby" #: source/uiDialogOptions.cpp:134 msgid "System" msgstr "Systém" #: source/uiDialogOptions.cpp:143 msgid "_Single instance" msgstr "_Jedna instance" #: source/uiDialogOptions.cpp:148 msgid "Save/_Restore palette" msgstr "Uložit/Obnovit paletu" #: source/uiDialogOptions.cpp:154 msgid "System tray" msgstr "Oznamovací oblast panelu" #: source/uiDialogOptions.cpp:162 msgid "_Minimize to system tray" msgstr "_Zmenšit do oznamovací oblasti panelu" #: source/uiDialogOptions.cpp:167 msgid "_Close to system tray" msgstr "Z_avřít do oznamovací oblasti panelu" #: source/uiDialogOptions.cpp:172 msgid "_Start in system tray" msgstr "_Spustit v oznamovací oblasti panelu" #: source/uiDialogOptions.cpp:178 msgid "_Main" msgstr "_Hlavní" #: source/uiDialogOptions.cpp:184 msgid "Display" msgstr "Zobrazení" #: source/uiDialogOptions.cpp:193 msgid "_Refresh rate:" msgstr "_Obnovovací rychlost:" #: source/uiDialogOptions.cpp:201 msgid "_Magnified area size:" msgstr "Velikost z_většené oblasti:" #: source/uiDialogOptions.cpp:207 msgid "Floating picker click behaviour" msgstr "Chování klepnutí u plovoucího sběrače" #: source/uiDialogOptions.cpp:226 msgid "'Spacebar' button behaviour" msgstr "Chování mezerníku" #: source/uiDialogOptions.cpp:244 msgid "_Rotate swatch" msgstr "_Otočit vzorky" #: source/uiDialogOptions.cpp:251 msgid "Enabled color spaces" msgstr "Povoleny barevné prostory" #: source/uiDialogOptions.cpp:266 msgid "Lab settings" msgstr "Nastavení Lab" #: source/uiDialogOptions.cpp:278 msgid "_Illuminant:" msgstr "_Světlo:" #: source/uiDialogOptions.cpp:302 msgid "_Observer:" msgstr "_Pozorovatel:" #: source/uiDialogOptions.cpp:321 msgid "Other settings" msgstr "Jiná nastavení" #: source/uiDialogOptions.cpp:330 msgid "_Mask out of gamut colors" msgstr "Za_krýt barvy mimo rozsah" #: source/uiDialogOptions.cpp:336 msgid "_Picker" msgstr "_Kapátko" #: source/uiDialogOptions.cpp:341 msgid "Color name generation" msgstr "Vytvoření názvu barvy" #: source/uiDialogOptions.cpp:350 msgid "_Imprecision postfix" msgstr "Připojení _nepřesnosti" #: source/uiDialogOptions.cpp:356 msgid "Tool color naming" msgstr "Přiřazení názvu barvy" #: source/uiDialogOptions.cpp:381 msgid "_Color names" msgstr "_Názvy barev" #: source/uiDialogSort.cpp:135 source/uiDialogSort.cpp:223 msgid "RGB Red" msgstr "Červená RGB" #: source/uiDialogSort.cpp:136 source/uiDialogSort.cpp:224 msgid "RGB Green" msgstr "Zelená RGB" #: source/uiDialogSort.cpp:137 source/uiDialogSort.cpp:225 msgid "RGB Blue" msgstr "Modrá RGB" #: source/uiDialogSort.cpp:138 source/uiDialogSort.cpp:226 msgid "RGB Grayscale" msgstr "Odstíny šedé RGB" #: source/uiDialogSort.cpp:139 source/uiDialogSort.cpp:227 msgid "HSL Hue" msgstr "Odstín HSL" #: source/uiDialogSort.cpp:140 source/uiDialogSort.cpp:228 msgid "HSL Saturation" msgstr "Sytost HSL" #: source/uiDialogSort.cpp:141 source/uiDialogSort.cpp:229 msgid "HSL Lightness" msgstr "Světlost HSL" #: source/uiDialogSort.cpp:142 source/uiDialogSort.cpp:230 msgid "Lab Lightness" msgstr "Světlost Lab" #: source/uiDialogSort.cpp:143 source/uiDialogSort.cpp:231 msgid "Lab A" msgstr "Lab A" #: source/uiDialogSort.cpp:144 source/uiDialogSort.cpp:232 msgid "Lab B" msgstr "Lab B" #: source/uiDialogSort.cpp:145 source/uiDialogSort.cpp:233 msgid "LCh Lightness" msgstr "Světlost LCh" #: source/uiDialogSort.cpp:146 source/uiDialogSort.cpp:234 msgid "LCh Chroma" msgstr "Chroma LCh (barevná čistota)" #: source/uiDialogSort.cpp:147 source/uiDialogSort.cpp:235 msgid "LCh Hue" msgstr "Odstín LCh" #: source/uiDialogSort.cpp:556 msgid "Group and sort" msgstr "Seskupit a třídit" #: source/uiDialogSort.cpp:564 msgid "Group type:" msgstr "Typ skupiny:" #: source/uiDialogSort.cpp:574 msgid "Grouping sensitivity:" msgstr "Citlivost seskupení:" #: source/uiDialogSort.cpp:581 msgid "Maximum number of groups:" msgstr "Největší počet skupin:" #: source/uiDialogSort.cpp:588 msgid "Sort type:" msgstr "Typ třídění:" #: source/uiDialogSort.cpp:598 msgid "_Reverse group order" msgstr "O_brácený pořádek skupin" #: source/uiDialogSort.cpp:604 msgid "_Reverse order inside groups" msgstr "O_brácený pořádek skupin uvnitř skupin" #: source/uiDialogVariations.cpp:60 msgid "variation" msgstr "Obměna" #: source/uiDialogVariations.cpp:194 msgid "_Use multiplication" msgstr "_Použít násobení" #: source/uiExport.cpp:475 msgid "Alias/WaveFront Material (*.mtl)" msgstr "Materiál Alias/WaveFront (*.mtl)" #: source/uiExport.cpp:477 msgid "Text file (*.txt)" msgstr "Textový soubor (*.txt)" #: source/uiExport.cpp:522 msgid "File could not be exported" msgstr "Soubor se nepodařilo vyvést" #: source/uiExport.cpp:573 source/uiExport.cpp:654 source/uiExport.cpp:666 msgid "Import" msgstr "Zavést" #: source/uiExport.cpp:653 msgid "File format is not supported" msgstr "Formát souboru není podporován" #: source/uiExport.cpp:665 msgid "File could not be imported" msgstr "Soubor se nepodařilo zavést" #: source/uiListPalette.cpp:158 source/uiListPalette.cpp:160 #, c-format msgid "%d color" msgid_plural "%d colors" msgstr[0] "%d barva" msgstr[1] "%d barev" #: source/uiListPalette.cpp:166 msgid "selected" msgstr "vybráno" #: source/uiListPalette.cpp:172 source/uiListPalette.cpp:174 #, c-format msgid "Total %d color" msgid_plural "Total %d colors" msgstr[0] "Celkem %d barva" msgstr[1] "Celkem %d barev" #: source/uiListPalette.cpp:353 msgid "Preview" msgstr "Náhled" #: source/uiListPalette.cpp:708 source/uiListPalette.cpp:717 msgid "Color" msgstr "Barva" #: source/uiListPalette.cpp:726 source/uiTransformations.cpp:183 msgid "Name" msgstr "Název" #: source/uiStatusIcon.cpp:67 msgid "_Show Main Window" msgstr "_Ukázat hlavní okno" #: source/uiStatusIcon.cpp:74 msgid "_Quit" msgstr "_Ukončit" #: source/uiTransformations.cpp:245 msgid "Display filters" msgstr "Filtry zobrazení" #: source/uiTransformations.cpp:259 msgid "_Enabled" msgstr "_Zapnuto" #: source/tools/PaletteFromImage.cpp:514 msgid "Palette from image" msgstr "Paleta z obrázku" #: source/tools/PaletteFromImage.cpp:527 msgid "Image" msgstr "Obrázek" #: source/tools/PaletteFromImage.cpp:536 msgid "Image file" msgstr "Obrázkový soubor" #: source/tools/PaletteFromImage.cpp:556 msgid "All images" msgstr "Všechny obrázky" #: source/transformation/ColorVisionDeficiency.cpp:41 msgid "Color vision deficiency" msgstr "Nedostatek ve vidění barvy" #: source/transformation/ColorVisionDeficiency.cpp:330 msgid "Protanomaly" msgstr "Částečně bez červené" #: source/transformation/ColorVisionDeficiency.cpp:331 msgid "Deuteranomaly" msgstr "Částečně bez zelené" #: source/transformation/ColorVisionDeficiency.cpp:332 msgid "Tritanomaly" msgstr "Částečně bez modré" #: source/transformation/ColorVisionDeficiency.cpp:333 msgid "Protanopia" msgstr "Bez červené" #: source/transformation/ColorVisionDeficiency.cpp:334 msgid "Deuteranopia" msgstr "Bez zelené" #: source/transformation/ColorVisionDeficiency.cpp:335 msgid "Tritanopia" msgstr "Bez modré" #: source/transformation/ColorVisionDeficiency.cpp:422 msgid "Altered spectral sensitivity of red receptors" msgstr "" "Změněná spektrální citlivost čidel červené barvy. Částečná barvoslepost pro " "červenou barvu" #: source/transformation/ColorVisionDeficiency.cpp:423 msgid "Altered spectral sensitivity of green receptors" msgstr "" "Změněná spektrální citlivost čidel zelené barvy. Částečná barvoslepost pro " "zelenou barvu" #: source/transformation/ColorVisionDeficiency.cpp:424 msgid "Altered spectral sensitivity of blue receptors" msgstr "" "Změněná spektrální citlivost čidel modré barvy. Částečná barvoslepost pro " "modrou barvu" #: source/transformation/ColorVisionDeficiency.cpp:425 msgid "Absence of red receptors" msgstr "Nepřítomnost čidel červené barvy. Barvoslepost na červenou barvu" #: source/transformation/ColorVisionDeficiency.cpp:426 msgid "Absence of green receptors" msgstr "Nepřítomnost čidel zelené barvy. Barvoslepost na zelenou barvu" #: source/transformation/ColorVisionDeficiency.cpp:427 msgid "Absence of blue receptors" msgstr "Nepřítomnost čidel modré barvy. Barvoslepost na modrou barvu" #: source/transformation/GammaModification.cpp:38 msgid "Gamma modification" msgstr "Pozměnění gamy" #: source/transformation/GammaModification.cpp:88 #: source/transformation/Quantization.cpp:96 msgid "Value:" msgstr "Hodnota:" #: source/transformation/Quantization.cpp:40 msgid "Quantization" msgstr "Kvantizace" #: source/transformation/Quantization.cpp:101 msgid "Clip top-end" msgstr "Oříznout horní okraj" #: share/gpick/init.lua:173 msgid "Web: hex code" msgstr "Web: šestnáctkový kód" #: share/gpick/init.lua:178 msgid "Web: hex code (3 digits)" msgstr "Web: šestnáctkový kód (3 číslice)" #: share/gpick/init.lua:183 msgid "Web: hex code (no hash symbol)" msgstr "Web: šestnáctkový kód (žádný hash symbol)" #: share/gpick/init.lua:188 msgid "CSS: hue saturation lightness" msgstr "CSS: odstín sytost světlost" #: share/gpick/init.lua:193 msgid "CSS: red green blue" msgstr "CSS: červená zelená modrá" #: share/gpick/layouts.lua:15 msgid "Homepage" msgstr "Stránky projektu" #: share/gpick/layouts.lua:15 msgid "About us" msgstr "O nás" #: share/gpick/layouts.lua:15 msgid "Links to us" msgstr "Odkazy" #: share/gpick/layouts.lua:15 msgid "Privacy" msgstr "Soukromí" #: share/gpick/layouts.lua:15 msgid "Terms" msgstr "Podmínky" #: share/gpick/layouts.lua:15 msgid "Contact us" msgstr "Spojení" #: share/gpick/layouts.lua:15 msgid "RSS" msgstr "RSS" #: share/gpick/layouts.lua:30 msgid "The quick brown fox jumps over the lazy dog" msgstr "" "Maličká včelka vydávala při letu nad svazenkovým polem bzučivé " "tóny. My také zpíváme a toužíme po krásně chutnajícím medu." #: share/gpick/layouts.lua:46 msgid "Webpage" msgstr "Stránky" #: share/gpick/layouts.lua:51 share/gpick/layouts.lua:73 msgid "Header" msgstr "Záhlaví" #: share/gpick/layouts.lua:52 msgid "Header text" msgstr "Text záhlaví" #: share/gpick/layouts.lua:54 msgid "Content" msgstr "Obsah" #: share/gpick/layouts.lua:55 msgid "Content text" msgstr "Text obsahu" #: share/gpick/layouts.lua:57 msgid "Sidebar" msgstr "Postranní panel" #: share/gpick/layouts.lua:59 share/gpick/layouts.lua:87 msgid "Button" msgstr "Tlačítko" #: share/gpick/layouts.lua:60 share/gpick/layouts.lua:88 msgid "Button (hover)" msgstr "Tlačítko (přejetí)" #: share/gpick/layouts.lua:61 share/gpick/layouts.lua:89 msgid "Button text" msgstr "Text tlačítka" #: share/gpick/layouts.lua:62 share/gpick/layouts.lua:90 msgid "Button text (hover)" msgstr "Text tlačítka (přejetí)" #: share/gpick/layouts.lua:64 msgid "Footer" msgstr "Zápatí" #: share/gpick/layouts.lua:82 share/gpick/layouts.lua:86 msgid "Menu" msgstr "Nabídka" #: share/gpick/layouts.lua:106 msgid "Brightness-Darkness" msgstr "Jas - Tma" #: share/gpick/layouts.lua:110 msgid "main" msgstr "Hlavní" #: share/gpick/layouts.lua:144 msgid "Grid (4x3)" msgstr "Mřížka (4x3)" #: share/gpick/layouts.lua:153 share/gpick/layouts.lua:159 #: share/gpick/layouts.lua:180 share/gpick/layouts.lua:186 msgid "Item" msgstr "Položka" #: share/gpick/layouts.lua:154 share/gpick/layouts.lua:181 msgid "Item text" msgstr "Text položky" #: share/gpick/layouts.lua:171 msgid "Grid (5x4)" msgstr "Mřížka (5x4)" #~ msgid "Edit _Transformations..." #~ msgstr "Editar _Transformaciones..." gpick-gpick-0.2.6/share/locale/es/000077500000000000000000000000001377073231300166655ustar00rootroot00000000000000gpick-gpick-0.2.6/share/locale/es/LC_MESSAGES/000077500000000000000000000000001377073231300204525ustar00rootroot00000000000000gpick-gpick-0.2.6/share/locale/es/LC_MESSAGES/gpick.po000066400000000000000000000671231377073231300221200ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: gpick 0.2.5rc1\n" "POT-Creation-Date: 2013-01-05 16:16+0200\n" "PO-Revision-Date: 2013-01-06 17:59-0300\n" "Last-Translator: Guillermo Espertino \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: source/BlendColors.cpp:114 source/BlendColors.cpp:116 msgid "blend node" msgstr "nodo de mezcla" #: source/BlendColors.cpp:119 msgid "blend" msgstr "mezcla" #: source/BlendColors.cpp:308 source/BrightnessDarkness.cpp:260 #: source/ColorMixer.cpp:321 source/ColorPicker.cpp:367 #: source/GenerateScheme.cpp:444 source/LayoutPreview.cpp:405 #: source/Variations.cpp:331 source/uiDialogOptions.cpp:215 #: source/uiDialogOptions.cpp:234 msgid "_Add to palette" msgstr "_Agregar a la paleta" #: source/BlendColors.cpp:314 source/BrightnessDarkness.cpp:265 #: source/ColorMixer.cpp:326 source/ColorPicker.cpp:371 #: source/GenerateScheme.cpp:449 source/LayoutPreview.cpp:410 #: source/Variations.cpp:336 msgid "A_dd all to palette" msgstr "Agregar to_do a la paleta" #: source/BlendColors.cpp:320 source/BrightnessDarkness.cpp:271 #: source/ColorMixer.cpp:333 source/ColorPicker.cpp:377 #: source/GenerateScheme.cpp:456 source/LayoutPreview.cpp:416 #: source/Variations.cpp:343 source/uiDialogOptions.cpp:220 #: source/uiDialogOptions.cpp:239 msgid "_Copy to clipboard" msgstr "_Copiar al portapapeles" #: source/BlendColors.cpp:374 source/GenerateScheme.cpp:485 msgid "_Reset" msgstr "_Reestablecer" #: source/BlendColors.cpp:517 msgid "Start:" msgstr "Inicio:" #: source/BlendColors.cpp:533 msgid "Middle:" msgstr "Medio:" #: source/BlendColors.cpp:551 msgid "End:" msgstr "Final:" #: source/BlendColors.cpp:568 source/GenerateScheme.cpp:875 #: source/uiDialogGenerate.cpp:237 source/uiDialogMix.cpp:249 #: source/transformation/ColorVisionDeficiency.cpp:363 msgid "Type:" msgstr "Tipo:" #: source/BlendColors.cpp:570 source/ColorWheelType.cpp:56 #: source/uiDialogMix.cpp:251 msgid "RGB" msgstr "RGB" #: source/BlendColors.cpp:571 source/uiDialogMix.cpp:252 msgid "HSV" msgstr "HSV" #: source/BlendColors.cpp:572 source/uiDialogMix.cpp:253 msgid "HSV shortest hue distance" msgstr "HSV distancia de matiz más corta" #: source/BlendColors.cpp:573 source/uiDialogMix.cpp:254 msgid "LAB" msgstr "LAB" #: source/BlendColors.cpp:582 msgid "Start steps:" msgstr "Pasos al inicio:" #: source/BlendColors.cpp:590 msgid "End steps:" msgstr "Pasos al final:" #: source/BlendColors.cpp:627 msgid "Blend colors" msgstr "Mezclar colores" #: source/BrightnessDarkness.cpp:86 msgid "brightness darkness" msgstr "brillo oscuridad" #: source/BrightnessDarkness.cpp:287 source/ColorMixer.cpp:373 #: source/ColorPicker.cpp:387 source/GenerateScheme.cpp:469 #: source/LayoutPreview.cpp:430 source/Variations.cpp:383 msgid "_Edit..." msgstr "_Editar..." #: source/BrightnessDarkness.cpp:292 source/ColorMixer.cpp:378 #: source/ColorPicker.cpp:391 source/GenerateScheme.cpp:474 #: source/LayoutPreview.cpp:435 source/Variations.cpp:388 msgid "_Paste" msgstr "_Pegar" #: source/BrightnessDarkness.cpp:385 msgid "Brightness" msgstr "Brillo" #: source/BrightnessDarkness.cpp:385 msgid "Darkness" msgstr "Oscuridad" #: source/BrightnessDarkness.cpp:431 msgid "Brightness Darkness" msgstr "Brillo - Oscuridad" #: source/ColorMixer.cpp:66 msgid "Normal" msgstr "Normal" #: source/ColorMixer.cpp:67 msgid "Multiply" msgstr "Multiplicar" #: source/ColorMixer.cpp:68 msgid "Add" msgstr "Suma" #: source/ColorMixer.cpp:69 msgid "Difference" msgstr "Diferencia" #: source/ColorMixer.cpp:70 source/ColorPicker.cpp:1180 #: source/ColorPicker.cpp:1194 source/ColorSpaceType.cpp:30 #: source/ColorSpaceType.cpp:37 source/Variations.cpp:66 msgid "Hue" msgstr "Matiz" #: source/ColorMixer.cpp:71 source/ColorPicker.cpp:1180 #: source/ColorPicker.cpp:1194 source/ColorSpaceType.cpp:31 #: source/ColorSpaceType.cpp:38 source/Variations.cpp:67 msgid "Saturation" msgstr "Saturación" #: source/ColorMixer.cpp:72 source/ColorPicker.cpp:1194 #: source/ColorPicker.cpp:1236 source/ColorPicker.cpp:1250 #: source/ColorSpaceType.cpp:39 source/ColorSpaceType.cpp:59 #: source/ColorSpaceType.cpp:66 source/Variations.cpp:68 msgid "Lightness" msgstr "Luminosidad" #: source/ColorMixer.cpp:114 msgid "color mixer" msgstr "mezclador de colores" #: source/ColorMixer.cpp:234 #, fuzzy msgid "secondary" msgstr "Vista _Secundaria" #: source/ColorMixer.cpp:238 source/Variations.cpp:229 #, c-format msgid "primary %d" msgstr "" #: source/ColorMixer.cpp:244 #, c-format msgid "result %d" msgstr "" #: source/ColorMixer.cpp:704 msgid "Opacity:" msgstr "Opacidad:" #: source/ColorMixer.cpp:732 msgid "Color mixer" msgstr "Mezclador de colores" #: source/ColorPicker.cpp:424 msgid "Press Spacebar to sample color under mouse pointer" msgstr "Presione Espacio para capturar el color debajo del puntero" #: source/ColorPicker.cpp:699 source/uiConverter.cpp:163 msgid "Copy" msgstr "Copiar" #: source/ColorPicker.cpp:703 source/uiConverter.cpp:172 msgid "Paste" msgstr "Pegar" #: source/ColorPicker.cpp:709 source/uiColorInput.cpp:119 msgid "Edit" msgstr "Editar" #: source/ColorPicker.cpp:771 source/uiApp.cpp:1012 #: source/uiDialogSort.cpp:222 msgid "None" msgstr "Ninguna" #: source/ColorPicker.cpp:772 msgid "Linear" msgstr "Lineal" #: source/ColorPicker.cpp:773 msgid "Quadratic" msgstr "Cuadrática" #: source/ColorPicker.cpp:774 msgid "Cubic" msgstr "Cúbica" #: source/ColorPicker.cpp:775 msgid "Exponential" msgstr "Exponencial" #: source/ColorPicker.cpp:951 msgid "Click on swatch area to begin adding colors to palette" msgstr "" "Haga click sobre el área de muestras para empezar a agregar colores a la " "paleta" #: source/ColorPicker.cpp:1143 msgid "Settings" msgstr "Ajustes" #: source/ColorPicker.cpp:1153 msgid "Oversample:" msgstr "Sobremuestreo:" #: source/ColorPicker.cpp:1160 msgid "Falloff:" msgstr "Atenuación:" #: source/ColorPicker.cpp:1167 msgid "Zoom:" msgstr "Ampliación:" #: source/ColorPicker.cpp:1180 source/ColorSpaceType.cpp:32 msgid "Value" msgstr "Valor" #: source/ColorPicker.cpp:1208 source/ColorSpaceType.cpp:44 msgid "Red" msgstr "Rojo" #: source/ColorPicker.cpp:1208 source/ColorSpaceType.cpp:45 msgid "Green" msgstr "Verde" #: source/ColorPicker.cpp:1208 source/ColorSpaceType.cpp:46 msgid "Blue" msgstr "Azul" #: source/ColorPicker.cpp:1222 source/ColorSpaceType.cpp:51 msgid "Cyan" msgstr "Cián" #: source/ColorPicker.cpp:1222 source/ColorSpaceType.cpp:52 msgid "Magenta" msgstr "Magenta" #: source/ColorPicker.cpp:1222 source/ColorSpaceType.cpp:53 msgid "Yellow" msgstr "Amarillo" #: source/ColorPicker.cpp:1222 source/ColorSpaceType.cpp:54 msgid "Key" msgstr "Negro (key)" #: source/ColorPicker.cpp:1258 msgid "Info" msgstr "Información" #: source/ColorPicker.cpp:1267 msgid "Color name:" msgstr "Nombre del color:" #: source/ColorPicker.cpp:1280 msgid "Contrast:" msgstr "Contraste:" #: source/ColorPicker.cpp:1285 source/ColorPicker.cpp:1291 msgid "Sample" msgstr "Muestra" #: source/ColorPicker.cpp:1324 msgid "Color picker" msgstr "Selector de color" #: source/ColorWheelType.cpp:57 msgid "RYB v1" msgstr "RYB v1" #: source/ColorWheelType.cpp:58 msgid "RYB v2" msgstr "RYB v2" #: source/GenerateScheme.cpp:90 msgid "Complementary" msgstr "Complementarios" #: source/GenerateScheme.cpp:91 msgid "Analogous" msgstr "Análogos" #: source/GenerateScheme.cpp:92 msgid "Triadic" msgstr "Tríada" #: source/GenerateScheme.cpp:93 msgid "Split-Complementary" msgstr "Complementarios divididos" #: source/GenerateScheme.cpp:94 msgid "Rectangle (tetradic)" msgstr "Rectangular (Tétrada)" #: source/GenerateScheme.cpp:95 msgid "Square" msgstr "Cuadrado" #: source/GenerateScheme.cpp:96 msgid "Neutral" msgstr "Neutros" #: source/GenerateScheme.cpp:97 msgid "Clash" msgstr "Complementarios en tensión" #: source/GenerateScheme.cpp:98 msgid "Five-Tone" msgstr "Cinco Tonos" #: source/GenerateScheme.cpp:99 msgid "Six-Tone" msgstr "Seis Tonos" #: source/GenerateScheme.cpp:119 source/uiDialogGenerate.cpp:76 msgid "scheme" msgstr "armonía" #: source/GenerateScheme.cpp:292 msgid "_Locked" msgstr "_Bloqueado" #: source/GenerateScheme.cpp:299 msgid "_Reset scheme" msgstr "_Reestablecer armonía" #: source/GenerateScheme.cpp:851 msgid "Hue:" msgstr "Matiz:" #: source/GenerateScheme.cpp:858 source/uiDialogVariations.cpp:171 msgid "Saturation:" msgstr "Saturación:" #: source/GenerateScheme.cpp:866 source/uiDialogVariations.cpp:156 msgid "Lightness:" msgstr "Luminosidad:" #: source/GenerateScheme.cpp:885 source/uiDialogGenerate.cpp:246 msgid "Color wheel:" msgstr "Rueda de color:" #: source/GenerateScheme.cpp:919 msgid "Scheme generation" msgstr "Generación de armonías" #: source/LayoutPreview.cpp:78 msgid "layout preview" msgstr "vista previa de diseño" #: source/LayoutPreview.cpp:153 msgid "Style item" msgstr "Ítem de estilo" #: source/LayoutPreview.cpp:162 msgid "CSS selector" msgstr "Selector CSS" #: source/LayoutPreview.cpp:184 msgid "Assign CSS selectors" msgstr "Asignar selectores CSS" #: source/LayoutPreview.cpp:547 source/LayoutPreview.cpp:595 #: source/uiApp.cpp:690 source/uiApp.cpp:711 msgid "File could not be saved" msgstr "El archivo no pudo ser guardado" #: source/LayoutPreview.cpp:558 source/uiExport.cpp:457 #: source/uiExport.cpp:523 msgid "Export" msgstr "Exportar" #: source/LayoutPreview.cpp:572 msgid "Cascading Style Sheets *.css" msgstr "Hojas de Estilos en Cascada *.css" #: source/LayoutPreview.cpp:666 msgid "Layout:" msgstr "Diseño:" #: source/LayoutPreview.cpp:672 msgid "Export CSS File" msgstr "Exportar Archivo CSS" #: source/LayoutPreview.cpp:673 msgid "Export CSS file" msgstr "Exportar archivo CSS" #: source/LayoutPreview.cpp:682 msgid "_Export CSS File As..." msgstr "_Exportar archivo CSS como..." #: source/LayoutPreview.cpp:686 msgid "_Assign CSS Selectors..." msgstr "_Asignar selectores CSS..." #: source/LayoutPreview.cpp:759 msgid "Layout preview" msgstr "Vista previa de diseño" #: source/ToolColorNaming.cpp:25 msgid "_Empty" msgstr "Ninguno" #: source/ToolColorNaming.cpp:26 msgid "_Automatic name" msgstr "Nombre _automático" #: source/ToolColorNaming.cpp:27 msgid "_Tool specific" msgstr "Específico de la herramien_ta" #: source/Variations.cpp:69 msgid "Lightness (Lab)" msgstr "Luminosidad (Lab)" #: source/Variations.cpp:110 msgid "variations" msgstr "variaciones" #: source/Variations.cpp:225 #, fuzzy msgid "all colors" msgstr "Mezclar colores" #: source/Variations.cpp:239 #, c-format msgid "result %d line %d" msgstr "" #: source/Variations.cpp:717 #: source/transformation/ColorVisionDeficiency.cpp:386 msgid "Strength:" msgstr "Intensidad:" #: source/Variations.cpp:745 source/uiDialogVariations.cpp:142 msgid "Variations" msgstr "Variaciones" #: source/uiAbout.cpp:88 msgid "About Gpick" msgstr "Acerca de Gpick" #: source/uiAbout.cpp:121 msgid "Advanced color picker" msgstr "Selector de color avanzado" #: source/uiAbout.cpp:126 msgid "Copyrights © 2009-2013, Albertas Vyšniauskas and Gpick development team" msgstr "" "Copyrights © 2009-2013, Albertas Vyšniauskas y el equipo de desarrollo de " "Gpick" #: source/uiAbout.cpp:141 msgid "License" msgstr "Licencia" #: source/uiAbout.cpp:142 msgid "Credits" msgstr "Créditos" #: source/uiAbout.cpp:143 msgid "Expat License" msgstr "Licencia Expat" #: source/uiAbout.cpp:144 msgid "Lua License" msgstr "Licencia Lua" #: source/uiApp.cpp:354 msgid "New palette" msgstr "Nueva paleta" #: source/uiApp.cpp:360 msgid "(Imported)" msgstr "(Importado)" #: source/uiApp.cpp:530 source/uiApp.cpp:545 source/uiApp.cpp:563 #: source/uiApp.cpp:641 msgid "File could not be opened" msgstr "El archivo no pudo ser abierto" #: source/uiApp.cpp:531 source/uiApp.cpp:546 source/uiApp.cpp:564 #: source/uiApp.cpp:642 msgid "Open" msgstr "Abrir" #: source/uiApp.cpp:576 source/uiExport.cpp:473 source/uiExport.cpp:587 msgid "Gpick Palette (*.gpa)" msgstr "Paleta de Gpick (*.gpa)" #: source/uiApp.cpp:577 source/uiExport.cpp:474 source/uiExport.cpp:588 msgid "GIMP/Inkscape Palette (*.gpl)" msgstr "Paleta de GIMP/Inkscape (*.gpl)" #: source/uiApp.cpp:578 source/uiExport.cpp:476 source/uiExport.cpp:589 msgid "Adobe Swatch Exchange (*.ase)" msgstr "Adobe Swatch Exchange (*.ase)" #: source/uiApp.cpp:584 source/uiExport.cpp:598 #: source/tools/PaletteFromImage.cpp:548 msgid "All files" msgstr "Todos los archivos" #: source/uiApp.cpp:589 source/uiExport.cpp:607 msgid "All supported formats" msgstr "Todos los formatos soportados" #: source/uiApp.cpp:610 msgid "Open File" msgstr "Abrir archivo" #: source/uiApp.cpp:659 source/uiApp.cpp:691 msgid "Save As" msgstr "Guardar como" #: source/uiApp.cpp:712 msgid "Save" msgstr "Guardar" #: source/uiApp.cpp:771 msgid "Open Last File" msgstr "Abrir el último archivo" #: source/uiApp.cpp:916 msgid "Recent _files" msgstr "Archivos _Recientes" #: source/uiApp.cpp:946 msgid "Ex_port..." msgstr "E_xportar..." #: source/uiApp.cpp:954 msgid "Expo_rt Selected..." msgstr "Ex_portar Seleccionados..." #: source/uiApp.cpp:962 msgid "_Import..." msgstr "_Importar..." #: source/uiApp.cpp:977 msgid "_File" msgstr "_Archivo" #: source/uiApp.cpp:985 msgid "Edit _Converters..." msgstr "Editar _Convertidores..." #: source/uiApp.cpp:989 msgid "Display _Filters..." msgstr "Mostrar _Filtros" #: source/uiApp.cpp:1001 msgid "_Edit" msgstr "_Editar" #: source/uiApp.cpp:1037 msgid "_Secondary View" msgstr "Vista _Secundaria" #: source/uiApp.cpp:1043 msgid "Palette" msgstr "Paleta" #: source/uiApp.cpp:1049 msgid "_View" msgstr "_Vista" #: source/uiApp.cpp:1055 msgid "Palette From _Image..." msgstr "Paleta desde _Imagen..." #: source/uiApp.cpp:1063 msgid "_Tools" msgstr "_Herramientas" #: source/uiApp.cpp:1078 msgid "_Help" msgstr "A_yuda" #: source/uiApp.cpp:1386 msgid "_Copy to Clipboard" msgstr "_Copiar al Portapapeles" #: source/uiApp.cpp:1402 msgid "_Mix Colors..." msgstr "_Mezclar Colores..." #: source/uiApp.cpp:1407 msgid "_Variations..." msgstr "_Variaciones..." #: source/uiApp.cpp:1412 msgid "_Generate..." msgstr "_Generar..." #: source/uiApp.cpp:1421 msgid "C_lear names" msgstr "_Limpiar nombres" #: source/uiApp.cpp:1427 msgid "Autona_me" msgstr "No_mbre automático" #: source/uiApp.cpp:1433 msgid "Auto_number..." msgstr "_Numerado automático" #: source/uiApp.cpp:1441 msgid "R_everse" msgstr "_Reverso" #: source/uiApp.cpp:1447 msgid "Group and _sort..." msgstr "Agrupar y ordenar" #: source/uiApp.cpp:1455 msgid "_Remove" msgstr "_Quitar" #: source/uiApp.cpp:1461 msgid "Remove _All" msgstr "Quitar _Todo" #: source/uiApp.cpp:1869 msgid "Color pic_ker" msgstr "Selector de _Color" #: source/uiApp.cpp:1878 msgid "Scheme _generation" msgstr "_Generación de armonías" #: source/uiApp.cpp:1897 msgid "Lay_out preview" msgstr "Vista previa de diseñ_o" #: source/uiApp.cpp:1947 msgid "Pick colors (Ctrl+P)" msgstr "Elegir color (CTRL+P)" #: source/uiApp.cpp:1956 msgid "" "File is currently in a non-native format, possible loss of precision and/or " "metadata." msgstr "" "El archivo está actualmente en un formato no-nativo, posible pérdida de " "precisión y/o metadatos." #: source/uiColorInput.cpp:45 msgid "Edit color" msgstr "Editar color" #: source/uiColorInput.cpp:69 msgid "Color:" msgstr "Color:" #: source/uiConverter.cpp:56 msgid "Test color" msgstr "Probar color" #: source/uiConverter.cpp:74 msgid "error" msgstr "error" #: source/uiConverter.cpp:145 msgid "Function name" msgstr "Nombre de la función" #: source/uiConverter.cpp:154 msgid "Example" msgstr "Ejemplo" #: source/uiConverter.cpp:196 msgid "Converters" msgstr "Convertidores" #: source/uiConverter.cpp:224 msgid "Displays:" msgstr "Visualizaciones:" #: source/uiConverter.cpp:230 msgid "Color list:" msgstr "Lista de colores:" #: source/uiDialogAutonumber.cpp:108 msgid "Autonumber colors" msgstr "Autonumerar colores" #: source/uiDialogAutonumber.cpp:122 msgid "Name:" msgstr "Nombre:" #: source/uiDialogAutonumber.cpp:132 msgid "Decimal places:" msgstr "Lugares decimales:" #: source/uiDialogAutonumber.cpp:139 msgid "Starting number:" msgstr "Número inicial:" #: source/uiDialogAutonumber.cpp:146 msgid "_Decreasing" msgstr "_Decreciente" #: source/uiDialogAutonumber.cpp:152 msgid "_Append" msgstr "_Agregar" #: source/uiDialogAutonumber.cpp:158 msgid "Sample:" msgstr "Muestra:" #: source/uiDialogGenerate.cpp:216 msgid "Generate colors" msgstr "Generar colores" #: source/uiDialogGenerate.cpp:230 source/tools/PaletteFromImage.cpp:599 msgid "Colors:" msgstr "Colores:" #: source/uiDialogGenerate.cpp:257 msgid "Chaos:" msgstr "Caos:" #: source/uiDialogGenerate.cpp:263 msgid "Seed:" msgstr "Semilla:" #: source/uiDialogGenerate.cpp:271 msgid "_Reverse" msgstr "_Reverso" #: source/uiDialogMix.cpp:76 source/uiDialogMix.cpp:78 msgid "mix node" msgstr "nodo de mezcla" #: source/uiDialogMix.cpp:81 msgid "mix" msgstr "mezcla" #: source/uiDialogMix.cpp:235 msgid "Mix colors" msgstr "Mezclar colores" #: source/uiDialogMix.cpp:262 source/uiDialogVariations.cpp:186 msgid "Steps:" msgstr "Pasos:" #: source/uiDialogMix.cpp:270 msgid "_Include Endpoints" msgstr "_incluir extremos" #: source/uiDialogOptions.cpp:117 source/tools/PaletteFromImage.cpp:589 msgid "Options" msgstr "Opciones" #: source/uiDialogOptions.cpp:134 msgid "System" msgstr "Sistema" #: source/uiDialogOptions.cpp:143 msgid "_Single instance" msgstr "In_stancia única" #: source/uiDialogOptions.cpp:148 msgid "Save/_Restore palette" msgstr "Guardar/_Reestablecer paleta" #: source/uiDialogOptions.cpp:154 msgid "System tray" msgstr "Bandeja de sistema" #: source/uiDialogOptions.cpp:162 msgid "_Minimize to system tray" msgstr "_Minimizar a la bandeja de sistema" #: source/uiDialogOptions.cpp:167 msgid "_Close to system tray" msgstr "_Cerrar a la bandeja de sistema" #: source/uiDialogOptions.cpp:172 msgid "_Start in system tray" msgstr "Iniciar en la bandeja de _sistema" #: source/uiDialogOptions.cpp:178 msgid "_Main" msgstr "_Principal" #: source/uiDialogOptions.cpp:184 msgid "Display" msgstr "Visualización" #: source/uiDialogOptions.cpp:193 msgid "_Refresh rate:" msgstr "Tasa de _refresco:" #: source/uiDialogOptions.cpp:201 msgid "_Magnified area size:" msgstr "Tamaño del área _magnificada:" #: source/uiDialogOptions.cpp:207 msgid "Floating picker click behaviour" msgstr "Comportamiento del selector flotante" #: source/uiDialogOptions.cpp:226 msgid "'Spacebar' button behaviour" msgstr "Comportamiento de la barra espaciadora" #: source/uiDialogOptions.cpp:244 msgid "_Rotate swatch" msgstr "_Rotar muestras" #: source/uiDialogOptions.cpp:251 msgid "Enabled color spaces" msgstr "Espacios de color habilitados" #: source/uiDialogOptions.cpp:266 msgid "Lab settings" msgstr "Ajustes Lab" #: source/uiDialogOptions.cpp:278 msgid "_Illuminant:" msgstr "_Iluminante" #: source/uiDialogOptions.cpp:302 msgid "_Observer:" msgstr "_Observador" #: source/uiDialogOptions.cpp:321 msgid "Other settings" msgstr "Otros ajustes" #: source/uiDialogOptions.cpp:330 msgid "_Mask out of gamut colors" msgstr "En_mascarar colores fuera de gamut" #: source/uiDialogOptions.cpp:336 msgid "_Picker" msgstr "_Selector" #: source/uiDialogOptions.cpp:341 msgid "Color name generation" msgstr "Generación de nombres de color" #: source/uiDialogOptions.cpp:350 msgid "_Imprecision postfix" msgstr "Sufijo de _impresición" #: source/uiDialogOptions.cpp:356 msgid "Tool color naming" msgstr "Asignación de nombres de color" #: source/uiDialogOptions.cpp:381 msgid "_Color names" msgstr "Nombre del _color" #: source/uiDialogSort.cpp:135 source/uiDialogSort.cpp:223 msgid "RGB Red" msgstr "Rojo RGB" #: source/uiDialogSort.cpp:136 source/uiDialogSort.cpp:224 msgid "RGB Green" msgstr "Verde RGB" #: source/uiDialogSort.cpp:137 source/uiDialogSort.cpp:225 msgid "RGB Blue" msgstr "Azul RGB" #: source/uiDialogSort.cpp:138 source/uiDialogSort.cpp:226 msgid "RGB Grayscale" msgstr "Escala de grises RGB" #: source/uiDialogSort.cpp:139 source/uiDialogSort.cpp:227 msgid "HSL Hue" msgstr "Matiz HSL" #: source/uiDialogSort.cpp:140 source/uiDialogSort.cpp:228 msgid "HSL Saturation" msgstr "Saturación HSL" #: source/uiDialogSort.cpp:141 source/uiDialogSort.cpp:229 msgid "HSL Lightness" msgstr "Luminosidad HSL" #: source/uiDialogSort.cpp:142 source/uiDialogSort.cpp:230 msgid "Lab Lightness" msgstr "Luminosidad Lab" #: source/uiDialogSort.cpp:143 source/uiDialogSort.cpp:231 msgid "Lab A" msgstr "Lab A" #: source/uiDialogSort.cpp:144 source/uiDialogSort.cpp:232 msgid "Lab B" msgstr "Lab B" #: source/uiDialogSort.cpp:145 source/uiDialogSort.cpp:233 msgid "LCh Lightness" msgstr "Luminosidad LCh" #: source/uiDialogSort.cpp:146 source/uiDialogSort.cpp:234 msgid "LCh Chroma" msgstr "Crominancia LCh" #: source/uiDialogSort.cpp:147 source/uiDialogSort.cpp:235 msgid "LCh Hue" msgstr "Matiz LCh" #: source/uiDialogSort.cpp:556 msgid "Group and sort" msgstr "Agrupar y ordenar" #: source/uiDialogSort.cpp:564 msgid "Group type:" msgstr "Tipo de grupo:" #: source/uiDialogSort.cpp:574 msgid "Grouping sensitivity:" msgstr "Sensibilidad de agrupamiento:" #: source/uiDialogSort.cpp:581 msgid "Maximum number of groups:" msgstr "Número máximo de grupos:" #: source/uiDialogSort.cpp:588 msgid "Sort type:" msgstr "Tipo de ordenamiento:" #: source/uiDialogSort.cpp:598 msgid "_Reverse group order" msgstr "Orden de grupo inve_rso" #: source/uiDialogSort.cpp:604 msgid "_Reverse order inside groups" msgstr "Orden de grupo inve_rso dentro de grupos" #: source/uiDialogVariations.cpp:60 msgid "variation" msgstr "variación" #: source/uiDialogVariations.cpp:194 msgid "_Use multiplication" msgstr "_Usar multiplicación" #: source/uiExport.cpp:475 msgid "Alias/WaveFront Material (*.mtl)" msgstr "Material de Alias/WaveFront (*.mtl)" #: source/uiExport.cpp:477 msgid "Text file (*.txt)" msgstr "Archivo de texto (*.txt)" #: source/uiExport.cpp:522 msgid "File could not be exported" msgstr "El archivo no pudo ser exportado" #: source/uiExport.cpp:573 source/uiExport.cpp:654 source/uiExport.cpp:666 msgid "Import" msgstr "Importar" #: source/uiExport.cpp:653 msgid "File format is not supported" msgstr "El formato de archivo no está soportado" #: source/uiExport.cpp:665 msgid "File could not be imported" msgstr "El archivo no pudo ser importado" #: source/uiListPalette.cpp:158 source/uiListPalette.cpp:160 #, c-format msgid "%d color" msgid_plural "%d colors" msgstr[0] "%d color" msgstr[1] "%d colores" #: source/uiListPalette.cpp:166 msgid "selected" msgstr "seleccionado" #: source/uiListPalette.cpp:172 source/uiListPalette.cpp:174 #, c-format msgid "Total %d color" msgid_plural "Total %d colors" msgstr[0] "Total %d color" msgstr[1] "Total %d colores" #: source/uiListPalette.cpp:353 msgid "Preview" msgstr "Vista previa" #: source/uiListPalette.cpp:708 source/uiListPalette.cpp:717 msgid "Color" msgstr "Color" #: source/uiListPalette.cpp:726 source/uiTransformations.cpp:183 msgid "Name" msgstr "Nombre" #: source/uiStatusIcon.cpp:67 msgid "_Show Main Window" msgstr "Mo_strar Ventana Principal" #: source/uiStatusIcon.cpp:74 msgid "_Quit" msgstr "Salir" #: source/uiTransformations.cpp:245 msgid "Display filters" msgstr "Filtros de visualización" #: source/uiTransformations.cpp:259 msgid "_Enabled" msgstr "_Activado" #: source/tools/PaletteFromImage.cpp:514 msgid "Palette from image" msgstr "Paleta desde imagen" #: source/tools/PaletteFromImage.cpp:527 msgid "Image" msgstr "Imagen" #: source/tools/PaletteFromImage.cpp:536 msgid "Image file" msgstr "Archivo de imagen" #: source/tools/PaletteFromImage.cpp:556 msgid "All images" msgstr "Todas las imágenes" #: source/transformation/ColorVisionDeficiency.cpp:41 msgid "Color vision deficiency" msgstr "Visión de color deficiente" #: source/transformation/ColorVisionDeficiency.cpp:330 msgid "Protanomaly" msgstr "Protanomalía" #: source/transformation/ColorVisionDeficiency.cpp:331 msgid "Deuteranomaly" msgstr "Deuteranomalía" #: source/transformation/ColorVisionDeficiency.cpp:332 msgid "Tritanomaly" msgstr "Tritanomalía" #: source/transformation/ColorVisionDeficiency.cpp:333 msgid "Protanopia" msgstr "Protanopía" #: source/transformation/ColorVisionDeficiency.cpp:334 msgid "Deuteranopia" msgstr "Deuteranopía" #: source/transformation/ColorVisionDeficiency.cpp:335 msgid "Tritanopia" msgstr "Tritanopía" #: source/transformation/ColorVisionDeficiency.cpp:422 msgid "Altered spectral sensitivity of red receptors" msgstr "Sensibilidad espectral alterada en receptores de rojos" #: source/transformation/ColorVisionDeficiency.cpp:423 msgid "Altered spectral sensitivity of green receptors" msgstr "Sensibilidad espectral alterada en receptores de verdes" #: source/transformation/ColorVisionDeficiency.cpp:424 msgid "Altered spectral sensitivity of blue receptors" msgstr "Sensibilidad espectral alterada en receptores de azules" #: source/transformation/ColorVisionDeficiency.cpp:425 msgid "Absence of red receptors" msgstr "Ausencia de receptores de rojo" #: source/transformation/ColorVisionDeficiency.cpp:426 msgid "Absence of green receptors" msgstr "Ausencia de receptores de verde" #: source/transformation/ColorVisionDeficiency.cpp:427 msgid "Absence of blue receptors" msgstr "Ausencia de receptores de azul" #: source/transformation/GammaModification.cpp:38 msgid "Gamma modification" msgstr "Modificación de gamma" #: source/transformation/GammaModification.cpp:88 #: source/transformation/Quantization.cpp:96 msgid "Value:" msgstr "Valor:" #: source/transformation/Quantization.cpp:40 msgid "Quantization" msgstr "Cuantización" #: source/transformation/Quantization.cpp:101 msgid "Clip top-end" msgstr "Recortar límite superior" #: share/gpick/init.lua:173 msgid "Web: hex code" msgstr "" #: share/gpick/init.lua:178 msgid "Web: hex code (3 digits)" msgstr "" #: share/gpick/init.lua:183 msgid "Web: hex code (no hash symbol)" msgstr "" #: share/gpick/init.lua:188 msgid "CSS: hue saturation lightness" msgstr "" #: share/gpick/init.lua:193 msgid "CSS: red green blue" msgstr "" #: share/gpick/layouts.lua:15 msgid "Homepage" msgstr "" #: share/gpick/layouts.lua:15 #, fuzzy msgid "About us" msgstr "Acerca de Gpick" #: share/gpick/layouts.lua:15 msgid "Links to us" msgstr "" #: share/gpick/layouts.lua:15 msgid "Privacy" msgstr "" #: share/gpick/layouts.lua:15 msgid "Terms" msgstr "" #: share/gpick/layouts.lua:15 #, fuzzy msgid "Contact us" msgstr "Contraste:" #: share/gpick/layouts.lua:15 msgid "RSS" msgstr "" #: share/gpick/layouts.lua:30 msgid "The quick brown fox jumps over the lazy dog" msgstr "" #: share/gpick/layouts.lua:46 msgid "Webpage" msgstr "" #: share/gpick/layouts.lua:51 share/gpick/layouts.lua:73 msgid "Header" msgstr "" #: share/gpick/layouts.lua:52 msgid "Header text" msgstr "" #: share/gpick/layouts.lua:54 #, fuzzy msgid "Content" msgstr "Contraste:" #: share/gpick/layouts.lua:55 msgid "Content text" msgstr "" #: share/gpick/layouts.lua:57 msgid "Sidebar" msgstr "" #: share/gpick/layouts.lua:59 share/gpick/layouts.lua:87 msgid "Button" msgstr "" #: share/gpick/layouts.lua:60 share/gpick/layouts.lua:88 msgid "Button (hover)" msgstr "" #: share/gpick/layouts.lua:61 share/gpick/layouts.lua:89 msgid "Button text" msgstr "" #: share/gpick/layouts.lua:62 share/gpick/layouts.lua:90 msgid "Button text (hover)" msgstr "" #: share/gpick/layouts.lua:64 msgid "Footer" msgstr "" #: share/gpick/layouts.lua:82 share/gpick/layouts.lua:86 msgid "Menu" msgstr "" #: share/gpick/layouts.lua:106 #, fuzzy msgid "Brightness-Darkness" msgstr "Brillo - Oscuridad" #: share/gpick/layouts.lua:110 msgid "main" msgstr "" #: share/gpick/layouts.lua:144 msgid "Grid (4x3)" msgstr "" #: share/gpick/layouts.lua:153 share/gpick/layouts.lua:159 #: share/gpick/layouts.lua:180 share/gpick/layouts.lua:186 msgid "Item" msgstr "" #: share/gpick/layouts.lua:154 share/gpick/layouts.lua:181 msgid "Item text" msgstr "" #: share/gpick/layouts.lua:171 msgid "Grid (5x4)" msgstr "" #~ msgid "Edit _Transformations..." #~ msgstr "Editar _Transformaciones..." gpick-gpick-0.2.6/share/locale/lt/000077500000000000000000000000001377073231300166755ustar00rootroot00000000000000gpick-gpick-0.2.6/share/locale/lt/LC_MESSAGES/000077500000000000000000000000001377073231300204625ustar00rootroot00000000000000gpick-gpick-0.2.6/share/locale/lt/LC_MESSAGES/gpick.po000066400000000000000000000443221377073231300221240ustar00rootroot00000000000000# msgid "" msgstr "" "Project-Id-Version: gpick 0.2.6\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-09-07 19:53+0300\n" "PO-Revision-Date: 2017-09-07 19:54+0300\n" "Last-Translator: Albertas Vyšniauskas \n" "Language-Team: \n" "Language: lt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.0.3\n" "X-Poedit-SourceCharset: UTF-8\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #, c-format msgid "%d color" msgid_plural "%d colors" msgstr[0] "%d spalva" msgstr[1] "%d spalvos" msgstr[2] "%d spalvų" msgid "'Spacebar' button behaviour" msgstr "'Tarpo' mygtuko elgsena" msgid "(Imported)" msgstr "(Importuotas)" msgid "A_dd all to palette" msgstr "Į_kelti visas į paletę" msgid "About Gpick" msgstr "Apie Gpick" msgid "About us" msgstr "Apie mus" msgid "Absence of blue receptors" msgstr "Mėlynų receptorių nebūvimas" msgid "Absence of green receptors" msgstr "Žalių receptorių nebūvimas" msgid "Absence of red receptors" msgstr "Raudonų receptorių nebūvimas" msgid "Active filters" msgstr "Aktyvūs filtrai" msgid "Add" msgstr "Sudėtis" msgid "Add color dictionary file" msgstr "Pridėti spalvų žodyną" msgid "Adobe Swatch Exchange (*.ase)" msgstr "Adobe Swatch Exchange (*.ase)" msgid "Advanced color picker" msgstr "Pažangi spalvų rinkyklė" msgid "Alias/WaveFront Material (*.mtl)" msgstr "Alias/WaveFront Material (*.mtl)" msgid "All files" msgstr "Visi failai" msgid "All images" msgstr "Visi paveikslėliai" msgid "All supported formats" msgstr "Visi palaikomi formatai" msgid "Altered spectral sensitivity of blue receptors" msgstr "Pakitęs mėlynų receptorių spektro jautrumas" msgid "Altered spectral sensitivity of green receptors" msgstr "Pakitęs žalių receptorių spektro jautrumas" msgid "Altered spectral sensitivity of red receptors" msgstr "Pakitęs raudonų receptorių spektro jautrumas" msgid "Analogous" msgstr "Analogiška" msgid "Assign CSS selectors" msgstr "Priskirti CSS selektorius" msgid "Auto_number..." msgstr "Auto. _numeracija..." msgid "Autona_me" msgstr "Auto. pavadinimai" msgid "Autonumber colors" msgstr "Sunumeruoti spalvas" msgid "Available filters" msgstr "Galimi filtrai" msgid "Background color" msgstr "Fono spalva" msgid "Background:" msgstr "Fonas:" msgid "Big" msgstr "Didelis" msgid "Black" msgstr "Juoda" msgid "Blend colors" msgstr "Sulieti spalvas" msgid "Blue" msgstr "Mėlyna" msgid "Brightness" msgstr "Šviesumas" msgid "Brightness Darkness" msgstr "Šviesumas, tamsumas" msgid "Brightness-Darkness" msgstr "Šviesumas-Tamsumas" msgid "Built in" msgstr "Integruotas" msgid "Button" msgstr "Mygtukas" msgid "Button (hover)" msgstr "Mygtukas (pažymėtas)" msgid "Button text" msgstr "Mygtuko tekstas" msgid "Button text (hover)" msgstr "Mygtuko tekstas (pažymėtas)" msgid "C style multi-line comments" msgstr "C stiliaus kelių eilučių komentarai" msgid "C style single-line comments" msgstr "C stiliaus vienos eilutės komentarai" msgid "CSS selector" msgstr "CSS selectorius" msgid "CSS: hue saturation lightness" msgstr "CSS: atspalvis įsotinimas šviesumas" msgid "CSS: red green blue" msgstr "CSS: raudona žalia mėlyna" msgid "C_lear names" msgstr "I_švalyti pavadinimus" msgid "Cascading Style Sheet (*.css)" msgstr "Cascading Style Sheets (*.css)" msgid "Cascading Style Sheets *.css" msgstr "Cascading Style Sheets *.css" msgid "Chaos:" msgstr "Chaosas:" msgid "Clash" msgstr "Nedarna" msgid "Click on swatch area to begin adding colors to palette" msgstr "Paspauskite mėginio plote norėdami pradėti spalvų rinkimą į paletę" msgid "Clip top-end" msgstr "Apkirpti viršutinę dalį" msgid "Closest colors" msgstr "Artimiausios spalvos" msgid "Color" msgstr "Spalva" msgid "Color Space _Sampler..." msgstr "Spalvų Erdvės _Rinkyklė..." msgid "Color _Dictionaries..." msgstr "_Spalvų Žodynai..." msgid "Color dictionaries" msgstr "_Spalvų žodynai" msgid "Color dictionary file" msgstr "Spalvų žodynas" msgid "Color list:" msgstr "Spalvų sąrašas::" msgid "Color mixer" msgstr "Spalvų maišyklė" msgid "Color name generation" msgstr "Spalvų pavadinimų generavimas" msgid "Color name:" msgstr "Spalvos pavadinimas:" msgid "Color pic_ker" msgstr "Spalvų rin_kyklė" msgid "Color picker" msgstr "Spalvų rinkyklė" msgid "Color space sampler" msgstr "Spalvų erdvės rinkyklė" msgid "Color space:" msgstr "Spalvų erdvė:" msgid "Color vision deficiency" msgstr "Spalvų matymo defektai" msgid "Color wheel:" msgstr "Spalvų ratas:" msgid "Color:" msgstr "Spalva:" msgid "Colors:" msgstr "Spalvos:" msgid "Complementary" msgstr "Papildanti" msgid "Contact us" msgstr "Kontaktai" msgid "Content" msgstr "Turinys" msgid "Content text" msgstr "Turinio tekstas" msgid "Contrast:" msgstr "Kontrastas:" msgid "Converter:" msgstr "Keitėjas:" msgid "Converters" msgstr "Keitėjai" msgid "Cop_y" msgstr "_Kopijuoti" msgid "Copy" msgstr "Kopijavimas" msgid "Copyright © 2009-2016, Albertas Vyšniauskas and Gpick development team" msgstr "Autorinės teisės priklauso © 2009-2016, Albertui Vyšniauskui ir Gpick kūrimo komandai" msgid "Credits" msgstr "Padėkos" msgid "Cubic" msgstr "Kubinis" msgid "Cyan" msgstr "Žydra" msgid "Darkness" msgstr "Tamsumas" msgid "Decimal places:" msgstr "Skaitmenys:" msgid "Default drag action" msgstr "Numatytas pertempimo veiksmas" msgid "Deuteranomaly" msgstr "Deuteranomalija" msgid "Deuteranopia" msgstr "Deuteranopija" msgid "Difference" msgstr "Skirtumas" msgid "Display" msgstr "Rodymas" msgid "Display _Filters..." msgstr "Rodymo _Filtrai..." msgid "Display filters" msgstr "Rodymo filtrai" msgid "Displays:" msgstr "Rodymas:" msgid "Edit" msgstr "Keisti" msgid "Edit _Converters..." msgstr "Keisti _keitėjus..." msgid "Edit color" msgstr "Keisti spalvą" msgid "Enable" msgstr "Įjungti" msgid "Enabled color spaces" msgstr "Aktyvios spalvų erdvės" msgid "End steps:" msgstr "Pabaigos žingsniai:" msgid "End:" msgstr "Pabaiga:" msgid "Ex_port..." msgstr "Eksportuoti..." msgid "Example" msgstr "Pavyzdys" msgid "Expat License" msgstr "Expat licencija" msgid "Expo_rt Selected..." msgstr "Eksportuoti _pažymėtas..." msgid "Exponential" msgstr "Eksponentinis" msgid "Export" msgstr "Eksportuoti" msgid "Export CSS File" msgstr "Eksportuoti CSS failą" msgid "Export CSS file" msgstr "Eksportuoti CSS failą" msgid "Falloff:" msgstr "Nuožulnumas:" msgid "File could not be exported" msgstr "Nepavyko eksportuoti failą" msgid "File could not be imported" msgstr "Nepavyko importuoti failą" msgid "File could not be opened" msgstr "Nepavyko atidaryti failo" msgid "File could not be saved" msgstr "Nepavyko išsaugoti failą" msgid "File format is not supported" msgstr "Failo formatas nėra palaikomas" msgid "File is currently in a non-native format, possible loss of precision and/or metadata." msgstr "Šiuo metu failas išsaugotas ne pagrindiniu formatu, galimas tikslumo ir/ar metaduomenų praradimas." msgid "First color" msgstr "Pirma spalva" msgid "Five-Tone" msgstr "Penki tonai" msgid "Floating picker click behaviour" msgstr "Slankaus rinkėjo elgsena" msgid "Footer" msgstr "Paraštė" msgid "Full hex" msgstr "Pilnas šešioliktainis" msgid "Function name" msgstr "Funkcijos pavadinimas" msgid "GIMP/Inkscape Palette (*.gpl)" msgstr "GIMP/Inkscape paletė (*.gpl)" msgid "Gamma modification" msgstr "Gamos pakeitimas" msgid "Generate colors" msgstr "Generuoti spalvas" msgid "Gpick Palette (*.gpa)" msgstr "Gpick paletė (*.gpa)" msgid "Gray" msgstr "Pilka" msgid "Green" msgstr "Žalia" msgid "Grid (4x3)" msgstr "Tinklas (4x3)" msgid "Grid (5x4)" msgstr "Tinklas (5x4)" msgid "Group and _sort..." msgstr "_Grupavimas ir rūšiavimas..." msgid "Group and sort" msgstr "Grupuoti ir rūšiuoti" msgid "Group type:" msgstr "Grupavimo tipas:" msgid "Grouping sensitivity:" msgstr "Grupavimo jautrumas:" msgid "HSL" msgstr "HSL" msgid "HSL Hue" msgstr "HSL Atspalvis" msgid "HSL Lightness" msgstr "HSL Šviesumas" msgid "HSL Saturation" msgstr "HSL Įsotinimas" msgid "HSV" msgstr "HSV" msgid "Hash single-line comments" msgstr "Grotelių simbolio vienos eilutės komentarai" msgid "Header" msgstr "Antraštė" msgid "Header text" msgstr "Antraštės tekstas" msgid "Hex format" msgstr "Šešioliktainis formatas" msgid "Homepage" msgstr "Namų puslapis" msgid "Hue" msgstr "Atspalvis" msgid "Hue:" msgstr "Atspalvis:" msgid "Hyper Text Markup Language (*.html, *.htm)" msgstr "Hyper Text Markup Language (*.html, *.htm)" msgid "Image" msgstr "Paveikslėlis" msgid "Image file" msgstr "Paveikslėlio failas" msgid "Import" msgstr "Importuoti" msgid "Import _Text File..." msgstr "Importuoti _Tekstinį Failą..." msgid "Import text file" msgstr "Eksportuoti teksto failą" msgid "Include color names" msgstr "Pridėti spalvų pavadinimus" msgid "Info" msgstr "Informacija" msgid "Integer values" msgstr "Sveikieji skaičiai" msgid "Item" msgstr "Lauk." msgid "Item size" msgstr "Elemento dydis" msgid "Item size:" msgstr "Elemento dydis:" msgid "Item text" msgstr "Laukelio tekstas" msgid "Key" msgstr "Juoda" msgid "LAB" msgstr "LAB" msgid "LCH" msgstr "LCH" msgid "LCh Chroma" msgstr "LCh Chroma" msgid "LCh Hue" msgstr "LCh Atspalvis" msgid "LCh Lightness" msgstr "LCh Šviesumas" msgid "Lab A" msgstr "Lab A" msgid "Lab B" msgstr "Lab B" msgid "Lab Lightness" msgstr "Lab Šviesumas" msgid "Lab settings" msgstr "Lab nustatymai" msgid "Last color" msgstr "Paskutinė spalva" msgid "Lay_out preview" msgstr "Maket_o peržiūra" msgid "Layout preview" msgstr "Išdėstymo peržiūra" msgid "Layout:" msgstr "Išdėstymas:" msgid "License" msgstr "Licencija" msgid "Lightness" msgstr "Šviesumas" msgid "Lightness (Lab)" msgstr "Šviesumas (Lab)" msgid "Lightness:" msgstr "Šviesumas:" msgid "Linear" msgstr "Tiesinis" msgid "Links to us" msgstr "Nuorodos" msgid "Lower case" msgstr "Apatinis registras" msgid "Lua License" msgstr "Lua licencija" msgid "M_ove" msgstr "_Perkelti" msgid "Magenta" msgstr "Purpurinė" msgid "Maximal value" msgstr "Maksimali reikšmė" msgid "Maximum number of groups:" msgstr "Maksimalus grupių skaičius:" msgid "Medium" msgstr "Vidutinis" msgid "Menu" msgstr "Meniu" msgid "Middle:" msgstr "Vidurys:" msgid "Minimal value" msgstr "Minimali reikšmė" msgid "Mix colors" msgstr "Maišyti spalvas" msgid "Multiply" msgstr "Daugyba" msgid "Name" msgstr "Pavadinimas" msgid "Name:" msgstr "Pavadinimas:" msgid "Neutral" msgstr "Neutralus" msgid "New palette" msgstr "Nauja paletė" msgid "No filter selected" msgstr "Filtras neparinktas" msgid "None" msgstr "Joks" msgid "Normal" msgstr "Paprastas" msgid "Opacity:" msgstr "Nepermatomumas:" msgid "Open" msgstr "Atidaryti" msgid "Open File" msgstr "Atidaryti failą" msgid "Open Last File" msgstr "Atidaryti vėliausią failą" msgid "Options" msgstr "Nustatymai" msgid "Other settings" msgstr "Kiti nustatymai" msgid "Oversample:" msgstr "Mėginio vidurkis" msgid "Palette" msgstr "Paletė" msgid "Palette From _Image..." msgstr "Paletė iš paveikslėlio..." msgid "Palette from image" msgstr "Paletė iš paveikslėlio" msgid "Paste" msgstr "Įdėjimas" msgid "Path" msgstr "Kelias" msgid "Pick color" msgstr "Rinkti spalvą" msgid "Pick colors (Ctrl+P)" msgstr "Rinkti spalvas (Vald+P)" msgid "Press Spacebar to sample color under mouse pointer" msgstr "Paspauskite Tarpą norėdami gauti spalvą esančią po pelės kursoriu" msgid "Preview" msgstr "Peržiūra" msgid "Privacy" msgstr "Privatumas" msgid "Protanomaly" msgstr "Protanomalija" msgid "Protanopia" msgstr "Protanopija" msgid "Quadratic" msgstr "Kvardatinis" msgid "Quantization" msgstr "Kvantavimas" msgid "RGB" msgstr "RGB" msgid "RGB Blue" msgstr "RGB Mėlyna" msgid "RGB Grayscale" msgstr "RGB Pustonis" msgid "RGB Green" msgstr "RGB Žalia" msgid "RGB Red" msgstr "RGB Raudona" msgid "RSS" msgstr "RSS" msgid "RYB v1" msgstr "RYB v1" msgid "RYB v2" msgstr "RYB v2" msgid "R_everse" msgstr "_Atvirkščiai" msgid "Real values" msgstr "Realūs skaičiai" msgid "Recent _Files" msgstr "Paskutiniai _Failai" msgid "Rectangle (tetradic)" msgstr "Keturkampis (tetrada)" msgid "Red" msgstr "Raudona" msgid "Remove _All" msgstr "Pašalinti _visas" msgid "Rotation:" msgstr "Pasukimas:" msgid "Sample" msgstr "Pavyzdys" msgid "Sample count" msgstr "Mėginių kiekis" msgid "Sample:" msgstr "Pavyzdys:" msgid "Saturation" msgstr "Įsotinimas" msgid "Saturation:" msgstr "Įsotinimas:" msgid "Save" msgstr "Išsaugoti" msgid "Save As" msgstr "Išsaugoti kaip" msgid "Save/_Restore palette" msgstr "Išsaugoti/_Atstatyti paletę" msgid "Scheme _generation" msgstr "Schemos _generavimas" msgid "Scheme generation" msgstr "Schemos generavimas" msgid "Seed:" msgstr "Sėkla:" msgid "Settings" msgstr "Nustatymai" msgid "Short hex" msgstr "Trumpas šešioliktainis" msgid "Sidebar" msgstr "Šonas" msgid "Six-Tone" msgstr "Šeši tonai" msgid "Small" msgstr "Mažas" msgid "Sort type:" msgstr "Rūšiavimo tipas:" msgid "Split-Complementary" msgstr "Perskirtas papildantis" msgid "Square" msgstr "Kvadratas" msgid "Start steps:" msgstr "Pradiniai žingsniai:" msgid "Start:" msgstr "Pradžia:" msgid "Starting number:" msgstr "Pradėti nuo:" msgid "Static" msgstr "Pastovus" msgid "Steps:" msgstr "Žingsniai:" msgid "Strength:" msgstr "Stiprumas:" msgid "Style item" msgstr "Stiliaus objektas" msgid "System" msgstr "Sistema" msgid "System tray" msgstr "Sisteminis dėklas" msgid "Terms" msgstr "Sąlygos" msgid "Test color" msgstr "Testavimo spalva" msgid "Text File (*.txt)" msgstr "Tekstinis failas (*.txt)" msgid "Text file (*.txt)" msgstr "Tekstinis failas (*.txt)" msgid "The quick brown fox jumps over the lazy dog" msgstr "Greita ruda lapė šoka per tingų šunį" msgid "Tool color naming" msgstr "Įrankių spalvų pavadinimai" #, c-format msgid "Total %d color" msgid_plural "Total %d colors" msgstr[0] "Viso %d spalva" msgstr[1] "Viso %d spalvos" msgstr[2] "Viso %d spalvų" msgid "Triadic" msgstr "Triada" msgid "Tritanomaly" msgstr "Tritanomalija" msgid "Tritanopia" msgstr "Tritanopija" msgid "Type:" msgstr "Tipas:" msgid "Upper case" msgstr "Viršutinis registras" msgid "User controllable" msgstr "Varotojo valdomas" msgid "Value" msgstr "Reikšmė" msgid "Value:" msgstr "Reikšmė:" msgid "Variations" msgstr "Pokyčiai" msgid "Web: hex code" msgstr "Tinklas: šešioliktainis kodas" msgid "Web: hex code (3 digits)" msgstr "Tinklas: šešioliktainis kodas (3 skaitmenys)" msgid "Web: hex code (no hash symbol)" msgstr "Tinklas: šešioliktainis kodas (be grotelių simbolio)" msgid "Webpage" msgstr "Puslapis" msgid "White" msgstr "Balta" msgid "X axis" msgstr "X ašis" msgid "Y axis" msgstr "Y ašis" msgid "Yellow" msgstr "Geltona" msgid "Z axis" msgstr "Z ašis" msgid "Zoom:" msgstr "Priartinimas:" msgid "_Add to palette" msgstr "_Įkelti į paletę" msgid "_Append" msgstr "_Pridėti" msgid "_Assign CSS Selectors..." msgstr "_Priskirti CSS selektorius..." msgid "_Automatic name" msgstr "_Automatinis pavadinimas" msgid "_Close to system tray" msgstr "_Uždaryti į sisteminį dėklą" msgid "_Color names" msgstr "_Spalvų pavadinimai" msgid "_Copy to clipboard" msgstr "_Kopijuoti" msgid "_Decreasing" msgstr "Mažėjantis" msgid "_Edit" msgstr "_Keisti" msgid "_Edit..." msgstr "_Keisti..." msgid "_Empty" msgstr "_Tuščia" msgid "_Enable display filters" msgstr "_Įjungti rodymo filtrus" msgid "_Export CSS File As..." msgstr "_Eksportuoti CSS failą kaip..." msgid "_File" msgstr "_Failas" msgid "_Generate..." msgstr "_Generuoti..." msgid "_Help" msgstr "_Pagalba" msgid "_Illuminant:" msgstr "_Apšvietimas:" msgid "_Import..." msgstr "_Importuoti..." msgid "_Imprecision postfix" msgstr "_Netikslumo ženklas" msgid "_Include Endpoints" msgstr "Įtraukti _galinius taškus" msgid "_Linearization" msgstr "_Tiesinimas" msgid "_Linked" msgstr "_Sujungti" msgid "_Magnified area size:" msgstr "_Padidinto ploto dydis:" msgid "_Main" msgstr "_Pagrindiniai" msgid "_Mask out of gamut colors" msgstr "Maskuoti spalvas esančias už gamos ribų" msgid "_Minimize to system tray" msgstr "_Nuleisti į sisteminį dėklą" msgid "_Mix Colors..." msgstr "_Maišyti spalvas..." msgid "_Nearest from palette" msgstr "_Artimiausios iš paletės" msgid "_Observer:" msgstr "_Stebėtojas:" msgid "_Paste" msgstr "_Įdėti" msgid "_Picker" msgstr "_Rinkėjas" msgid "_Quit" msgstr "_Išeiti" msgid "_Refresh rate:" msgstr "_Atnaujinimo dažnis:" msgid "_Remove" msgstr "_Pašalinti" msgid "_Reset" msgstr "_Atstatyti" msgid "_Reset scheme" msgstr "_Atstatyti schemą" msgid "_Reverse" msgstr "_Atvirkščiai" msgid "_Reverse group order" msgstr "_Atvirkščia grupių tvarka" msgid "_Reverse order inside groups" msgstr "_Atvirkščia tvarka grupėse" msgid "_Rotate swatch" msgstr "_Pasukti mėginį" msgid "_Secondary View" msgstr "_Antrinis vaizdas" msgid "_Show Main Window" msgstr "_Rodyti pagrindinį langą" msgid "_Single instance" msgstr "_Vienas egzempliorius" msgid "_Start in system tray" msgstr "_Paleisti sisteminiame dėkle" msgid "_Tool specific" msgstr "_Priklausomai nuo įrankio" msgid "_Tools" msgstr "_Įrankiai" msgid "_Use multiplication" msgstr "_Naudoti daugybą" msgid "_Variations..." msgstr "_Pokyčiai..." msgid "_View" msgstr "_Rodymas" msgid "all colors" msgstr "visos spalvos" msgid "blend" msgstr "suliejimas" msgid "blend node" msgstr "suliejimo mazgas" msgid "brightness darkness" msgstr "šviesumas tamsumas" msgid "closest color" msgstr "artimiausia spalva" msgid "color mixer" msgstr "spalvų maišyklė" msgid "color space" msgstr "spalvų erdvė" msgid "error" msgstr "klaida" msgid "layout preview" msgstr "išdėstymo peržiūra" msgid "main" msgstr "pagrindinis" #, c-format msgid "match %d" msgstr "atitikmuo %d" msgid "mix" msgstr "maišymas" msgid "mix node" msgstr "maišymo mazgas" #, c-format msgid "primary %d" msgstr "pirminė %d" #, c-format msgid "result %d" msgstr "rezultatas %d" #, c-format msgid "result %d line %d" msgstr "rezultatas %d eilutėje %d" msgid "rgb.txt File (rgb.txt)" msgstr "rgb.txt failas (*.txt)" msgid "scheme" msgstr "schema" msgid "secondary" msgstr "antrinė" msgid "selected" msgstr "pasirinkta" msgid "target" msgstr "taikinys" msgid "variation" msgstr "pokyčiai" msgid "variations" msgstr "pokyčiai" gpick-gpick-0.2.6/share/locale/ru/000077500000000000000000000000001377073231300167045ustar00rootroot00000000000000gpick-gpick-0.2.6/share/locale/ru/LC_MESSAGES/000077500000000000000000000000001377073231300204715ustar00rootroot00000000000000gpick-gpick-0.2.6/share/locale/ru/LC_MESSAGES/gpick.po000066400000000000000000001206471377073231300221400ustar00rootroot00000000000000# Translation of Gpick into Russian # Александр Прокудин , 2011-2017 # Alexandre Prokoudine , 2017-2020. # msgid "" msgstr "" "Project-Id-Version: gpick 0.2.6\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-01-01 01:53+0300\n" "PO-Revision-Date: 2020-01-01 02:07+0300\n" "Last-Translator: Alexandre Prokoudine \n" "Language-Team: русский \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" "X-Poedit-Language: Russian\n" "X-Poedit-Country: RUSSIAN FEDERATION\n" "X-Generator: Gtranslator 3.33.90\n" #: source/BlendColors.cpp:114 source/BlendColors.cpp:116 msgid "blend node" msgstr "основной" #: source/BlendColors.cpp:119 msgid "blend" msgstr "переход" #: source/BlendColors.cpp:262 source/BrightnessDarkness.cpp:234 #: source/ClosestColors.cpp:165 source/ColorMixer.cpp:289 #: source/ColorPicker.cpp:321 source/GenerateScheme.cpp:428 #: source/LayoutPreview.cpp:374 source/Variations.cpp:311 #: source/uiDialogOptions.cpp:281 source/uiDialogOptions.cpp:304 msgid "_Add to palette" msgstr "_Добавить в палитру" #: source/BlendColors.cpp:266 source/BrightnessDarkness.cpp:238 #: source/ClosestColors.cpp:169 source/ColorMixer.cpp:294 #: source/ColorPicker.cpp:325 source/GenerateScheme.cpp:433 #: source/LayoutPreview.cpp:379 source/Variations.cpp:316 msgid "A_dd all to palette" msgstr "Доб_авить все в палитру" #: source/BlendColors.cpp:316 source/GenerateScheme.cpp:462 msgid "_Reset" msgstr "С_бросить" #: source/BlendColors.cpp:438 msgid "Start:" msgstr "Начало:" #: source/BlendColors.cpp:451 msgid "Middle:" msgstr "Середина:" #: source/BlendColors.cpp:465 msgid "End:" msgstr "Конец:" #: source/BlendColors.cpp:479 source/GenerateScheme.cpp:809 #: source/uiDialogGenerate.cpp:217 source/uiDialogMix.cpp:272 #: source/transformation/ColorVisionDeficiency.cpp:363 msgid "Type:" msgstr "Тип:" #: source/BlendColors.cpp:481 source/ColorWheelType.cpp:56 #: source/uiDialogMix.cpp:274 source/tools/ColorSpaceSampler.cpp:236 msgid "RGB" msgstr "RGB" #: source/BlendColors.cpp:482 source/uiDialogMix.cpp:275 #: source/tools/ColorSpaceSampler.cpp:237 msgid "HSV" msgstr "HSV" #: source/BlendColors.cpp:483 source/uiDialogMix.cpp:276 #: source/tools/ColorSpaceSampler.cpp:239 msgid "LAB" msgstr "LAB" #: source/BlendColors.cpp:484 source/uiDialogMix.cpp:277 #: source/tools/ColorSpaceSampler.cpp:240 msgid "LCH" msgstr "LCH" #: source/BlendColors.cpp:490 msgid "Start steps:" msgstr "Шагов в начале:" #: source/BlendColors.cpp:497 msgid "End steps:" msgstr "Шагов в конце:" #: source/BlendColors.cpp:523 msgid "Blend colors" msgstr "Переход между цветами" #: source/BrightnessDarkness.cpp:81 msgid "brightness darkness" msgstr "Яркость-Темнота" #: source/BrightnessDarkness.cpp:252 source/ClosestColors.cpp:182 #: source/ColorMixer.cpp:335 source/ColorPicker.cpp:335 #: source/GenerateScheme.cpp:446 source/LayoutPreview.cpp:394 #: source/Variations.cpp:357 source/uiApp.cpp:1318 msgid "_Edit..." msgstr "_Изменить…" #: source/BrightnessDarkness.cpp:256 source/ClosestColors.cpp:186 #: source/ColorMixer.cpp:340 source/ColorPicker.cpp:339 #: source/GenerateScheme.cpp:451 source/LayoutPreview.cpp:399 #: source/Variations.cpp:362 source/uiApp.cpp:1323 msgid "_Paste" msgstr "_Вставить" #: source/BrightnessDarkness.cpp:319 msgid "Brightness" msgstr "Яркость" #: source/BrightnessDarkness.cpp:319 msgid "Darkness" msgstr "Темнота" #: source/BrightnessDarkness.cpp:357 msgid "Brightness Darkness" msgstr "Яркость-Темнота" #: source/ClosestColors.cpp:68 msgid "closest color" msgstr "ближайший цвет" #: source/ClosestColors.cpp:116 msgid "target" msgstr "" #: source/ClosestColors.cpp:119 msgid "match {}" msgstr "совпадение {}" #: source/ClosestColors.cpp:400 msgid "Closest colors" msgstr "Ближайшие цвета" #: source/ColorMixer.cpp:66 msgid "Normal" msgstr "Нормальный" #: source/ColorMixer.cpp:67 msgid "Multiply" msgstr "Умножение" #: source/ColorMixer.cpp:68 msgid "Add" msgstr "Добавление" #: source/ColorMixer.cpp:69 msgid "Difference" msgstr "Разница" #: source/ColorMixer.cpp:70 source/ColorPicker.cpp:1066 #: source/ColorPicker.cpp:1080 source/ColorSpaceType.cpp:34 #: source/ColorSpaceType.cpp:41 source/Variations.cpp:66 #: source/uiColorInput.cpp:155 source/uiColorInput.cpp:157 msgid "Hue" msgstr "Тон" #: source/ColorMixer.cpp:71 source/ColorPicker.cpp:1066 #: source/ColorPicker.cpp:1080 source/ColorSpaceType.cpp:35 #: source/ColorSpaceType.cpp:42 source/Variations.cpp:67 #: source/uiColorInput.cpp:155 source/uiColorInput.cpp:157 msgid "Saturation" msgstr "Насыщенность" #: source/ColorMixer.cpp:72 source/ColorPicker.cpp:1080 #: source/ColorPicker.cpp:1122 source/ColorPicker.cpp:1136 #: source/ColorSpaceType.cpp:43 source/ColorSpaceType.cpp:63 #: source/ColorSpaceType.cpp:70 source/Variations.cpp:68 #: source/uiColorInput.cpp:157 source/uiColorInput.cpp:163 #: source/uiColorInput.cpp:165 msgid "Lightness" msgstr "Светлота" #: source/ColorMixer.cpp:110 msgid "color mixer" msgstr "Микшер цветов" #: source/ColorMixer.cpp:210 msgid "secondary" msgstr "первичный" #: source/ColorMixer.cpp:213 source/Variations.cpp:219 msgid "primary {}" msgstr "первичный {}" #: source/ColorMixer.cpp:215 msgid "result {}" msgstr "результат {}" #: source/ColorMixer.cpp:632 msgid "Opacity:" msgstr "Непрозрачность:" #: source/ColorMixer.cpp:655 msgid "Color mixer" msgstr "Микшер цветов" #: source/ColorPicker.cpp:365 msgid "Press Spacebar to sample color under mouse pointer" msgstr "Нажмите пробел для добавления цвета под указателем" #: source/ColorPicker.cpp:621 source/uiConverter.cpp:133 msgid "Copy" msgstr "Копирование" #: source/ColorPicker.cpp:625 msgid "Paste" msgstr "Вставка" #: source/ColorPicker.cpp:631 source/uiColorInput.cpp:216 msgid "Edit" msgstr "Изменить" #: source/ColorPicker.cpp:687 source/uiApp.cpp:1006 source/uiDialogSort.cpp:223 #: source/uiImportExport.cpp:92 msgid "None" msgstr "Нет" #: source/ColorPicker.cpp:688 msgid "Linear" msgstr "Линейное" #: source/ColorPicker.cpp:689 msgid "Quadratic" msgstr "Квадратичное" #: source/ColorPicker.cpp:690 msgid "Cubic" msgstr "Кубическое" #: source/ColorPicker.cpp:691 msgid "Exponential" msgstr "Экспоненциальное" #: source/ColorPicker.cpp:833 msgid "Click on swatch area to begin adding colors to palette" msgstr "Щёлкните по области с образцами, чтобы добавить цвет в палитру" #: source/ColorPicker.cpp:948 msgid "Pick color" msgstr "Снять цвет" #: source/ColorPicker.cpp:1029 msgid "Settings" msgstr "Параметры" #: source/ColorPicker.cpp:1039 msgid "Oversample:" msgstr "Оверсэмплинг:" #: source/ColorPicker.cpp:1046 msgid "Falloff:" msgstr "Спадание:" #: source/ColorPicker.cpp:1053 msgid "Zoom:" msgstr "Масштаб:" #: source/ColorPicker.cpp:1066 source/ColorSpaceType.cpp:36 #: source/uiColorInput.cpp:155 msgid "Value" msgstr "Значение" #: source/ColorPicker.cpp:1094 source/ColorSpaceType.cpp:48 #: source/uiColorInput.cpp:159 msgid "Red" msgstr "Красный" #: source/ColorPicker.cpp:1094 source/ColorSpaceType.cpp:49 #: source/uiColorInput.cpp:159 msgid "Green" msgstr "Зелёный" #: source/ColorPicker.cpp:1094 source/ColorSpaceType.cpp:50 #: source/uiColorInput.cpp:159 msgid "Blue" msgstr "Синий" #: source/ColorPicker.cpp:1108 source/ColorSpaceType.cpp:55 #: source/uiColorInput.cpp:161 msgid "Cyan" msgstr "Cyan" #: source/ColorPicker.cpp:1108 source/ColorSpaceType.cpp:56 #: source/uiColorInput.cpp:161 msgid "Magenta" msgstr "Magenta" #: source/ColorPicker.cpp:1108 source/ColorSpaceType.cpp:57 #: source/uiColorInput.cpp:161 msgid "Yellow" msgstr "Yellow" #: source/ColorPicker.cpp:1108 source/ColorSpaceType.cpp:58 #: source/uiColorInput.cpp:161 msgid "Key" msgstr "Key" #: source/ColorPicker.cpp:1144 msgid "Info" msgstr "Информация" #: source/ColorPicker.cpp:1153 msgid "Color name:" msgstr "Название цвета:" #: source/ColorPicker.cpp:1166 msgid "Contrast:" msgstr "Контраст:" #: source/ColorPicker.cpp:1171 source/ColorPicker.cpp:1177 msgid "Sample" msgstr "Образец" #: source/ColorPicker.cpp:1204 msgid "Color picker" msgstr "Пипетка" #: source/ColorWheelType.cpp:57 msgid "RYB v1" msgstr "RYB v1" #: source/ColorWheelType.cpp:58 msgid "RYB v2" msgstr "RYB v2" #: source/GenerateScheme.cpp:94 msgid "Complementary" msgstr "Противоположные" #: source/GenerateScheme.cpp:95 msgid "Analogous" msgstr "Аналоговая" #: source/GenerateScheme.cpp:96 msgid "Triadic" msgstr "Триады" #: source/GenerateScheme.cpp:97 msgid "Split-Complementary" msgstr "Разделённые противоположные" #: source/GenerateScheme.cpp:98 msgid "Rectangle (tetradic)" msgstr "Прямоугольник (тетрады)" #: source/GenerateScheme.cpp:99 msgid "Square" msgstr "Квадрат" #: source/GenerateScheme.cpp:100 msgid "Neutral" msgstr "Нейтральная" #: source/GenerateScheme.cpp:101 msgid "Clash" msgstr "Конфликт" #: source/GenerateScheme.cpp:102 msgid "Five-Tone" msgstr "Пять тонов" #: source/GenerateScheme.cpp:103 msgid "Six-Tone" msgstr "Шесть тонов" #: source/GenerateScheme.cpp:125 source/uiDialogGenerate.cpp:82 msgid "scheme" msgstr "Схема" #: source/GenerateScheme.cpp:276 msgid "_Linked" msgstr "_Связано" #: source/GenerateScheme.cpp:283 msgid "_Reset scheme" msgstr "_Сбросить изменения" #: source/GenerateScheme.cpp:785 msgid "Hue:" msgstr "Тон:" #: source/GenerateScheme.cpp:792 source/uiDialogVariations.cpp:167 msgid "Saturation:" msgstr "Насыщенность:" #: source/GenerateScheme.cpp:800 source/uiDialogVariations.cpp:153 msgid "Lightness:" msgstr "Светлота:" #: source/GenerateScheme.cpp:819 source/uiDialogGenerate.cpp:227 msgid "Color wheel:" msgstr "Цветовой круг:" #: source/GenerateScheme.cpp:848 msgid "Scheme generation" msgstr "Создание цветовой схемы" #: source/ImportExport.cpp:455 msgid "Item size" msgstr "Размер объектов" #: source/ImportExport.cpp:458 msgid "Background color" msgstr "Цвет фона" #: source/LayoutPreview.cpp:75 msgid "layout preview" msgstr "Просмотр макета" #: source/LayoutPreview.cpp:140 msgid "Style item" msgstr "Объект стиля" #: source/LayoutPreview.cpp:149 msgid "CSS selector" msgstr "Селектор CSS" #: source/LayoutPreview.cpp:166 msgid "Assign CSS selectors" msgstr "Назначить селекторы CSS" #: source/LayoutPreview.cpp:479 source/LayoutPreview.cpp:527 #: source/uiApp.cpp:526 source/uiApp.cpp:545 msgid "File could not be saved" msgstr "Не удалось сохранить файл" #: source/LayoutPreview.cpp:490 source/uiImportExport.cpp:460 #: source/uiImportExport.cpp:517 msgid "Export" msgstr "Экспортировать" #: source/LayoutPreview.cpp:504 msgid "Cascading Style Sheets *.css" msgstr "Каскадные таблицы стилей (*.css)" #: source/LayoutPreview.cpp:586 msgid "Layout:" msgstr "Макет:" #: source/LayoutPreview.cpp:590 msgid "Export CSS File" msgstr "Экспортировать файл CSS" #: source/LayoutPreview.cpp:591 msgid "Export CSS file" msgstr "Экспортировать файл CSS" #: source/LayoutPreview.cpp:597 msgid "_Export CSS File As..." msgstr "_Экспортировать файл CSS как…" #: source/LayoutPreview.cpp:600 msgid "_Assign CSS Selectors..." msgstr "_Назначить селекторы CSS…" #: source/LayoutPreview.cpp:651 msgid "Layout preview" msgstr "Просмотр макета" #: source/StandardMenu.cpp:28 source/uiDialogOptions.cpp:285 #: source/uiDialogOptions.cpp:308 msgid "_Copy to clipboard" msgstr "С_копировать в буфер обмена" #: source/StandardMenu.cpp:32 msgid "_Nearest from palette" msgstr "_Ближайший из палитры" #: source/ToolColorNaming.cpp:29 msgid "_Empty" msgstr "_Без названия" #: source/ToolColorNaming.cpp:30 msgid "_Automatic name" msgstr "_Автоматическое именование" #: source/ToolColorNaming.cpp:31 msgid "_Tool specific" msgstr "_В зависимости от инструмента" #: source/Variations.cpp:69 msgid "Lightness (Lab)" msgstr "Светлота (Lab)" #: source/Variations.cpp:108 msgid "variations" msgstr "Вариации" #: source/Variations.cpp:216 msgid "all colors" msgstr "все цвета" #: source/Variations.cpp:225 msgid "result {} line {}" msgstr "результат {} строка {}" #: source/Variations.cpp:672 #: source/transformation/ColorVisionDeficiency.cpp:386 msgid "Strength:" msgstr "Сила:" #: source/Variations.cpp:695 source/uiDialogVariations.cpp:146 msgid "Variations" msgstr "Вариации светлоты и насыщенности" #: source/uiAbout.cpp:80 msgid "About Gpick" msgstr "О программе Gpick" #: source/uiAbout.cpp:95 msgid "Revision" msgstr "Редакция" #: source/uiAbout.cpp:102 msgid "Copyright © 2009-2018, Albertas Vyšniauskas and Gpick development team" msgstr "" "Авторские права © 2009-2020, Albertas Vyšniauskas и команда разработчиков " "Gpick" #: source/uiAbout.cpp:114 msgid "License" msgstr "Лицензия" #: source/uiAbout.cpp:115 msgid "Credits" msgstr "Авторы" #: source/uiAbout.cpp:116 msgid "Expat License" msgstr "Лицензия на Expat" #: source/uiAbout.cpp:117 msgid "Lua License" msgstr "Лицензия на Lua" #: source/uiApp.cpp:216 msgid "New palette" msgstr "Новая палитра" #: source/uiApp.cpp:222 msgid "(Imported)" msgstr "(импортировано)" #: source/uiApp.cpp:378 source/uiApp.cpp:391 source/uiApp.cpp:407 #: source/uiApp.cpp:486 msgid "File could not be opened" msgstr "Не удалось открыть файл" #: source/uiApp.cpp:379 source/uiApp.cpp:392 source/uiApp.cpp:408 #: source/uiApp.cpp:487 msgid "Open" msgstr "Открыть" #: source/uiApp.cpp:421 source/uiImportExport.cpp:319 #: source/uiImportExport.cpp:468 msgid "Gpick Palette (*.gpa)" msgstr "Палитры Gpick (*.gpa)" #: source/uiApp.cpp:422 source/uiImportExport.cpp:320 #: source/uiImportExport.cpp:469 msgid "GIMP/Inkscape Palette (*.gpl)" msgstr "Палитры GIMP/Inkscape (*.gpl)" #: source/uiApp.cpp:423 source/uiImportExport.cpp:321 #: source/uiImportExport.cpp:471 msgid "Adobe Swatch Exchange (*.ase)" msgstr "Палитры Adobe Swatch Exchange (*.ase)" #: source/uiApp.cpp:428 source/uiImportExport.cpp:330 #: source/tools/PaletteFromImage.cpp:531 msgid "All files" msgstr "Все файлы" #: source/uiApp.cpp:436 source/uiImportExport.cpp:338 msgid "All supported formats" msgstr "Все поддерживаемые форматы" #: source/uiApp.cpp:461 msgid "Open File" msgstr "Открыть файл" #: source/uiApp.cpp:500 source/uiApp.cpp:527 msgid "Save As" msgstr "Сохранить как" #: source/uiApp.cpp:546 msgid "Save" msgstr "Сохранить" #: source/uiApp.cpp:604 msgid "Open Last File" msgstr "Открыть последний файл" #: source/uiApp.cpp:848 msgid "Primary" msgstr "Первичный" #: source/uiApp.cpp:849 source/uiApp.cpp:1037 msgid "Palette" msgstr "Палитра цветов" #: source/uiApp.cpp:850 msgid "Secondary" msgstr "Вторичный" #: source/uiApp.cpp:911 msgid "Recent _Files" msgstr "_Недавние файлы" #: source/uiApp.cpp:935 msgid "Ex_port..." msgstr "_Экспортировать…" #: source/uiApp.cpp:940 msgid "Expo_rt Selected..." msgstr "Экспортировать _выделенное…" #: source/uiApp.cpp:945 msgid "_Import..." msgstr "_Импортировать…" #: source/uiApp.cpp:950 msgid "Import _Text File..." msgstr "_Импортировать текстовый файл…" #: source/uiApp.cpp:962 msgid "_File" msgstr "_Файл" #: source/uiApp.cpp:968 msgid "Edit _Converters..." msgstr "_Конвертеры…" #: source/uiApp.cpp:971 msgid "Display _Filters..." msgstr "_Экранные фильтры..." #: source/uiApp.cpp:974 msgid "Color _Dictionaries..." msgstr "_Цветовые словари…" #: source/uiApp.cpp:983 msgid "_Edit" msgstr "_Правка" #: source/uiApp.cpp:999 msgid "_Layout" msgstr "_Макет" #: source/uiApp.cpp:1028 msgid "_Secondary View" msgstr "_Дополнительная панель" #: source/uiApp.cpp:1033 msgid "_Primary View" msgstr "_Первичный вид" #: source/uiApp.cpp:1043 msgid "_View" msgstr "_Вид" #: source/uiApp.cpp:1047 msgid "_Pick colors..." msgstr "С_нимать цвета…" #: source/uiApp.cpp:1052 msgid "Palette From _Image..." msgstr "_Палитра из изображения…" #: source/uiApp.cpp:1055 #, fuzzy msgid "Color Space _Sampler..." msgstr "П_ипетка" #: source/uiApp.cpp:1058 msgid "_Text Parser..." msgstr "Парсер _текста…" #: source/uiApp.cpp:1061 msgid "_Tools" msgstr "_Инструменты" #: source/uiApp.cpp:1071 msgid "_Help" msgstr "_Справка" #: source/uiApp.cpp:1314 msgid "A_dd..." msgstr "_Добавить…" #: source/uiApp.cpp:1329 msgid "_Mix Colors..." msgstr "С_мешать цвета…" #: source/uiApp.cpp:1333 msgid "_Variations..." msgstr "Вариации _светлоты и насыщенности…" #: source/uiApp.cpp:1337 msgid "_Generate..." msgstr "Вариации _тонов…" #: source/uiApp.cpp:1342 msgid "C_lear names" msgstr "Ст_ереть названия" #: source/uiApp.cpp:1347 msgid "Autona_me" msgstr "_Автоматически подобрать названия" #: source/uiApp.cpp:1352 msgid "Auto_number..." msgstr "Автоматически _пронумеровать..." #: source/uiApp.cpp:1358 msgid "R_everse" msgstr "_Развернуть" #: source/uiApp.cpp:1363 msgid "Group and _sort..." msgstr "С_группировать и отсортировать..." #: source/uiApp.cpp:1369 msgid "_Remove" msgstr "_Удалить" #: source/uiApp.cpp:1374 msgid "Remove _All" msgstr "Удалить _все" #: source/uiApp.cpp:1661 msgid "Color pic_ker" msgstr "П_ипетка" #: source/uiApp.cpp:1766 msgid "Scheme _generation" msgstr "Создание _цветовой схемы" #: source/uiApp.cpp:1780 msgid "Lay_out preview" msgstr "Просмотр _макета" #: source/uiApp.cpp:1819 msgid "Pick colors (Ctrl+P)" msgstr "Снять цвет пипеткой (Ctrl+P)" #: source/uiApp.cpp:1826 msgid "" "File is currently in a non-native format, possible loss of precision and/or " "metadata." msgstr "" "Файл сохранён не в собственном формате Gpick, возможны потери точности или " "метаданных." #: source/uiColorDictionaries.cpp:107 msgid "Path" msgstr "Расположение" #: source/uiColorDictionaries.cpp:115 msgid "Enable" msgstr "Включить" #: source/uiColorDictionaries.cpp:220 msgid "Color dictionaries" msgstr "Цветовые словари" #: source/uiColorDictionaries.cpp:242 msgid "Add color dictionary file" msgstr "Добавить файл цветового словаря" #: source/uiColorDictionaries.cpp:246 msgid "Color dictionary file" msgstr "Файл цветового словаря" #: source/uiColorDictionaries.cpp:264 source/uiColorDictionaries.cpp:276 msgid "Built in" msgstr "Встроенный" #: source/uiColorInput.cpp:128 msgid "Add color" msgstr "Добавить цвет" #: source/uiColorInput.cpp:128 msgid "Edit color" msgstr "Изменить цвет" #: source/uiColorInput.cpp:147 msgid "Color:" msgstr "Цвет:" #: source/uiConverter.cpp:58 msgid "Test color" msgstr "Пробный цвет" #: source/uiConverter.cpp:118 msgid "Function name" msgstr "Название функции" #: source/uiConverter.cpp:126 msgid "Example" msgstr "Пример" #: source/uiConverter.cpp:141 msgid "Paste / Edit" msgstr "Вставка / Ред." #: source/uiConverter.cpp:159 msgid "Converters" msgstr "Конвертеры" #: source/uiConverter.cpp:177 msgid "Displays:" msgstr "Показывает:" #: source/uiConverter.cpp:183 msgid "Color list:" msgstr "Список цветов:" #: source/uiDialogAutonumber.cpp:104 msgid "Autonumber colors" msgstr "Автоматически пронумеровать цвета" #: source/uiDialogAutonumber.cpp:119 msgid "Name:" msgstr "Название:" #: source/uiDialogAutonumber.cpp:129 msgid "Decimal places:" msgstr "Число разрядов:" #: source/uiDialogAutonumber.cpp:136 msgid "Starting number:" msgstr "Начать с цифры:" #: source/uiDialogAutonumber.cpp:143 msgid "_Decreasing" msgstr "По _нисходящей" #: source/uiDialogAutonumber.cpp:149 msgid "_Append" msgstr "_Добавлять поверх" #: source/uiDialogAutonumber.cpp:155 msgid "Sample:" msgstr "Образец:" #: source/uiDialogGenerate.cpp:151 source/uiDialogGenerate.cpp:222 msgid "Static" msgstr "" #: source/uiDialogGenerate.cpp:201 msgid "Generate colors" msgstr "Вариации тонов" #: source/uiDialogGenerate.cpp:210 source/tools/PaletteFromImage.cpp:580 msgid "Colors:" msgstr "Цветов:" #: source/uiDialogGenerate.cpp:237 msgid "Chaos:" msgstr "Хаос:" #: source/uiDialogGenerate.cpp:243 msgid "Seed:" msgstr "Зерно:" #: source/uiDialogGenerate.cpp:250 msgid "Rotation:" msgstr "Вращение:" #: source/uiDialogGenerate.cpp:257 msgid "_Reverse" msgstr "_Развернуть" #: source/uiDialogMix.cpp:94 source/uiDialogMix.cpp:96 msgid "mix node" msgstr "" #: source/uiDialogMix.cpp:99 msgid "mix" msgstr "" #: source/uiDialogMix.cpp:258 msgid "Mix colors" msgstr "Смешать цвета" #: source/uiDialogMix.cpp:284 source/uiDialogVariations.cpp:181 msgid "Steps:" msgstr "Шагов:" #: source/uiDialogMix.cpp:292 msgid "_Include Endpoints" msgstr "_Включая оконечные цвета" #: source/uiDialogOptions.cpp:151 source/tools/PaletteFromImage.cpp:572 msgid "Options" msgstr "Параметры" #: source/uiDialogOptions.cpp:159 msgid "System" msgstr "Системные" #: source/uiDialogOptions.cpp:166 msgid "_Single instance" msgstr "_Запускать лишь одну копию приложения" #: source/uiDialogOptions.cpp:170 msgid "Save/_Restore palette" msgstr "Сохранить/_Восстановить палитру" #: source/uiDialogOptions.cpp:174 msgid "System tray" msgstr "Область уведомления" #: source/uiDialogOptions.cpp:181 msgid "_Minimize to system tray" msgstr "С_ворачивать в область уведомления" #: source/uiDialogOptions.cpp:185 msgid "_Close to system tray" msgstr "_Закрывать в область уведомления" #: source/uiDialogOptions.cpp:189 msgid "_Start in system tray" msgstr "З_апускать в области уведомления" #: source/uiDialogOptions.cpp:193 msgid "Default drag action" msgstr "При перетаскивании по умолчанию" #: source/uiDialogOptions.cpp:202 msgid "M_ove" msgstr "Пере_мещать" #: source/uiDialogOptions.cpp:208 msgid "Cop_y" msgstr "_Копировать" #: source/uiDialogOptions.cpp:215 msgid "Hex format" msgstr "HEX-формат" #: source/uiDialogOptions.cpp:224 msgid "Lower case" msgstr "в нижнем регистре" #: source/uiDialogOptions.cpp:230 msgid "Upper case" msgstr "В ВЕРХНЕМ РЕГИСТРЕ" #: source/uiDialogOptions.cpp:236 msgid "_Main" msgstr "О_сновные" #: source/uiDialogOptions.cpp:239 msgid "Display" msgstr "Внешний вид" #: source/uiDialogOptions.cpp:246 msgid "_Refresh rate:" msgstr "_Частота обновления:" #: source/uiDialogOptions.cpp:252 msgid "_Magnified area size:" msgstr "_Размер области увеличения:" #: source/uiDialogOptions.cpp:258 msgid "Picker" msgstr "Пипетка" #: source/uiDialogOptions.cpp:265 msgid "_Always use floating picker" msgstr "_Всегда плавающая" #: source/uiDialogOptions.cpp:269 msgid "_Hide cursor" msgstr "_Скрывать курсор" #: source/uiDialogOptions.cpp:274 msgid "Floating picker click behaviour" msgstr "Действие по щелчку пипеткой" #: source/uiDialogOptions.cpp:289 msgid "A_dd to swatch" msgstr "_Добавить в палитру" #: source/uiDialogOptions.cpp:293 msgid "R_otate swatch" msgstr "По_вернуть образец" #: source/uiDialogOptions.cpp:297 msgid "'Spacebar' button behaviour" msgstr "Действие по нажатию пробела" #: source/uiDialogOptions.cpp:312 msgid "_Rotate swatch" msgstr "По_вернуть образец" #: source/uiDialogOptions.cpp:317 msgid "Enabled color spaces" msgstr "Используемые цветовые пространства" #: source/uiDialogOptions.cpp:330 msgid "Lab settings" msgstr "Параметры Lab" #: source/uiDialogOptions.cpp:340 msgid "_Illuminant:" msgstr "Ос_ветитель:" #: source/uiDialogOptions.cpp:363 msgid "_Observer:" msgstr "_Наблюдатель:" #: source/uiDialogOptions.cpp:380 msgid "Other settings" msgstr "Прочие параметры" #: source/uiDialogOptions.cpp:387 msgid "_Mask out of gamut colors" msgstr "_Маскировать цвета вне охвата" #: source/uiDialogOptions.cpp:391 msgid "_Picker" msgstr "_Пипетка" #: source/uiDialogOptions.cpp:394 msgid "Color name generation" msgstr "Подбор названий" #: source/uiDialogOptions.cpp:401 msgid "_Imprecision postfix" msgstr "Помечать _неточное совпадение тильдой" #: source/uiDialogOptions.cpp:405 msgid "Tool color naming" msgstr "Именование снятых цветов" #: source/uiDialogOptions.cpp:425 msgid "_Color names" msgstr "_Названия цветов" #: source/uiDialogSort.cpp:136 source/uiDialogSort.cpp:224 msgid "RGB Red" msgstr "Красный в RGB" #: source/uiDialogSort.cpp:137 source/uiDialogSort.cpp:225 msgid "RGB Green" msgstr "Зелёный в RGB" #: source/uiDialogSort.cpp:138 source/uiDialogSort.cpp:226 msgid "RGB Blue" msgstr "Синий в RGB" #: source/uiDialogSort.cpp:139 source/uiDialogSort.cpp:227 msgid "RGB Grayscale" msgstr "Градации серого в RGB" #: source/uiDialogSort.cpp:140 source/uiDialogSort.cpp:228 msgid "HSL Hue" msgstr "Тон HSL" #: source/uiDialogSort.cpp:141 source/uiDialogSort.cpp:229 msgid "HSL Saturation" msgstr "Насыщенность в HSL" #: source/uiDialogSort.cpp:142 source/uiDialogSort.cpp:230 msgid "HSL Lightness" msgstr "Светлота в HSL" #: source/uiDialogSort.cpp:143 source/uiDialogSort.cpp:231 msgid "Lab Lightness" msgstr "Светлота в Lab" #: source/uiDialogSort.cpp:144 source/uiDialogSort.cpp:232 msgid "Lab A" msgstr "Lab A" #: source/uiDialogSort.cpp:145 source/uiDialogSort.cpp:233 msgid "Lab B" msgstr "Lab B" #: source/uiDialogSort.cpp:146 source/uiDialogSort.cpp:234 msgid "LCh Lightness" msgstr "Светлота в LCH" #: source/uiDialogSort.cpp:147 source/uiDialogSort.cpp:235 msgid "LCh Chroma" msgstr "Цветность в LCH" #: source/uiDialogSort.cpp:148 source/uiDialogSort.cpp:236 msgid "LCh Hue" msgstr "Тон в LCH" #: source/uiDialogSort.cpp:556 msgid "Group and sort" msgstr "Сгруппировать и отсортировать" #: source/uiDialogSort.cpp:564 msgid "Group type:" msgstr "Критерий группировки:" #: source/uiDialogSort.cpp:574 msgid "Grouping sensitivity:" msgstr "Чувствительность группировки:" #: source/uiDialogSort.cpp:581 msgid "Maximum number of groups:" msgstr "Предельное количество групп:" #: source/uiDialogSort.cpp:588 msgid "Sort type:" msgstr "Критерий сортировки:" #: source/uiDialogSort.cpp:598 msgid "_Reverse group order" msgstr "О_братить порядок группировки" #: source/uiDialogSort.cpp:604 msgid "_Reverse order inside groups" msgstr "Обратить порядок _внутри группы" #: source/uiDialogVariations.cpp:63 msgid "variation" msgstr "Вариации светлоты и насыщенности" #: source/uiDialogVariations.cpp:189 msgid "_Use multiplication" msgstr "_Использовать умножение" #: source/uiDialogVariations.cpp:196 source/tools/ColorSpaceSampler.cpp:246 msgid "_Linearization" msgstr "_Линеаризация" #: source/uiImportExport.cpp:84 msgid "Small" msgstr "Маленькие" #: source/uiImportExport.cpp:85 msgid "Medium" msgstr "Средние" #: source/uiImportExport.cpp:86 msgid "Big" msgstr "Большие" #: source/uiImportExport.cpp:87 source/uiImportExport.cpp:98 msgid "User controllable" msgstr "Определяется пользователем" #: source/uiImportExport.cpp:93 msgid "White" msgstr "Белый" #: source/uiImportExport.cpp:94 msgid "Gray" msgstr "Серый" #: source/uiImportExport.cpp:95 msgid "Black" msgstr "Чёрный" #: source/uiImportExport.cpp:96 msgid "First color" msgstr "Первый в списке" #: source/uiImportExport.cpp:97 msgid "Last color" msgstr "Последний в списке" #: source/uiImportExport.cpp:102 msgid "Include color names" msgstr "Включить названия цветов" #: source/uiImportExport.cpp:107 msgid "Converter:" msgstr "Конвертер:" #: source/uiImportExport.cpp:108 msgid "Item size:" msgstr "Размер объектов:" #: source/uiImportExport.cpp:109 msgid "Background:" msgstr "Цвет фона:" #: source/uiImportExport.cpp:119 source/tools/TextParser.cpp:116 msgid "C style single-line comments" msgstr "Однострочные комментарии в стиле C" #: source/uiImportExport.cpp:120 source/tools/TextParser.cpp:117 msgid "C style multi-line comments" msgstr "Многострочные комментарии в стиле C" #: source/uiImportExport.cpp:121 source/tools/TextParser.cpp:118 msgid "Hash single-line comments" msgstr "Комментарии, начинающиеся решёткой" #: source/uiImportExport.cpp:125 source/tools/TextParser.cpp:122 msgid "Full hex" msgstr "Полный HEX" #: source/uiImportExport.cpp:127 source/tools/TextParser.cpp:124 msgid "Short hex" msgstr "Короткий HEX" #: source/uiImportExport.cpp:128 source/tools/TextParser.cpp:125 msgid "Integer values" msgstr "Целые значения" #: source/uiImportExport.cpp:129 source/tools/TextParser.cpp:126 msgid "Real values" msgstr "Реальные значения" #: source/uiImportExport.cpp:312 source/uiImportExport.cpp:377 #: source/uiImportExport.cpp:391 msgid "Import" msgstr "Импортировать" #: source/uiImportExport.cpp:322 msgid "Text File (*.txt)" msgstr "Текстовый файл (*.txt)" #: source/uiImportExport.cpp:323 msgid "rgb.txt File (rgb.txt)" msgstr "Файл rgb.txt (rgb.txt)" #: source/uiImportExport.cpp:376 msgid "File format is not supported" msgstr "Этот формат файлов не поддерживается" #: source/uiImportExport.cpp:390 source/uiImportExport.cpp:446 msgid "File could not be imported" msgstr "Не удалось импортировать файл" #: source/uiImportExport.cpp:410 source/uiImportExport.cpp:447 msgid "Import text file" msgstr "Импортировать текстовый файл" #: source/uiImportExport.cpp:470 msgid "Alias/WaveFront Material (*.mtl)" msgstr "Материалы Alias/WaveFront (*.mtl)" #: source/uiImportExport.cpp:472 msgid "Cascading Style Sheet (*.css)" msgstr "Каскадная таблица стилей (*.css)" #: source/uiImportExport.cpp:473 msgid "Hyper Text Markup Language (*.html, *.htm)" msgstr "Файл HTML (*.html, *.htm)" #: source/uiImportExport.cpp:474 msgid "Text file (*.txt)" msgstr "Текстовые файлы (*.txt)" #: source/uiImportExport.cpp:516 msgid "File could not be exported" msgstr "Не удалось экспортировать файл" #: source/uiListPalette.cpp:148 msgid "{} color" msgid_plural "{} colors" msgstr[0] "{} цвет" msgstr[1] "{} цвета" msgstr[2] "{} цветов" #: source/uiListPalette.cpp:152 msgid "selected" msgstr "выбрано" #: source/uiListPalette.cpp:155 msgid "Total {} color" msgid_plural "Total {} colors" msgstr[0] "Всего {} цвет" msgstr[1] "Всего {} цвета" msgstr[2] "Всего {} цветов" #: source/uiListPalette.cpp:309 msgid "Preview" msgstr "Предпросмотр" #: source/uiListPalette.cpp:670 source/uiListPalette.cpp:679 msgid "Color" msgstr "Цвет" #: source/uiListPalette.cpp:688 msgid "Name" msgstr "Название" #: source/uiStatusIcon.cpp:56 msgid "_Show Main Window" msgstr "_Показать основное окно" #: source/uiStatusIcon.cpp:60 msgid "_Quit" msgstr "В_ыход" #: source/uiTransformations.cpp:197 msgid "Available filters" msgstr "Доступные фильтры" #: source/uiTransformations.cpp:200 msgid "Active filters" msgstr "Активные фильтры" #: source/uiTransformations.cpp:240 source/uiTransformations.cpp:345 msgid "No filter selected" msgstr "Фильтр не выбран" #: source/uiTransformations.cpp:293 msgid "Display filters" msgstr "Экранные фильтры" #: source/uiTransformations.cpp:303 msgid "_Enable display filters" msgstr "_Включить экранные фильтры" #: source/tools/ColorSpaceSampler.cpp:76 msgid "color space" msgstr "цветовое пространство" #: source/tools/ColorSpaceSampler.cpp:221 #, fuzzy msgid "Color space sampler" msgstr "Пипетка" #: source/tools/ColorSpaceSampler.cpp:234 msgid "Color space:" msgstr "Цыетовое пространство:" #: source/tools/ColorSpaceSampler.cpp:238 msgid "HSL" msgstr "HSL" #: source/tools/ColorSpaceSampler.cpp:252 msgid "Sample count" msgstr "" #: source/tools/ColorSpaceSampler.cpp:253 msgid "Minimal value" msgstr "Мин. значение" #: source/tools/ColorSpaceSampler.cpp:254 msgid "Maximal value" msgstr "Макс. значение" #: source/tools/ColorSpaceSampler.cpp:258 msgid "X axis" msgstr "Ось X" #: source/tools/ColorSpaceSampler.cpp:259 msgid "Y axis" msgstr "Ось Y" #: source/tools/ColorSpaceSampler.cpp:260 msgid "Z axis" msgstr "Ось Z" #: source/tools/PaletteFromImage.cpp:501 msgid "Palette from image" msgstr "Палитра из изображения" #: source/tools/PaletteFromImage.cpp:511 msgid "Image" msgstr "Изображение" #: source/tools/PaletteFromImage.cpp:520 msgid "Image file" msgstr "Файл изображения" #: source/tools/PaletteFromImage.cpp:539 msgid "All images" msgstr "Все изображения" #: source/tools/TextParser.cpp:103 msgid "Text parser" msgstr "Парсер текста" #: source/tools/TextParser.cpp:112 msgid "Text" msgstr "Текст" #: source/transformation/ColorVisionDeficiency.cpp:41 msgid "Color vision deficiency" msgstr "Цветонеразличение" #: source/transformation/ColorVisionDeficiency.cpp:330 msgid "Protanomaly" msgstr "Протаномалия" #: source/transformation/ColorVisionDeficiency.cpp:331 msgid "Deuteranomaly" msgstr "Дейтераномалия" #: source/transformation/ColorVisionDeficiency.cpp:332 msgid "Tritanomaly" msgstr "Тританомалия" #: source/transformation/ColorVisionDeficiency.cpp:333 msgid "Protanopia" msgstr "Протанопия" #: source/transformation/ColorVisionDeficiency.cpp:334 msgid "Deuteranopia" msgstr "Дейтеранопия" #: source/transformation/ColorVisionDeficiency.cpp:335 msgid "Tritanopia" msgstr "Тританопия" #: source/transformation/ColorVisionDeficiency.cpp:422 msgid "Altered spectral sensitivity of red receptors" msgstr "Слабое восприятие красного цвета" #: source/transformation/ColorVisionDeficiency.cpp:423 msgid "Altered spectral sensitivity of green receptors" msgstr "Слабое восприятие зелёного цвета" #: source/transformation/ColorVisionDeficiency.cpp:424 msgid "Altered spectral sensitivity of blue receptors" msgstr "Слабое восприятие синего цвета" #: source/transformation/ColorVisionDeficiency.cpp:425 msgid "Absence of red receptors" msgstr "Отсутствие рецепторов красного цвета" #: source/transformation/ColorVisionDeficiency.cpp:426 msgid "Absence of green receptors" msgstr "Отсутствие рецепторов зелёного цвета" #: source/transformation/ColorVisionDeficiency.cpp:427 msgid "Absence of blue receptors" msgstr "Отсутствие рецепторов синего цвета" #: source/transformation/GammaModification.cpp:38 msgid "Gamma modification" msgstr "Гамма-коррекция" #: source/transformation/GammaModification.cpp:88 #: source/transformation/Quantization.cpp:96 msgid "Value:" msgstr "Значение:" #: source/transformation/Quantization.cpp:40 msgid "Quantization" msgstr "Квантование" #: source/transformation/Quantization.cpp:101 msgid "Clip top-end" msgstr "" #: share/gpick/converters.lua:154 msgid "Web: hex code" msgstr "Web: hex-код" #: share/gpick/converters.lua:155 msgid "Web: hex code (3 digits)" msgstr "Web: hex-код (3 знака)" #: share/gpick/converters.lua:156 msgid "Web: hex code (no hash symbol)" msgstr "Web: hex-код (без решётки)" #: share/gpick/converters.lua:157 msgid "CSS: hue saturation lightness" msgstr "CSS: тон, насыщенность, светлота" #: share/gpick/converters.lua:158 msgid "CSS: red green blue" msgstr "CSS: красный, зелёный, синий" #: share/gpick/layouts.lua:16 msgid "The quick brown fox jumps over the lazy dog" msgstr "" #: share/gpick/layouts.lua:27 msgid "Homepage" msgstr "Homepage" #: share/gpick/layouts.lua:27 msgid "About us" msgstr "About us" #: share/gpick/layouts.lua:27 msgid "Links to us" msgstr "Links to us" #: share/gpick/layouts.lua:27 msgid "Privacy" msgstr "Privacy" #: share/gpick/layouts.lua:27 msgid "Terms" msgstr "Terms" #: share/gpick/layouts.lua:27 msgid "Contact us" msgstr "Contact us" #: share/gpick/layouts.lua:27 msgid "RSS" msgstr "RSS" #: share/gpick/layouts.lua:36 msgid "Brightness-Darkness" msgstr "Brightness-Darkness" #: share/gpick/layouts.lua:38 msgid "main" msgstr "основной" #: share/gpick/layouts.lua:64 msgid "Webpage" msgstr "Webpage" #: share/gpick/layouts.lua:66 share/gpick/layouts.lua:82 msgid "Header" msgstr "Header" #: share/gpick/layouts.lua:67 msgid "Header text" msgstr "Header text" #: share/gpick/layouts.lua:68 msgid "Content" msgstr "Content" #: share/gpick/layouts.lua:69 msgid "Content text" msgstr "Content text" #: share/gpick/layouts.lua:70 msgid "Sidebar" msgstr "Sidebar" #: share/gpick/layouts.lua:71 share/gpick/layouts.lua:90 msgid "Button" msgstr "Button" #: share/gpick/layouts.lua:72 share/gpick/layouts.lua:91 msgid "Button (hover)" msgstr "Button (hover)" #: share/gpick/layouts.lua:73 share/gpick/layouts.lua:92 msgid "Button text" msgstr "Button text" #: share/gpick/layouts.lua:74 share/gpick/layouts.lua:93 msgid "Button text (hover)" msgstr "Button text (hover)" #: share/gpick/layouts.lua:75 msgid "Footer" msgstr "Footer" #: share/gpick/layouts.lua:87 share/gpick/layouts.lua:89 msgid "Menu" msgstr "Menu" #: share/gpick/layouts.lua:102 msgid "Grid (4x3)" msgstr "Сетка (4x3)" #: share/gpick/layouts.lua:108 share/gpick/layouts.lua:113 #: share/gpick/layouts.lua:124 share/gpick/layouts.lua:129 msgid "Item" msgstr "Item" #: share/gpick/layouts.lua:109 share/gpick/layouts.lua:125 msgid "Item text" msgstr "Item text" #: share/gpick/layouts.lua:118 msgid "Grid (5x4)" msgstr "Сетка (5x4)" #~ msgid "Advanced color picker" #~ msgstr "Продвинутая цветовая пипетка" #~ msgid "HSV shortest hue distance" #~ msgstr "HSV, кратчайшее расстояние" #~ msgid "_Locked" #~ msgstr "_Блокировать насыщенность и светлоту" #~ msgid "_Copy to Clipboard" #~ msgstr "С_копировать в буфер обмена" #~ msgid "error" #~ msgstr "Ошибка" #~ msgid "Edit _Transformations..." #~ msgstr "_Коррекция вывода цвета…" gpick-gpick-0.2.6/share/locale/sv/000077500000000000000000000000001377073231300167065ustar00rootroot00000000000000gpick-gpick-0.2.6/share/locale/sv/LC_MESSAGES/000077500000000000000000000000001377073231300204735ustar00rootroot00000000000000gpick-gpick-0.2.6/share/locale/sv/LC_MESSAGES/gpick.po000066400000000000000000000423121377073231300221320ustar00rootroot00000000000000# msgid "" msgstr "" "Project-Id-Version: gpick 0.2.6\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-09-07 19:53+0300\n" "PO-Revision-Date: 2019-01-18 03:20+0100\n" "Last-Translator: Åke Engelbrektson \n" "Language-Team: Svenska Språkfiler \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.0.6\n" "X-Poedit-SourceCharset: UTF-8\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #, c-format msgid "%d color" msgid_plural "%d colors" msgstr[0] "%d färg" msgstr[1] "%d färger" msgid "'Spacebar' button behaviour" msgstr "Mellanslagsbeteende" msgid "(Imported)" msgstr "(Importerat)" msgid "A_dd all to palette" msgstr "L_ägg till alla i paletten" msgid "About Gpick" msgstr "Om Gpick" msgid "About us" msgstr "Om oss" msgid "Absence of blue receptors" msgstr "Avsaknad av blå receptorer" msgid "Absence of green receptors" msgstr "Avsaknad av gröna receptorer" msgid "Absence of red receptors" msgstr "Avsaknad av röda receptorer" msgid "Active filters" msgstr "Aktiva filter" msgid "Add" msgstr "Lägg till" msgid "Add color dictionary file" msgstr "Lägg till färglexikonfil" msgid "Adobe Swatch Exchange (*.ase)" msgstr "Adobe Swatch Exchange (*.ase)" msgid "Advanced color picker" msgstr "Avancerad färgväljare" msgid "Alias/WaveFront Material (*.mtl)" msgstr "Alias/WaveFront Material (*.mtl)" msgid "All files" msgstr "Alla filer" msgid "All images" msgstr "Alla bilder" msgid "All supported formats" msgstr "Alla format som stöds" msgid "Altered spectral sensitivity of blue receptors" msgstr "Förändrad spektral känslighet hos blå receptorer" msgid "Altered spectral sensitivity of green receptors" msgstr "Förändrad spektral känslighet hos gröna receptorer" msgid "Altered spectral sensitivity of red receptors" msgstr "Förändrad spektral känslighet hos röda receptorer" msgid "Analogous" msgstr "Analog" msgid "Assign CSS selectors" msgstr "Tilldela CSS-väljare" msgid "Auto_number..." msgstr "Autonumrera..." msgid "Autona_me" msgstr "Namnge automatiskt" msgid "Autonumber colors" msgstr "Automatisk färgnumrering" msgid "Available filters" msgstr "Tillgängliga filter" msgid "Background color" msgstr "Bakgrundsfärg" msgid "Background:" msgstr "Bakgrund:" msgid "Big" msgstr "Stor" msgid "Black" msgstr "Svart" msgid "Blend colors" msgstr "Blanda färger" msgid "Blue" msgstr "Blå" msgid "Brightness" msgstr "Ljusstyrka" msgid "Brightness Darkness" msgstr "Ljusstyrka mörker" msgid "Brightness-Darkness" msgstr "Ljusstyrka-Mörker" msgid "Built in" msgstr "Inbyggt" msgid "Button" msgstr "Knapp" msgid "Button (hover)" msgstr "Knapp (hovring)" msgid "Button text" msgstr "Knapptext" msgid "Button text (hover)" msgstr "Knapptext (hovring)" msgid "C style multi-line comments" msgstr "C-stil flerraderskommentarer" msgid "C style single-line comments" msgstr "C-stil enkelradskommentarer" msgid "CSS selector" msgstr "CSS-väljare" msgid "CSS: hue saturation lightness" msgstr "CSS: nyans mättnad ljusstyrka" msgid "CSS: red green blue" msgstr "CSS: röd grön blå" msgid "C_lear names" msgstr "_Rensa namn" msgid "Cascading Style Sheet (*.css)" msgstr "Cascading Style Sheet (*.css)" msgid "Cascading Style Sheets *.css" msgstr "Cascading Style Sheets *.css" msgid "Chaos:" msgstr "Kaos:" msgid "Clash" msgstr "Konflikt" msgid "Click on swatch area to begin adding colors to palette" msgstr "Klicka på färgrutan för att börja lägga till färger i paletten" msgid "Clip top-end" msgstr "Clip top-end" msgid "Closest colors" msgstr "Närmaste färg" msgid "Color" msgstr "Färg" msgid "Color Space _Sampler..." msgstr "Färgrymds_sampler..." msgid "Color _Dictionaries..." msgstr "Färg_lexikon..." msgid "Color dictionaries" msgstr "Färglexikon" msgid "Color dictionary file" msgstr "Färglexikonfil" msgid "Color list:" msgstr "Färglista:" msgid "Color mixer" msgstr "Färgblandare" msgid "Color name generation" msgstr "Generering av färgnamn" msgid "Color name:" msgstr "Färgnamn:" msgid "Color pic_ker" msgstr "Färg_väljare" msgid "Color picker" msgstr "Färgväljare" msgid "Color space sampler" msgstr "Färgrymdssampler" msgid "Color space:" msgstr "Färgrymd:" msgid "Color vision deficiency" msgstr "Färgblindhet" msgid "Color wheel:" msgstr "Färghjul:" msgid "Color:" msgstr "Färg:" msgid "Colors:" msgstr "Färger:" msgid "Complementary" msgstr "Kompletterande" msgid "Contact us" msgstr "Kontakta oss" msgid "Content" msgstr "Innehåll" msgid "Content text" msgstr "Innehållstext" msgid "Contrast:" msgstr "Kontrast:" msgid "Converter:" msgstr "Omvandlare:" msgid "Converters" msgstr "Omvandlare" msgid "Cop_y" msgstr "_Kopiera" msgid "Copy" msgstr "Kopiera" msgid "Copyright © 2009-2016, Albertas Vyšniauskas and Gpick development team" msgstr "Copyright © 2009-2016, Albertas Vyšniauskas and Gpick development team" msgid "Credits" msgstr "Tack" msgid "Cubic" msgstr "Kubisk" msgid "Cyan" msgstr "Cyan" msgid "Darkness" msgstr "Mörker" msgid "Decimal places:" msgstr "Decimalplacering:" msgid "Default drag action" msgstr "Standard dragåtgärd" msgid "Deuteranomaly" msgstr "Deuteranomali" msgid "Deuteranopia" msgstr "Deuteranopi" msgid "Difference" msgstr "Differens" msgid "Display" msgstr "Skärm" msgid "Display _Filters..." msgstr "Skärm_filter..." msgid "Display filters" msgstr "Skärmfilter" msgid "Displays:" msgstr "Skärmar:" msgid "Edit" msgstr "Redigera" msgid "Edit _Converters..." msgstr "Redigera _omvandlare..." msgid "Edit color" msgstr "Redigera färg" msgid "Enable" msgstr "Aktivera" msgid "Enabled color spaces" msgstr "Aktiverade färgrymder" msgid "End steps:" msgstr "Slutsteg:" msgid "End:" msgstr "Slut:" msgid "Ex_port..." msgstr "Ex_portera..." msgid "Example" msgstr "Exempel" msgid "Expat License" msgstr "Expat-licens" msgid "Expo_rt Selected..." msgstr "Expo_rtera markerat..." msgid "Exponential" msgstr "Exponentiell" msgid "Export" msgstr "Exportera" msgid "Export CSS File" msgstr "Exportera CSS-fil" msgid "Export CSS file" msgstr "Exportera CSS-fil" msgid "Falloff:" msgstr "Falloff:" msgid "File could not be exported" msgstr "Filen kunde inte exporteras" msgid "File could not be imported" msgstr "Filen kunde inte importeras" msgid "File could not be opened" msgstr "Filen kunde inte öppnas" msgid "File could not be saved" msgstr "Filen kunde inte sparas" msgid "File format is not supported" msgstr "Filformatet stöds inte" msgid "File is currently in a non-native format, possible loss of precision and/or metadata." msgstr "Filen är för närvarande i ett främmande format, eventuell förlust av precision och/eller metadata." msgid "First color" msgstr "Första färg" msgid "Five-Tone" msgstr "Fem-ton" msgid "Floating picker click behaviour" msgstr "Klickbeteende för flytande färgväljare" msgid "Footer" msgstr "Sidfot" msgid "Full hex" msgstr "Full hex" msgid "Function name" msgstr "Funktionsnamn" msgid "GIMP/Inkscape Palette (*.gpl)" msgstr "GIMP/Inkscape Palette (*.gpl)" msgid "Gamma modification" msgstr "Gammamodifiering" msgid "Generate colors" msgstr "Generera färger" msgid "Gpick Palette (*.gpa)" msgstr "Gpick Palette (*.gpa)" msgid "Gray" msgstr "Grå" msgid "Green" msgstr "Grön" msgid "Grid (4x3)" msgstr "Rutnät (4x3)" msgid "Grid (5x4)" msgstr "Rutnät (5x4)" msgid "Group and _sort..." msgstr "Gruppera och _sortera..." msgid "Group and sort" msgstr "Gruppera och sortera" msgid "Group type:" msgstr "Grupptyp:" msgid "Grouping sensitivity:" msgstr "Grupperingskänslighet:" msgid "HSL" msgstr "HSL" msgid "HSL Hue" msgstr "HSL-nyans" msgid "HSL Lightness" msgstr "HSL-ljusstyrka" msgid "HSL Saturation" msgstr "HSL-mättnad" msgid "HSV" msgstr "HSV" msgid "Hash single-line comments" msgstr "Hash-beräkna enkelradskommentarer" msgid "Header" msgstr "Sidhuvud" msgid "Header text" msgstr "Sidhuvudstext" msgid "Hex format" msgstr "Hex-format" msgid "Homepage" msgstr "Hemsida" msgid "Hue" msgstr "Nyans" msgid "Hue:" msgstr "Nyans:" msgid "Hyper Text Markup Language (*.html, *.htm)" msgstr "Hyper Text Markup Language (*.html, *.htm)" msgid "Image" msgstr "Bild" msgid "Image file" msgstr "Bildfil" msgid "Import" msgstr "Importera" msgid "Import _Text File..." msgstr "Importera _textfil..." msgid "Import text file" msgstr "Importera textfil" msgid "Include color names" msgstr "Inkludera färgnamn" msgid "Info" msgstr "Info" msgid "Integer values" msgstr "Heltalsvärden" msgid "Item" msgstr "Objekt" msgid "Item size" msgstr "Objektstorlek" msgid "Item size:" msgstr "Objektstorlek:" msgid "Item text" msgstr "Objekttext" msgid "Key" msgstr "Nyckel" msgid "LAB" msgstr "LAB" msgid "LCH" msgstr "LCH" msgid "LCh Chroma" msgstr "LCh-kroma" msgid "LCh Hue" msgstr "LCh-nyans" msgid "LCh Lightness" msgstr "LCh-ljusstyrka" msgid "Lab A" msgstr "Lab A" msgid "Lab B" msgstr "Lab B" msgid "Lab Lightness" msgstr "Lab ljusstyrka" msgid "Lab settings" msgstr "Lab inställningar" msgid "Last color" msgstr "Senaste färg" msgid "Lay_out preview" msgstr "Lay_outgranskning" msgid "Layout preview" msgstr "Layoutgranskning" msgid "Layout:" msgstr "Layout:" msgid "License" msgstr "Licens" msgid "Lightness" msgstr "Ljusstyrka" msgid "Lightness (Lab)" msgstr "Ljusstyrka (Lab)" msgid "Lightness:" msgstr "Ljusstyrka:" msgid "Linear" msgstr "Linjär" msgid "Links to us" msgstr "Länkar till oss" msgid "Lower case" msgstr "gemener" msgid "Lua License" msgstr "Lua-licens" msgid "M_ove" msgstr "Fl_ytta" msgid "Magenta" msgstr "Magenta" msgid "Maximal value" msgstr "Maxvärde" msgid "Maximum number of groups:" msgstr "Max antal grupper:" msgid "Medium" msgstr "Medel" msgid "Menu" msgstr "Meny" msgid "Middle:" msgstr "Mitten:" msgid "Minimal value" msgstr "Minimivärde" msgid "Mix colors" msgstr "Blanda färger" msgid "Multiply" msgstr "Multiplicera" msgid "Name" msgstr "Namn" msgid "Name:" msgstr "Namn:" msgid "Neutral" msgstr "Neutral" msgid "New palette" msgstr "Ny palett" msgid "No filter selected" msgstr "Inget filter valt" msgid "None" msgstr "Ingen" msgid "Normal" msgstr "Normal" msgid "Opacity:" msgstr "Opacitet:" msgid "Open" msgstr "Öppna" msgid "Open File" msgstr "Öppna fil" msgid "Open Last File" msgstr "Öppna senaste filen" msgid "Options" msgstr "Alternativ" msgid "Other settings" msgstr "Andra inställningar" msgid "Oversample:" msgstr "Översampling:" msgid "Palette" msgstr "Palett" msgid "Palette From _Image..." msgstr "Palett från _bild..." msgid "Palette from image" msgstr "Palett från bild" msgid "Paste" msgstr "Klistra in" msgid "Path" msgstr "Sökväg" msgid "Pick color" msgstr "Välj färg" msgid "Pick colors (Ctrl+P)" msgstr "Välj färger (Ctrl+P)" msgid "Press Spacebar to sample color under mouse pointer" msgstr "Tryck mellanslag för att granska färgen under muspekaren" msgid "Preview" msgstr "Förhandsgranska" msgid "Privacy" msgstr "Integritet" msgid "Protanomaly" msgstr "Protanomali" msgid "Protanopia" msgstr "Protanopi" msgid "Quadratic" msgstr "Kvadratisk" msgid "Quantization" msgstr "Kvantisering" msgid "RGB" msgstr "RGB" msgid "RGB Blue" msgstr "RGB blå" msgid "RGB Grayscale" msgstr "RGB gråskala" msgid "RGB Green" msgstr "RGB grön" msgid "RGB Red" msgstr "RGB röd" msgid "RSS" msgstr "RSS" msgid "RYB v1" msgstr "RYB v1" msgid "RYB v2" msgstr "RYB v2" msgid "R_everse" msgstr "O_mvänt" msgid "Real values" msgstr "Verkliga värden" msgid "Recent _Files" msgstr "Tidigare _filer" msgid "Rectangle (tetradic)" msgstr "Rektangel (tetradic)" msgid "Red" msgstr "Röd" msgid "Remove _All" msgstr "Ta bort _alla" msgid "Rotation:" msgstr "Rotation:" msgid "Sample" msgstr "Prov" msgid "Sample count" msgstr "Antal prov" msgid "Sample:" msgstr "Prov:" msgid "Saturation" msgstr "Mättnad" msgid "Saturation:" msgstr "Mättnad:" msgid "Save" msgstr "Spara" msgid "Save As" msgstr "Spara som" msgid "Save/_Restore palette" msgstr "Spara/_Återställ palett" msgid "Scheme _generation" msgstr "Schema_generering" msgid "Scheme generation" msgstr "Schemagenerering" msgid "Seed:" msgstr "Startvärde:" msgid "Settings" msgstr "Inställningar" msgid "Short hex" msgstr "Kort hex" msgid "Sidebar" msgstr "Sidofält" msgid "Six-Tone" msgstr "Sex-ton" msgid "Small" msgstr "Liten" msgid "Sort type:" msgstr "Sorteringstyp:" msgid "Split-Complementary" msgstr "Split-Complementary" msgid "Square" msgstr "Kvadrat" msgid "Start steps:" msgstr "Startsteg:" msgid "Start:" msgstr "Start:" msgid "Starting number:" msgstr "Startnummer:" msgid "Static" msgstr "Statisk" msgid "Steps:" msgstr "Steg:" msgid "Strength:" msgstr "Styrka:" msgid "Style item" msgstr "Stilobjekt" msgid "System" msgstr "System" msgid "System tray" msgstr "Systemfält" msgid "Terms" msgstr "Villkor" msgid "Test color" msgstr "Testfärg" msgid "Text File (*.txt)" msgstr "Textfil (*.txt)" msgid "Text file (*.txt)" msgstr "Textfil (*.txt)" msgid "The quick brown fox jumps over the lazy dog" msgstr "Flygande bäckasiner söka strax hwila på mjuka tuvor" msgid "Tool color naming" msgstr "Verktygsfärgnamn" #, c-format msgid "Total %d color" msgid_plural "Total %d colors" msgstr[0] "Totalt %d färg" msgstr[1] "Totalt %d färger" msgid "Triadic" msgstr "Triadisk" msgid "Tritanomaly" msgstr "Tritanomali" msgid "Tritanopia" msgstr "Tritanopi" msgid "Type:" msgstr "Typ:" msgid "Upper case" msgstr "VERSALER" msgid "User controllable" msgstr "Kontrollerbar för användaren" msgid "Value" msgstr "Värde" msgid "Value:" msgstr "Värde:" msgid "Variations" msgstr "Variationer" msgid "Web: hex code" msgstr "Webb: Hex-kod" msgid "Web: hex code (3 digits)" msgstr "Webb: Hex-kod (3 siffror)" msgid "Web: hex code (no hash symbol)" msgstr "Webb: Hex-kod (ingen hash-symbol)" msgid "Webpage" msgstr "Webbsida" msgid "White" msgstr "Vit" msgid "X axis" msgstr "X-axel" msgid "Y axis" msgstr "Y-axel" msgid "Yellow" msgstr "Gul" msgid "Z axis" msgstr "Z-axel" msgid "Zoom:" msgstr "Zoom:" msgid "_Add to palette" msgstr "_Lägg till i paletten" msgid "_Append" msgstr "_Bifoga" msgid "_Assign CSS Selectors..." msgstr "_Tilldela CSS-väljare..." msgid "_Automatic name" msgstr "_Automatiskt namn" msgid "_Close to system tray" msgstr "Stäng till systemfältet" msgid "_Color names" msgstr "_Färgnamn" msgid "_Copy to clipboard" msgstr "Kopiera till _urklipp" msgid "_Decreasing" msgstr "_Sjunkande" msgid "_Edit" msgstr "_Redigera" msgid "_Edit..." msgstr "_Redigera..." msgid "_Empty" msgstr "_Tom" msgid "_Enable display filters" msgstr "_Aktivera skärmfilter" msgid "_Export CSS File As..." msgstr "_Exportera CSS-fil som..." msgid "_File" msgstr "_Arkiv" msgid "_Generate..." msgstr "_Generera..." msgid "_Help" msgstr "_Hjälp" msgid "_Illuminant:" msgstr "_Belysning:" msgid "_Import..." msgstr "_Importera..." msgid "_Imprecision postfix" msgstr "Imprecis postfix" msgid "_Include Endpoints" msgstr "_Inkludera ändpunkter" msgid "_Linearization" msgstr "_Linjärisering" msgid "_Linked" msgstr "_Länkat" msgid "_Magnified area size:" msgstr "_Storlek på förstorat område:" msgid "_Main" msgstr "_Allmänt" msgid "_Mask out of gamut colors" msgstr "_Mask av gamut-färger" msgid "_Minimize to system tray" msgstr "_Minimera till systemfältet" msgid "_Mix Colors..." msgstr "_Blanda färger..." msgid "_Nearest from palette" msgstr "Närmast från palett" msgid "_Observer:" msgstr "_Observatör:" msgid "_Paste" msgstr "_Klistra in" msgid "_Picker" msgstr "_Väljare" msgid "_Quit" msgstr "A_vsluta" msgid "_Refresh rate:" msgstr "_Uppdateringsintervall:" msgid "_Remove" msgstr "_Ta bort" msgid "_Reset" msgstr "_Återställ" msgid "_Reset scheme" msgstr "_Återställningsschema" msgid "_Reverse" msgstr "_Omvänt" msgid "_Reverse group order" msgstr "_Omvänd gruppordning" msgid "_Reverse order inside groups" msgstr "_Omvänd ordning i grupper" msgid "_Rotate swatch" msgstr "_Rotera färgrutan" msgid "_Secondary View" msgstr "_Sekundär vy" msgid "_Show Main Window" msgstr "_Visa huvudfönstret" msgid "_Single instance" msgstr "_Endast en instans" msgid "_Start in system tray" msgstr "_Starta i systemfältet" msgid "_Tool specific" msgstr "_Verktygsspecifik" msgid "_Tools" msgstr "_Verktyg" msgid "_Use multiplication" msgstr "_Använd multiplicering" msgid "_Variations..." msgstr "_Variationer..." msgid "_View" msgstr "V_isa" msgid "all colors" msgstr "alla färger" msgid "blend" msgstr "blanda" msgid "blend node" msgstr "blandnod" msgid "brightness darkness" msgstr "ljusstyrka mörker" msgid "closest color" msgstr "närmaste färg" msgid "color mixer" msgstr "färgblandare" msgid "color space" msgstr "färgrymd" msgid "error" msgstr "fel" msgid "layout preview" msgstr "layoutgranskning" msgid "main" msgstr "allmänt" #, c-format msgid "match %d" msgstr "matcha %d" msgid "mix" msgstr "blanda" msgid "mix node" msgstr "mix-nod" #, c-format msgid "primary %d" msgstr "primär %d" #, c-format msgid "result %d" msgstr "resultat %d" #, c-format msgid "result %d line %d" msgstr "resultat %d rad %d" msgid "rgb.txt File (rgb.txt)" msgstr "rgb textfil (rgb.txt)" msgid "scheme" msgstr "schema" msgid "secondary" msgstr "sekundär" msgid "selected" msgstr "markerad" msgid "target" msgstr "mål" msgid "variation" msgstr "variation" msgid "variations" msgstr "variationer" gpick-gpick-0.2.6/share/man/000077500000000000000000000000001377073231300155725ustar00rootroot00000000000000gpick-gpick-0.2.6/share/man/man1/000077500000000000000000000000001377073231300164265ustar00rootroot00000000000000gpick-gpick-0.2.6/share/man/man1/gpick.1000066400000000000000000000003241377073231300176040ustar00rootroot00000000000000.TH gpick .SH NAME gpick \- advanced color picker .SH SYNOPSIS .B gpick [\fIFILE\fR] .SH DESCRIPTION \fBgpick\fR starts an application and opens FILE if it is specified .SH AUTHOR Written by Albertas Vyšniauskasgpick-gpick-0.2.6/share/metainfo/000077500000000000000000000000001377073231300166215ustar00rootroot00000000000000gpick-gpick-0.2.6/share/metainfo/gpick.appdata.xml000066400000000000000000000032031377073231300220470ustar00rootroot00000000000000 gpick.desktop CC0-1.0 BSD-3-Clause Gpick Advanced color picker and palette editor

Gpick is an application that allows you to sample any color from anywhere on the desktop, and use it to create palettes (i.e. collections of colors) for use in graphic design applications. Gpick also has other features that help in the creation of color palettes, such as: the ability to create a palette from an imported image, automatic naming of colors, and a scheme generator.

http://static.gpick.org/image/appdata-screenshot-0.2.6.png The main window showing the application in action http://www.gpick.org https://github.com/thezbyg/gpick albertas.vysniauskas@gpick.org Albertas Vyšniauskas http://www.gpick.org/help/donation.html http://www.gpick.org/help.html gpick color picker eye dropper palette scheme http://www.gpick.org/help/translation.html
gpick-gpick-0.2.6/share/mime/000077500000000000000000000000001377073231300157465ustar00rootroot00000000000000gpick-gpick-0.2.6/share/mime/packages/000077500000000000000000000000001377073231300175245ustar00rootroot00000000000000gpick-gpick-0.2.6/share/mime/packages/gpick.xml000066400000000000000000000004341377073231300213440ustar00rootroot00000000000000 Gpick palette gpick-gpick-0.2.6/source/000077500000000000000000000000001377073231300152155ustar00rootroot00000000000000gpick-gpick-0.2.6/source/BezierCubicCurve.h000066400000000000000000000042431377073231300205640ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_BEZIER_CUBIC_CURVE_H_ #define GPICK_BEZIER_CUBIC_CURVE_H_ namespace math { template struct BezierCubicCurve { BezierCubicCurve(const PT &p0_, const PT &p1_, const PT &p2_, const PT &p3_): p0(p0_), p1(p1_), p2(p2_), p3(p3_) { }; PT operator() (const T &t) { T t2 = 1 - t; return p0 * (t2 * t2 * t2) + p1 * (3 * (t2 * t2) * t) + p2 * (3 * t2 * t * t) + p3 * (t * t * t); }; BezierCubicCurve& operator= (const BezierCubicCurve& curve) { p0 = curve.p0; p1 = curve.p1; p2 = curve.p2; p3 = curve.p3; return *this; }; PT p0; PT p1; PT p2; PT p3; }; } #endif /* GPICK_BEZIER_CUBIC_CURVE_H_ */ gpick-gpick-0.2.6/source/BlendColors.cpp000066400000000000000000000411171377073231300201330ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "BlendColors.h" #include "ColorObject.h" #include "ColorSource.h" #include "ColorSourceManager.h" #include "ColorUtils.h" #include "uiListPalette.h" #include "uiUtilities.h" #include "dynv/Map.h" #include "GlobalState.h" #include "ToolColorNaming.h" #include "DragDrop.h" #include "ColorList.h" #include "color_names/ColorNames.h" #include "gtk/ColorWidget.h" #include "StandardEventHandler.h" #include "IMenuExtension.h" #include "I18N.h" #include #include struct BlendColorNameAssigner: ToolColorNameAssigner { BlendColorNameAssigner(GlobalState *gs): ToolColorNameAssigner(gs) { m_isColorItem = false; } void setNames(const std::string &startColorName, const std::string &endColorName) { m_colorStart = startColorName; m_colorEnd = endColorName; } void setStepsAndStage(int steps, int stage) { m_steps = steps; m_stage = stage; } void assign(ColorObject *colorObject, const Color *color, int step) { m_startPercent = step * 100 / (m_steps - 1); m_endPercent = 100 - (step * 100 / (m_steps - 1)); m_isColorItem = (((step == 0 || step == m_steps - 1) && m_stage == 0) || (m_stage == 1 && step == m_steps - 1)); ToolColorNameAssigner::assign(colorObject, color); } void assign(ColorObject *colorObject, const Color *color) { m_isColorItem = true; ToolColorNameAssigner::assign(colorObject, color); } virtual std::string getToolSpecificName(ColorObject *colorObject, const Color *color) { m_stream.str(""); if (m_isColorItem) { if (m_endPercent == 100) { m_stream << m_colorEnd << " " << _("blend node"); } else { m_stream << m_colorStart << " " << _("blend node"); } } else { m_stream << m_colorStart << " " << m_startPercent << " " << _("blend") << " " << m_endPercent << " " << m_colorEnd; } return m_stream.str(); } private: std::stringstream m_stream; std::string m_colorStart, m_colorEnd; int m_startPercent, m_endPercent, m_steps, m_stage; bool m_isColorItem; }; struct BlendColorsArgs { ColorSource source; GtkWidget *main, *mixType, *stepsSpinButton1, *stepsSpinButton2, *startColor, *middleColor, *endColor, *lastFocusedColor; ColorList *previewColorList; dynv::Ref options; GlobalState *gs; ColorObject colorObject; void add(const Color &color, int step, BlendColorNameAssigner &nameAssigner) { colorObject.setColor(color); nameAssigner.assign(&colorObject, &color, step); color_list_add_color_object(previewColorList, colorObject, true); } void addToPalette() { colorObject = getColor(); color_list_add_color_object(gs->getColorList(), colorObject, true); } const ColorObject &getColor() { Color color; gtk_color_get_color(GTK_COLOR(lastFocusedColor), &color); colorObject.setColor(color); BlendColorNameAssigner nameAssigner(gs); auto name = color_names_get(gs->getColorNames(), &color, false); nameAssigner.setNames(name, name); nameAssigner.assign(&colorObject, &color); return colorObject; } void setColor(const ColorObject &colorObject) { gtk_color_set_color(GTK_COLOR(lastFocusedColor), colorObject.getColor()); update(); } void setActiveWidget(int index) { switch (index) { case 0: lastFocusedColor = startColor; break; case 1: lastFocusedColor = middleColor; break; case 2: lastFocusedColor = endColor; break; } } void setActiveWidget(GtkWidget *widget) { lastFocusedColor = widget; } static void onResetMiddleColor(GtkWidget *, BlendColorsArgs *args) { Color a, b; gtk_color_get_color(GTK_COLOR(args->startColor), &a); gtk_color_get_color(GTK_COLOR(args->endColor), &b); color_multiply(&a, 0.5f); color_multiply(&b, 0.5f); color_add(&a, &b); gtk_color_set_color(GTK_COLOR(args->middleColor), a); args->update(); } static void onChange(GtkWidget *, BlendColorsArgs *args) { args->update(); } void update(int limit = 101) { int steps1 = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stepsSpinButton1)); int steps2 = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(stepsSpinButton2)); int type = gtk_combo_box_get_active(GTK_COMBO_BOX(mixType)); Color r, a, b; BlendColorNameAssigner nameAssigner(gs); color_list_remove_all(previewColorList); for (int stage = 0; stage < 2; stage++) { int steps; if (stage == 0) { steps = steps1 + 1; gtk_color_get_color(GTK_COLOR(startColor), &a); gtk_color_get_color(GTK_COLOR(middleColor), &b); } else { steps = steps2 + 1; gtk_color_get_color(GTK_COLOR(middleColor), &a); gtk_color_get_color(GTK_COLOR(endColor), &b); } auto startName = color_names_get(gs->getColorNames(), &a, false); auto endName = color_names_get(gs->getColorNames(), &b, false); nameAssigner.setNames(startName, endName); nameAssigner.setStepsAndStage(steps, stage); int i = stage; switch (type) { case 0: color_rgb_get_linear(&a, &a); color_rgb_get_linear(&b, &b); for (; i < steps; ++i) { color_utils::mix(a, b, i / static_cast(steps - 1), r); color_linear_get_rgb(&r, &r); add(r, i, nameAssigner); } break; case 1: { Color a_hsv, b_hsv, r_hsv; color_rgb_to_hsv(&a, &a_hsv); color_rgb_to_hsv(&b, &b_hsv); if (a_hsv.hsv.hue > b_hsv.hsv.hue) { if (a_hsv.hsv.hue - b_hsv.hsv.hue > 0.5) a_hsv.hsv.hue -= 1; } else { if (b_hsv.hsv.hue - a_hsv.hsv.hue > 0.5) b_hsv.hsv.hue -= 1; } for (; i < steps; ++i) { color_utils::mix(a_hsv, b_hsv, i / static_cast(steps - 1), r_hsv); if (r_hsv.hsv.hue < 0) r_hsv.hsv.hue += 1; color_hsv_to_rgb(&r_hsv, &r); add(r, i, nameAssigner); } } break; case 2: { Color a_lab, b_lab, r_lab; color_rgb_to_lab_d50(&a, &a_lab); color_rgb_to_lab_d50(&b, &b_lab); for (; i < steps; ++i) { color_utils::mix(a_lab, b_lab, i / static_cast(steps - 1), r_lab); color_lab_to_rgb_d50(&r_lab, &r); color_rgb_normalize(&r); add(r, i, nameAssigner); } } break; case 3: { Color a_lch, b_lch, r_lch; color_rgb_to_lch_d50(&a, &a_lch); color_rgb_to_lch_d50(&b, &b_lch); if (a_lch.lch.h > b_lch.lch.h) { if (a_lch.lch.h - b_lch.lch.h > 180) a_lch.lch.h -= 360; } else { if (b_lch.lch.h - a_lch.lch.h > 180) b_lch.lch.h -= 360; } for (; i < steps; ++i) { color_utils::mix(a_lch, b_lch, i / static_cast(steps - 1), r_lch); if (r_lch.lch.h < 0) r_lch.lch.h += 360; color_lch_to_rgb_d50(&r_lch, &r); color_rgb_normalize(&r); add(r, i, nameAssigner); } } break; } } } struct Editable: IEditableColorUI, IMenuExtension { Editable(BlendColorsArgs *args, int index): args(args), index(index) { } virtual ~Editable() = default; virtual void addToPalette(const ColorObject &) override { args->setActiveWidget(index); args->addToPalette(); } virtual void setColor(const ColorObject &colorObject) override { args->setActiveWidget(index); args->setColor(colorObject.getColor()); } virtual const ColorObject &getColor() override { args->setActiveWidget(index); return args->getColor(); } virtual bool isEditable() override { return true; } virtual bool hasSelectedColor() override { return true; } virtual void extendMenu(GtkWidget *menu, Position position) { if (position != Position::end || index != 1) return; gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); auto item = gtk_menu_item_new_with_mnemonic(_("_Reset")); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(onResetMiddleColor), args); } private: BlendColorsArgs *args; int index; }; std::vector editables; }; static ColorObject *getColorObject(struct DragDrop *dd) { auto *args = static_cast(dd->userdata); args->setActiveWidget(dd->widget); return args->getColor().copy(); } static int setColorObjectAt(struct DragDrop *dd, ColorObject *colorObject, int, int, bool, bool) { auto *args = static_cast(dd->userdata); args->setActiveWidget(dd->widget); args->setColor(*colorObject); return 0; } static int getColor(BlendColorsArgs *args, ColorObject **color) { return -1; } static int setColor(BlendColorsArgs *args, ColorObject *color) { return -1; } static int activate(BlendColorsArgs *args) { return 0; } static int deactivate(BlendColorsArgs *args) { return 0; } static int destroy(BlendColorsArgs *args) { int steps1 = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(args->stepsSpinButton1)); int steps2 = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(args->stepsSpinButton2)); int type = gtk_combo_box_get_active(GTK_COMBO_BOX(args->mixType)); args->options->set("type", type); args->options->set("steps1", steps1); args->options->set("steps2", steps2); Color color; gtk_color_get_color(GTK_COLOR(args->startColor), &color); args->options->set("start_color", color); gtk_color_get_color(GTK_COLOR(args->middleColor), &color); args->options->set("middle_color", color); gtk_color_get_color(GTK_COLOR(args->endColor), &color); args->options->set("end_color", color); color_list_destroy(args->previewColorList); gtk_widget_destroy(args->main); delete args; return 0; } static ColorSource *source_implement(ColorSource *source, GlobalState *gs, const dynv::Ref &options) { auto *args = new BlendColorsArgs; args->editables.emplace_back(args, 0); args->editables.emplace_back(args, 1); args->editables.emplace_back(args, 2); args->options = options; args->gs = gs; color_source_init(&args->source, source->identificator, source->hr_name); args->source.destroy = (int (*)(ColorSource *))destroy; args->source.get_color = (int (*)(ColorSource *, ColorObject **))getColor; args->source.set_color = (int (*)(ColorSource *, ColorObject *))setColor; args->source.deactivate = (int (*)(ColorSource *))deactivate; args->source.activate = (int (*)(ColorSource *))activate; GtkWidget *table, *widget; int table_y = 0; table = gtk_table_new(6, 2, false); struct DragDrop dd; dragdrop_init(&dd, gs); dd.converterType = Converters::Type::display; dd.userdata = args; dd.get_color_object = getColorObject; dd.set_color_object_at = setColorObjectAt; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Start:"), 0, 0, 0, 0), 0, 1, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 5, 5); args->startColor = widget = gtk_color_new(args->options->getColor("start_color", Color(0.5f)), ColorWidgetConfiguration::standard); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 0, 0); gtk_drag_dest_set(widget, GtkDestDefaults(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT), 0, 0, GDK_ACTION_COPY); gtk_drag_source_set(widget, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY); dragdrop_widget_attach(widget, DragDropFlags(DRAGDROP_SOURCE | DRAGDROP_DESTINATION), &dd); StandardEventHandler::forWidget(widget, args->gs, &args->editables[0]); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Middle:"), 0, 0, 0, 0), 0, 1, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 5, 5); args->middleColor = widget = gtk_color_new(args->options->getColor("middle_color", Color(0.5f)), ColorWidgetConfiguration::standard); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 0, 0); gtk_drag_dest_set(widget, GtkDestDefaults(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT), 0, 0, GDK_ACTION_COPY); gtk_drag_source_set(widget, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY); dragdrop_widget_attach(widget, DragDropFlags(DRAGDROP_SOURCE | DRAGDROP_DESTINATION), &dd); StandardEventHandler::forWidget(widget, args->gs, &args->editables[1]); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("End:"), 0, 0, 0, 0), 0, 1, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 5, 5); args->endColor = widget = gtk_color_new(args->options->getColor("end_color", Color(0.5f)), ColorWidgetConfiguration::standard); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 0, 0); gtk_drag_dest_set(widget, GtkDestDefaults(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT), 0, 0, GDK_ACTION_COPY); gtk_drag_source_set(widget, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY); dragdrop_widget_attach(widget, DragDropFlags(DRAGDROP_SOURCE | DRAGDROP_DESTINATION), &dd); StandardEventHandler::forWidget(widget, args->gs, &args->editables[2]); table_y = 0; GtkWidget *vbox = gtk_vbox_new(false, 0); gtk_box_pack_start(GTK_BOX(vbox), gtk_label_aligned_new(_("Type:"), 0, 0, 0, 0), false, false, 0); args->mixType = widget = gtk_combo_box_text_new(); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), _("RGB")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), _("HSV")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), _("LAB")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), _("LCH")); gtk_combo_box_set_active(GTK_COMBO_BOX(widget), args->options->getInt32("type", 0)); gtk_box_pack_start(GTK_BOX(vbox), widget, false, false, 0); g_signal_connect(G_OBJECT(widget), "changed", G_CALLBACK(BlendColorsArgs::onChange), args); gtk_table_attach(GTK_TABLE(table), vbox, 4, 5, table_y, table_y + 3, GtkAttachOptions(GTK_FILL), GtkAttachOptions(GTK_FILL), 5, 0); table_y = 0; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Start steps:"), 0, 0, 0, 0), 2, 3, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 5, 5); args->stepsSpinButton1 = widget = gtk_spin_button_new_with_range(1, 255, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), args->options->getInt32("steps1", 3)); gtk_table_attach(GTK_TABLE(table), widget, 3, 4, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 5, 0); table_y++; g_signal_connect(G_OBJECT(widget), "value-changed", G_CALLBACK(BlendColorsArgs::onChange), args); gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("End steps:"), 0, 0, 0, 0), 2, 3, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 5, 5); args->stepsSpinButton2 = widget = gtk_spin_button_new_with_range(1, 255, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), args->options->getInt32("steps2", 3)); gtk_table_attach(GTK_TABLE(table), widget, 3, 4, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 5, 0); table_y++; g_signal_connect(G_OBJECT(widget), "value-changed", G_CALLBACK(BlendColorsArgs::onChange), args); table_y = 3; ColorList *previewColorList = nullptr; gtk_table_attach(GTK_TABLE(table), palette_list_preview_new(gs, false, false, gs->getColorList(), &previewColorList), 0, 5, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL | GTK_EXPAND), 5, 5); table_y++; args->previewColorList = previewColorList; args->update(); gtk_widget_show_all(table); args->main = table; args->source.widget = table; return (ColorSource *)args; } int blend_colors_source_register(ColorSourceManager *csm) { ColorSource *color_source = new ColorSource; color_source_init(color_source, "blend_colors", _("Blend colors")); color_source->implement = source_implement; color_source->default_accelerator = GDK_KEY_b; color_source_manager_add_source(csm, color_source); return 0; } gpick-gpick-0.2.6/source/BlendColors.h000066400000000000000000000033071377073231300175770ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_BLEND_COLORS_H_ #define GPICK_BLEND_COLORS_H_ struct ColorSourceManager; int blend_colors_source_register(ColorSourceManager *csm); #endif /* GPICK_BLEND_COLORS_H_ */ gpick-gpick-0.2.6/source/BrightnessDarkness.cpp000066400000000000000000000302301377073231300215220ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "BrightnessDarkness.h" #include "ColorSource.h" #include "ColorSourceManager.h" #include "DragDrop.h" #include "GlobalState.h" #include "ToolColorNaming.h" #include "uiUtilities.h" #include "ColorList.h" #include "MathUtil.h" #include "gtk/Range2D.h" #include "gtk/LayoutPreview.h" #include "dynv/Map.h" #include "I18N.h" #include "color_names/ColorNames.h" #include "layout/Layout.h" #include "layout/Layouts.h" #include "layout/Style.h" #include "StandardEventHandler.h" #include "common/Format.h" #include #include #include #include using namespace layout; struct BrightnessDarknessArgs; struct BrightnessDarknessColorNameAssigner: public ToolColorNameAssigner { BrightnessDarknessColorNameAssigner(GlobalState *gs): ToolColorNameAssigner(gs) { } void assign(ColorObject *colorObject, Color *color, const char *ident) { m_ident = ident; ToolColorNameAssigner::assign(colorObject, color); } virtual std::string getToolSpecificName(ColorObject *colorObject, const Color *color) { m_stream.str(""); m_stream << color_names_get(m_gs->getColorNames(), color, false) << " " << _("brightness darkness") << " " << m_ident; return m_stream.str(); } protected: std::stringstream m_stream; const char *m_ident; }; struct BrightnessDarknessArgs { ColorSource source; Color color; GtkWidget *main, *statusBar, *brightnessDarkness, *layoutView; System *layoutSystem; dynv::Ref options; GlobalState *gs; void addToPalette() { if (!isSelected()) return; color_list_add_color_object(gs->getColorList(), getColor(), true); } void addAllToPalette() { if (layoutSystem == nullptr) return; BrightnessDarknessColorNameAssigner nameAssigner(gs); for (auto &style: layoutSystem->styles) { ColorObject colorObject(style->color); nameAssigner.assign(&colorObject, &style->color, style->label.c_str()); color_list_add_color_object(gs->getColorList(), colorObject, true); } } void setColor(const ColorObject &colorObject) { color = colorObject.getColor(); gtk_layout_preview_set_color_named(GTK_LAYOUT_PREVIEW(layoutView), &color, "main"); update(false); } ColorObject colorObject; const ColorObject &getColor() { Color color; if (gtk_layout_preview_get_current_color(GTK_LAYOUT_PREVIEW(layoutView), &color) != 0) return colorObject; Style *style = 0; if (gtk_layout_preview_get_current_style(GTK_LAYOUT_PREVIEW(layoutView), &style) != 0) return colorObject; colorObject.setColor(color); BrightnessDarknessColorNameAssigner nameAssigner(gs); nameAssigner.assign(&colorObject, &color, style->label.c_str()); return colorObject; } std::vector getColors(bool selected) { if (layoutSystem == nullptr) return std::vector(); BrightnessDarknessColorNameAssigner nameAssigner(gs); std::vector colors; if (selected) { auto colorObject = getColor(); colors.push_back(colorObject); } else { for (auto &style: layoutSystem->styles) { ColorObject colorObject(style->color); nameAssigner.assign(&colorObject, &style->color, style->label.c_str()); colors.push_back(colorObject); } } return colors; } bool selectMain() { gtk_layout_preview_set_focus_named(GTK_LAYOUT_PREVIEW(layoutView), "main"); return gtk_layout_preview_is_selected(GTK_LAYOUT_PREVIEW(layoutView)); } bool isSelected() { return gtk_layout_preview_is_selected(GTK_LAYOUT_PREVIEW(layoutView)); } bool isEditable() { if (!gtk_layout_preview_is_selected(GTK_LAYOUT_PREVIEW(layoutView))) return false; return gtk_layout_preview_is_editable(GTK_LAYOUT_PREVIEW(layoutView)); } static std::string format(char prefix, int index) { return prefix + common::as_string(index); } void update(bool saveSettings) { float brightness = static_cast(gtk_range_2d_get_x(GTK_RANGE_2D(brightnessDarkness))); float darkness = static_cast(gtk_range_2d_get_y(GTK_RANGE_2D(brightnessDarkness))); if (saveSettings) { options->set("brightness", brightness); options->set("darkness", brightness); } Color hslOriginal, hsl, r; color_rgb_to_hsl(&color, &hslOriginal); Box *box; std::string name; if (layoutSystem == nullptr) return; for (int i = 1; i <= 4; i++) { color_copy(&hslOriginal, &hsl); hsl.hsl.lightness = mix_float(hsl.hsl.lightness, mix_float(hsl.hsl.lightness, 1, brightness), i / 4.0f); color_hsl_to_rgb(&hsl, &r); name = format('b', i); box = layoutSystem->GetNamedBox(name.c_str()); if (box && box->style) { color_copy(&r, &box->style->color); } color_copy(&hslOriginal, &hsl); hsl.hsl.lightness = mix_float(hsl.hsl.lightness, mix_float(hsl.hsl.lightness, 0, darkness), i / 4.0f); color_hsl_to_rgb(&hsl, &r); name = format('c', i); box = layoutSystem->GetNamedBox(name.c_str()); if (box && box->style) { color_copy(&r, &box->style->color); } } gtk_widget_queue_draw(GTK_WIDGET(layoutView)); } static void onChange(GtkWidget *, BrightnessDarknessArgs *args) { args->update(false); } struct Editable: public IEditableColorsUI { Editable(BrightnessDarknessArgs *args): args(args) { } virtual ~Editable() = default; virtual void addToPalette(const ColorObject &) override { args->addToPalette(); } virtual void addAllToPalette() override { args->addAllToPalette(); } virtual void setColor(const ColorObject &colorObject) override { args->setColor(colorObject.getColor()); } virtual const ColorObject &getColor() override { return args->getColor(); } virtual std::vector getColors(bool selected) override { return args->getColors(selected); } virtual bool isEditable() override { return args->isEditable(); } virtual bool hasColor() override { return true; } virtual bool hasSelectedColor() override { return args->isSelected(); } private: BrightnessDarknessArgs *args; }; boost::optional editable; }; static int getColor(BrightnessDarknessArgs *args, ColorObject **color) { if (!args->isSelected()) return -1; auto colorObject = args->getColor(); *color = colorObject.copy(); return 0; } static int setColor(BrightnessDarknessArgs *args, ColorObject *colorObject) { args->setColor(*colorObject); return 0; } static ColorObject *getColorObject(struct DragDrop *dd) { auto *args = static_cast(dd->userdata); if (!args->isSelected()) return nullptr; return args->getColor().copy(); } static int setColorObjectAt(struct DragDrop *dd, ColorObject *colorObject, int x, int y, bool, bool) { auto *args = static_cast(dd->userdata); args->setColor(*colorObject); return 0; } static bool testAt(struct DragDrop *dd, int x, int y) { auto *args = static_cast(dd->userdata); return args->selectMain(); } static gboolean onButtonPress(GtkWidget *widget, GdkEventButton *event, BrightnessDarknessArgs *args) { if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) { args->addToPalette(); return true; } return false; } static int destroy(BrightnessDarknessArgs *args) { if (args->layoutSystem) System::unref(args->layoutSystem); args->layoutSystem = nullptr; gtk_widget_destroy(args->main); delete args; return 0; } static int activate(BrightnessDarknessArgs *args) { auto chain = args->gs->getTransformationChain(); gtk_layout_preview_set_transformation_chain(GTK_LAYOUT_PREVIEW(args->layoutView), chain); gtk_statusbar_push(GTK_STATUSBAR(args->statusBar), gtk_statusbar_get_context_id(GTK_STATUSBAR(args->statusBar), "empty"), ""); return 0; } static int deactivate(BrightnessDarknessArgs *args) { args->options->set("color", args->color); args->update(true); return 0; } static ColorSource *implement(ColorSource *source, GlobalState *gs, const dynv::Ref &options) { auto *args = new BrightnessDarknessArgs; args->editable = BrightnessDarknessArgs::Editable(args); args->options = options; args->statusBar = gs->getStatusBar(); args->gs = gs; color_source_init(&args->source, source->identificator, source->hr_name); args->source.destroy = (int (*)(ColorSource *source)) destroy; args->source.get_color = (int (*)(ColorSource *source, ColorObject **color)) getColor; args->source.set_color = (int (*)(ColorSource *source, ColorObject *color)) setColor; args->source.deactivate = (int (*)(ColorSource *source)) deactivate; args->source.activate = (int (*)(ColorSource *source)) activate; args->layoutSystem = nullptr; GtkWidget *hbox, *widget; hbox = gtk_hbox_new(false, 0); struct DragDrop dd; dragdrop_init(&dd, gs); dd.converterType = Converters::Type::display; dd.userdata = args; dd.get_color_object = getColorObject; dd.set_color_object_at = setColorObjectAt; dd.test_at = testAt; args->brightnessDarkness = widget = gtk_range_2d_new(); gtk_range_2d_set_values(GTK_RANGE_2D(widget), options->getFloat("brightness", 0.5f), options->getFloat("darkness", 0.5f)); gtk_range_2d_set_axis(GTK_RANGE_2D(widget), _("Brightness"), _("Darkness")); g_signal_connect(G_OBJECT(widget), "values_changed", G_CALLBACK(BrightnessDarknessArgs::onChange), args); gtk_box_pack_start(GTK_BOX(hbox), widget, false, false, 0); args->layoutView = widget = gtk_layout_preview_new(); g_signal_connect_after(G_OBJECT(widget), "button-press-event", G_CALLBACK(onButtonPress), args); StandardEventHandler::forWidget(widget, args->gs, &*args->editable); gtk_box_pack_start(GTK_BOX(hbox), widget, false, false, 0); //setup drag&drop gtk_drag_dest_set(widget, GtkDestDefaults(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT), 0, 0, GDK_ACTION_COPY); gtk_drag_source_set(widget, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY); dd.userdata2 = (void *)-1; dragdrop_widget_attach(widget, DragDropFlags(DRAGDROP_SOURCE | DRAGDROP_DESTINATION), &dd); auto layout = gs->layouts().byName("std_layout_brightness_darkness"); if (layout != nullptr) { System *layoutSystem = layout->build(); gtk_layout_preview_set_system(GTK_LAYOUT_PREVIEW(args->layoutView), layoutSystem); if (args->layoutSystem) System::unref(args->layoutSystem); args->layoutSystem = layoutSystem; } else { if (args->layoutSystem) System::unref(args->layoutSystem); args->layoutSystem = nullptr; } args->color = options->getColor("color", Color(0.5f)); gtk_layout_preview_set_color_named(GTK_LAYOUT_PREVIEW(args->layoutView), &args->color, "main"); args->update(false); gtk_widget_show_all(hbox); args->main = hbox; args->source.widget = hbox; return (ColorSource *)args; } int brightness_darkness_source_register(ColorSourceManager *csm) { ColorSource *color_source = new ColorSource; color_source_init(color_source, "brightness_darkness", _("Brightness Darkness")); color_source->implement = implement; color_source->default_accelerator = GDK_KEY_d; color_source_manager_add_source(csm, color_source); return 0; } gpick-gpick-0.2.6/source/BrightnessDarkness.h000066400000000000000000000033431377073231300211740ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_BRIGHTNESS_DARKNESS_H_ #define GPICK_BRIGHTNESS_DARKNESS_H_ struct ColorSourceManager; int brightness_darkness_source_register(ColorSourceManager *csm); #endif /* GPICK_BRIGHTNESS_DARKNESS_H_ */ gpick-gpick-0.2.6/source/Clipboard.cpp000066400000000000000000000370231377073231300176250ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Clipboard.h" #include "Converters.h" #include "Converter.h" #include "GlobalState.h" #include "ColorObject.h" #include "Color.h" #include "uiListPalette.h" #include "ColorList.h" #include "dynv/Map.h" #include #include namespace clipboard { enum class Target : guint { string = 1, color, serializedColorObjectList, }; static const GtkTargetEntry targets[] = { { const_cast("application/x-color_object-list"), 0, static_cast(Target::serializedColorObjectList) }, { const_cast("application/x-color-object-list"), 0, static_cast(Target::serializedColorObjectList) }, { const_cast("application/x-color"), 0, static_cast(Target::color) }, { const_cast("text/plain"), 0, static_cast(Target::string) }, { const_cast("UTF8_STRING"), 0, static_cast(Target::string) }, { const_cast("STRING"), 0, static_cast(Target::string) }, }; static const size_t targetCount = sizeof(targets) / sizeof(GtkTargetEntry); struct CopyPasteArgs { Converter *converter; ColorList *colors; GlobalState *gs; CopyPasteArgs(ColorList *colors, Converter *converter, GlobalState *gs): converter(converter), colors(colors), gs(gs) { } ~CopyPasteArgs() { if (colors != nullptr) color_list_destroy(colors); } }; static void setData(GtkClipboard *, GtkSelectionData *selectionData, Target targetType, CopyPasteArgs *args) { if (!selectionData) return; switch (targetType) { case Target::string: { const auto &colors = args->colors->colors; std::stringstream text; std::string textLine; ConverterSerializePosition position(args->colors->colors.size()); if (position.count() > 0) { for (auto &color: colors) { if (position.index() + 1 == position.count()) position.last(true); textLine = args->converter->serialize(color, position); if (position.first()) { text << textLine; position.first(false); } else { text << "\n" << textLine; } position.incrementIndex(); } } textLine = text.str(); if (textLine.length() > 0) gtk_selection_data_set_text(selectionData, textLine.c_str(), -1); } break; case Target::color: { auto &colorObject = args->colors->colors.front(); auto &color = colorObject->getColor(); guint16 dataColor[4]; dataColor[0] = static_cast(color.rgb.red * 0xFFFF); dataColor[1] = static_cast(color.rgb.green * 0xFFFF); dataColor[2] = static_cast(color.rgb.blue * 0xFFFF); dataColor[3] = 0xffff; gtk_selection_data_set(selectionData, gdk_atom_intern("application/x-color", false), 16, reinterpret_cast(dataColor), 8); } break; case Target::serializedColorObjectList: { std::vector colors; colors.reserve(args->colors->colors.size()); for (auto &colorObject: args->colors->colors) { auto color = dynv::Map::create(); color->set("name", colorObject->getName()); color->set("color", colorObject->getColor()); colors.push_back(color); } dynv::Map values; values.set("colors", colors); std::stringstream str; values.serializeXml(str); auto data = str.str(); gtk_selection_data_set(selectionData, gdk_atom_intern("application/x-color-object-list", false), 8, reinterpret_cast(&data.front()), data.length()); } break; } } static void deleteState(GtkClipboard *, CopyPasteArgs *args) { delete args; } static bool setupClipboard(const ColorObject &colorObject, Converter *converter, GlobalState *gs) { auto colorList = color_list_new(); color_list_add_color_object(colorList, colorObject.copy(), false); auto args = new CopyPasteArgs(colorList, converter, gs); if (gtk_clipboard_set_with_data(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), targets, targetCount, reinterpret_cast(setData), reinterpret_cast(deleteState), args)) { gtk_clipboard_set_can_store(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), nullptr, 0); return true; } deleteState(nullptr, args); return false; } static bool setupClipboard(ColorList *colorList, Converter *converter, GlobalState *gs) { auto args = new CopyPasteArgs(colorList, converter, gs); if (gtk_clipboard_set_with_data(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), targets, targetCount, reinterpret_cast(setData), reinterpret_cast(deleteState), args)) { gtk_clipboard_set_can_store(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), nullptr, 0); return true; } deleteState(nullptr, args); return false; } static bool setupClipboard(const std::vector &colorObjects, Converter *converter, GlobalState *gs) { auto colorList = color_list_new(); for (auto &colorObject: colorObjects) { color_list_add_color_object(colorList, colorObject.copy(), false); } auto args = new CopyPasteArgs(colorList, converter, gs); if (gtk_clipboard_set_with_data(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), targets, targetCount, reinterpret_cast(setData), reinterpret_cast(deleteState), args)) { gtk_clipboard_set_can_store(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), nullptr, 0); return true; } deleteState(nullptr, args); return false; } static Converter *getConverter(ConverterSelection converterSelection, GlobalState *gs) { struct GetConverter: public boost::static_visitor { GetConverter(GlobalState *gs): gs(gs) { } Converter *operator()(const char *&name) const { auto converter = gs->converters().byNameOrFirstCopy(name); if (converter == nullptr) converter = gs->converters().firstCopyOrAny(); return converter; } Converter *operator()(Converter *converter) const { auto result = converter; if (result == nullptr) result = gs->converters().firstCopyOrAny(); return result; } Converter *operator()(Converters::Type converterType) const { auto converter = gs->converters().forType(converterType); if (converter == nullptr) converter = gs->converters().firstCopyOrAny(); return converter; } GlobalState *gs; }; return boost::apply_visitor(GetConverter(gs), converterSelection); } void set(const std::string &value) { gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), value.c_str(), -1); gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), value.c_str(), -1); } void set(const ColorObject *colorObject, GlobalState *gs, ConverterSelection converterSelection) { auto converter = getConverter(converterSelection, gs); if (converter == nullptr) return; setupClipboard(*colorObject, converter, gs); } void set(const std::vector &colorObjects, GlobalState *gs, ConverterSelection converterSelection) { auto converter = getConverter(converterSelection, gs); if (converter == nullptr) return; setupClipboard(colorObjects, converter, gs); } void set(const ColorObject &colorObject, GlobalState *gs, ConverterSelection converterSelection) { auto converter = getConverter(converterSelection, gs); if (converter == nullptr) return; setupClipboard(colorObject, converter, gs); } static PaletteListCallbackReturn addToColorList(ColorObject *colorObject, ColorList *colorList) { color_list_add_color_object(colorList, colorObject, 1); return PALETTE_LIST_CALLBACK_NO_UPDATE; } void set(GtkWidget *palette_widget, GlobalState *gs, ConverterSelection converterSelection) { auto converter = getConverter(converterSelection, gs); if (converter == nullptr) return; std::stringstream text; auto colorList = color_list_new(); palette_list_foreach_selected(palette_widget, (PaletteListCallback)addToColorList, colorList); if (colorList->colors.empty()) return; setupClipboard(colorList, converter, gs); } void set(const Color &color, GlobalState *gs, ConverterSelection converterSelection) { auto converter = getConverter(converterSelection, gs); if (converter == nullptr) return; setupClipboard(ColorObject("", color), converter, gs); } enum class VisitResult { stop, advance, }; static void perMatchedTarget(GdkAtom *availableTargets, size_t count, std::function callback) { for (size_t j = 0; j < targetCount; ++j) { for (size_t i = 0; i < count; ++i) { auto atomName = gdk_atom_name(availableTargets[i]); if (g_strcmp0(targets[j].target, atomName) == 0) { g_free(atomName); if (callback(i, static_cast(targets[j].info)) == VisitResult::stop) return; } else { g_free(atomName); } } } } bool colorObjectAvailable() { GdkAtom *availableTargets; gint availableTargetCount; if (!gtk_clipboard_wait_for_targets(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), &availableTargets, &availableTargetCount)) return false; if (availableTargetCount <= 0) { g_free(availableTargets); return false; } bool found = false; perMatchedTarget(availableTargets, static_cast(availableTargetCount), [&found](size_t, Target) { found = true; return VisitResult::stop; }); g_free(availableTargets); return found; } ColorObject *getFirst(GlobalState *gs) { auto clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); GdkAtom *availableTargets; gint availableTargetCount; if (!gtk_clipboard_wait_for_targets(clipboard, &availableTargets, &availableTargetCount)) return nullptr; if (availableTargetCount <= 0) { g_free(availableTargets); return nullptr; } ColorObject *result = nullptr; perMatchedTarget(availableTargets, static_cast(availableTargetCount), [&result, clipboard, availableTargets, gs](size_t i, Target target) { auto selectionData = gtk_clipboard_wait_for_contents(clipboard, availableTargets[i]); if (!selectionData) return VisitResult::advance; switch (target) { case Target::string: { auto data = gtk_selection_data_get_data(selectionData); auto text = std::string(reinterpret_cast(data), reinterpret_cast(data) + gtk_selection_data_get_length(selectionData)); if (gs->converters().deserialize(text.c_str(), &result)) return VisitResult::stop; } break; case Target::color: { if (gtk_selection_data_get_length(selectionData) != 8) return VisitResult::advance; auto data = gtk_selection_data_get_data(selectionData); guint16 values[4]; ::memcpy(values, data, 8); Color color; color.rgb.red = static_cast(data[0] / static_cast(0xFFFF)); color.rgb.green = static_cast(data[1] / static_cast(0xFFFF)); color.rgb.blue = static_cast(data[2] / static_cast(0xFFFF)); color.ma[3] = 0; result = new ColorObject("", color); return VisitResult::stop; } break; case Target::serializedColorObjectList: { auto data = gtk_selection_data_get_data(selectionData); auto text = std::string(reinterpret_cast(data), reinterpret_cast(data) + gtk_selection_data_get_length(selectionData)); std::stringstream textStream(text); dynv::Map values; if (!values.deserializeXml(textStream)) return VisitResult::advance; auto colors = values.getMaps("colors"); if (colors.size() == 0) return VisitResult::advance; static Color defaultColor = {}; result = new ColorObject(colors[0]->getString("name", ""), colors[0]->getColor("color", defaultColor)); return VisitResult::stop; } break; } return VisitResult::advance; }); return result; } ColorList *getColors(GlobalState *gs) { auto clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); GdkAtom *availableTargets; gint availableTargetCount; if (!gtk_clipboard_wait_for_targets(clipboard, &availableTargets, &availableTargetCount)) return nullptr; if (availableTargetCount <= 0) { g_free(availableTargets); return nullptr; } bool success = false; auto colorList = color_list_new(); perMatchedTarget(availableTargets, static_cast(availableTargetCount), [colorList, &success, clipboard, availableTargets, gs](size_t i, Target target) { auto selectionData = gtk_clipboard_wait_for_contents(clipboard, availableTargets[i]); if (!selectionData) return VisitResult::advance; switch (target) { case Target::string: { auto data = gtk_selection_data_get_data(selectionData); auto text = std::string(reinterpret_cast(data), reinterpret_cast(data) + gtk_selection_data_get_length(selectionData)); ColorObject *colorObject = nullptr; //TODO: multiple colors should be extracted from string, but converters do not support this right now if (gs->converters().deserialize(text.c_str(), &colorObject)) { color_list_add_color_object(colorList, colorObject, false); success = true; return VisitResult::stop; } } break; case Target::color: { if (gtk_selection_data_get_length(selectionData) != 8) return VisitResult::advance; auto data = gtk_selection_data_get_data(selectionData); guint16 values[4]; ::memcpy(values, data, 8); Color color; color.rgb.red = static_cast(data[0] / static_cast(0xFFFF)); color.rgb.green = static_cast(data[1] / static_cast(0xFFFF)); color.rgb.blue = static_cast(data[2] / static_cast(0xFFFF)); color.ma[3] = 0; ColorObject *reference; color_list_add_color_object(colorList, (reference = new ColorObject("", color)), false); reference->release(); success = true; return VisitResult::stop; } break; case Target::serializedColorObjectList: { auto data = gtk_selection_data_get_data(selectionData); auto text = std::string(reinterpret_cast(data), reinterpret_cast(data) + gtk_selection_data_get_length(selectionData)); std::stringstream textStream(text); dynv::Map values; if (!values.deserializeXml(textStream)) return VisitResult::advance; auto colors = values.getMaps("colors"); if (colors.size() == 0) return VisitResult::advance; static Color defaultColor = {}; for (auto &color: colors) { ColorObject *reference; color_list_add_color_object(colorList, (reference = new ColorObject(color->getString("name", ""), color->getColor("color", defaultColor))), false); reference->release(); } success = true; return VisitResult::stop; } break; } return VisitResult::advance; }); if (!success) { color_list_destroy(colorList); return nullptr; } return colorList; } } gpick-gpick-0.2.6/source/Clipboard.h000066400000000000000000000050441377073231300172700ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_CLIPBOARD_H_ #define GPICK_CLIPBOARD_H_ #include "Converters.h" #include #include #include struct ColorObject; struct GlobalState; struct Converter; struct Color; struct ColorList; typedef struct _GtkWidget GtkWidget; namespace clipboard { void set(const std::string &value); using ConverterSelection = boost::variant; void set(const ColorObject *colorObject, GlobalState *gs, ConverterSelection converterSelection); void set(const ColorObject &colorObject, GlobalState *gs, ConverterSelection converterSelection); void set(const std::vector &colorObjects, GlobalState *gs, ConverterSelection converterSelection); void set(const Color &color, GlobalState *gs, ConverterSelection converterSelection); void set(GtkWidget *paletteWidget, GlobalState *gs, ConverterSelection converterSelection); bool colorObjectAvailable(); ColorObject *getFirst(GlobalState *gs); ColorList *getColors(GlobalState *gs); } #endif /* GPICK_CLIPBOARD_H_ */ gpick-gpick-0.2.6/source/ClosestColors.cpp000066400000000000000000000260551377073231300205270ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ClosestColors.h" #include "ColorObject.h" #include "ColorSource.h" #include "ColorSourceManager.h" #include "DragDrop.h" #include "GlobalState.h" #include "ToolColorNaming.h" #include "uiUtilities.h" #include "ColorList.h" #include "gtk/ColorWidget.h" #include "dynv/Map.h" #include "I18N.h" #include "color_names/ColorNames.h" #include "StandardEventHandler.h" #include "common/Format.h" #include #include struct ClosestColorsArgs; struct ClosestColorsColorNameAssigner: public ToolColorNameAssigner { ClosestColorsColorNameAssigner(GlobalState *gs): ToolColorNameAssigner(gs) { } void assign(ColorObject *colorObject, const Color *color, const char *ident) { m_ident = ident; ToolColorNameAssigner::assign(colorObject, color); } virtual std::string getToolSpecificName(ColorObject *colorObject, const Color *color) { m_stream.str(""); m_stream << color_names_get(m_gs->getColorNames(), color, false) << " " << _("closest color") << " " << m_ident; return m_stream.str(); } protected: std::stringstream m_stream; const char *m_ident; }; struct ClosestColorsArgs { ColorSource source; GtkWidget *main, *statusBar, *targetColor, *lastFocusedColor, *colorPreviews, *closestColors[9]; dynv::Ref options; GlobalState *gs; void addToPalette() { color_list_add_color_object(gs->getColorList(), getColor(), true); } void addAllToPalette() { ClosestColorsColorNameAssigner nameAssigner(gs); Color color; gtk_color_get_color(GTK_COLOR(targetColor), &color); colorObject.setColor(color); auto widgetName = identifyColorWidget(targetColor); nameAssigner.assign(&colorObject, &color, widgetName.c_str()); color_list_add_color_object(gs->getColorList(), colorObject, true); for (int i = 0; i < 9; ++i) { gtk_color_get_color(GTK_COLOR(closestColors[i]), &color); colorObject.setColor(color); widgetName = identifyColorWidget(closestColors[i]); nameAssigner.assign(&colorObject, &color, widgetName.c_str()); color_list_add_color_object(gs->getColorList(), colorObject, true); } } void setColor(const ColorObject &colorObject) { gtk_color_set_color(GTK_COLOR(targetColor), colorObject.getColor()); update(); } ColorObject colorObject; const ColorObject &getColor() { Color color; gtk_color_get_color(GTK_COLOR(lastFocusedColor), &color); auto widgetName = identifyColorWidget(lastFocusedColor); colorObject.setColor(color); ClosestColorsColorNameAssigner nameAssigner(gs); nameAssigner.assign(&colorObject, &color, widgetName.c_str()); return colorObject; } std::string identifyColorWidget(GtkWidget *widget) { if (targetColor == widget) return _("target"); for (int i = 0; i < 9; ++i) { if (closestColors[i] == widget) { return common::format(_("match {}"), i + 1); } } return "unknown"; } void update() { Color color; gtk_color_get_color(GTK_COLOR(targetColor), &color); std::vector> colors; color_names_find_nearest(gs->getColorNames(), color, 9, colors); for (size_t i = 0; i < 9; ++i) { if (i < colors.size()) { gtk_color_set_color(GTK_COLOR(closestColors[i]), &colors[i].second, colors[i].first); gtk_widget_set_sensitive(closestColors[i], true); } else { gtk_widget_set_sensitive(closestColors[i], false); } } } bool isEditable() { return lastFocusedColor == targetColor; } static gboolean onFocusEvent(GtkWidget *widget, GdkEventFocus *, ClosestColorsArgs *args) { args->lastFocusedColor = widget; return false; } static void onColorActivate(GtkWidget *, ClosestColorsArgs *args) { args->addToPalette(); } struct Editable: public IEditableColorsUI { Editable(ClosestColorsArgs *args): args(args) { } virtual ~Editable() = default; virtual void addToPalette(const ColorObject &) override { args->addToPalette(); } virtual void addAllToPalette() override { args->addAllToPalette(); } virtual void setColor(const ColorObject &colorObject) override { args->setColor(colorObject.getColor()); } virtual const ColorObject &getColor() override { return args->getColor(); } virtual std::vector getColors(bool selected) override { std::vector colors; colors.push_back(getColor()); return colors; } virtual bool isEditable() override { return args->isEditable(); } virtual bool hasColor() override { return true; } virtual bool hasSelectedColor() override { return true; } private: ClosestColorsArgs *args; }; boost::optional editable; }; static int destroy(ClosestColorsArgs *args) { Color color; gtk_color_get_color(GTK_COLOR(args->targetColor), &color); args->options->set("color", color); gtk_widget_destroy(args->main); delete args; return 0; } static int getColor(ClosestColorsArgs *args, ColorObject **color) { auto colorObject = args->getColor(); *color = colorObject.copy(); return 0; } static int setColor(ClosestColorsArgs *args, ColorObject *colorObject) { args->setColor(*colorObject); return 0; } static int activate(ClosestColorsArgs *args) { auto chain = args->gs->getTransformationChain(); gtk_color_set_transformation_chain(GTK_COLOR(args->targetColor), chain); for (int i = 0; i < 9; ++i) { gtk_color_set_transformation_chain(GTK_COLOR(args->closestColors[i]), chain); } gtk_statusbar_push(GTK_STATUSBAR(args->statusBar), gtk_statusbar_get_context_id(GTK_STATUSBAR(args->statusBar), "empty"), ""); return 0; } static int deactivate(ClosestColorsArgs *args) { return 0; } static ColorObject *getColorObject(DragDrop *dd) { auto *args = static_cast(dd->userdata); return args->getColor().copy(); } static int setColorObjectAt(DragDrop *dd, ColorObject *colorObject, int x, int y, bool, bool) { auto *args = static_cast(dd->userdata); setColor(args, colorObject); return 0; } ColorSource *source_implement(ColorSource *source, GlobalState *gs, const dynv::Ref &options) { auto *args = new ClosestColorsArgs; args->editable = ClosestColorsArgs::Editable(args); args->options = options; args->statusBar = gs->getStatusBar(); args->gs = gs; color_source_init(&args->source, source->identificator, source->hr_name); args->source.destroy = (int (*)(ColorSource * source)) destroy; args->source.get_color = (int (*)(ColorSource * source, ColorObject * *color)) getColor; args->source.set_color = (int (*)(ColorSource * source, ColorObject * color)) setColor; args->source.deactivate = (int (*)(ColorSource * source)) deactivate; args->source.activate = (int (*)(ColorSource * source)) activate; GtkWidget *vbox, *hbox, *widget; hbox = gtk_hbox_new(false, 0); vbox = gtk_vbox_new(false, 0); gtk_box_pack_start(GTK_BOX(hbox), vbox, true, true, 5); args->colorPreviews = gtk_table_new(3, 3, false); gtk_box_pack_start(GTK_BOX(vbox), args->colorPreviews, true, true, 0); DragDrop dd; dragdrop_init(&dd, gs); dd.converterType = Converters::Type::display; dd.userdata = args; dd.get_color_object = getColorObject; dd.set_color_object_at = setColorObjectAt; widget = gtk_color_new(); gtk_color_set_rounded(GTK_COLOR(widget), true); gtk_color_set_hcenter(GTK_COLOR(widget), true); gtk_color_set_roundness(GTK_COLOR(widget), 5); gtk_table_attach(GTK_TABLE(args->colorPreviews), widget, 0, 3, 0, 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL | GTK_EXPAND), 0, 0); args->targetColor = widget; g_signal_connect(G_OBJECT(widget), "activated", G_CALLBACK(ClosestColorsArgs::onColorActivate), args); g_signal_connect(G_OBJECT(widget), "focus-in-event", G_CALLBACK(ClosestColorsArgs::onFocusEvent), args); StandardEventHandler::forWidget(widget, args->gs, &*args->editable); gtk_widget_set_size_request(widget, 30, 30); //setup drag&drop gtk_drag_dest_set(widget, GtkDestDefaults(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT), 0, 0, GDK_ACTION_COPY); gtk_drag_source_set(widget, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY); dd.userdata2 = (void *)-1; dragdrop_widget_attach(widget, DragDropFlags(DRAGDROP_SOURCE | DRAGDROP_DESTINATION), &dd); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { widget = gtk_color_new(); gtk_color_set_rounded(GTK_COLOR(widget), true); gtk_color_set_hcenter(GTK_COLOR(widget), true); gtk_color_set_roundness(GTK_COLOR(widget), 5); gtk_table_attach(GTK_TABLE(args->colorPreviews), widget, i, i + 1, j + 1, j + 2, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL | GTK_EXPAND), 0, 0); args->closestColors[i + j * 3] = widget; g_signal_connect(G_OBJECT(widget), "activated", G_CALLBACK(ClosestColorsArgs::onColorActivate), args); g_signal_connect(G_OBJECT(widget), "focus-in-event", G_CALLBACK(ClosestColorsArgs::onFocusEvent), args); gtk_widget_set_size_request(widget, 30, 30); gtk_drag_source_set(widget, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY); dd.userdata2 = reinterpret_cast(i + j * 3); dragdrop_widget_attach(widget, DragDropFlags(DRAGDROP_SOURCE), &dd); StandardEventHandler::forWidget(widget, args->gs, &*args->editable); } } gtk_color_set_color(GTK_COLOR(args->targetColor), options->getColor("color", Color(0.5f))); auto hbox2 = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox2, false, false, 0); gtk_widget_show_all(hbox); args->update(); args->main = hbox; args->source.widget = hbox; return (ColorSource *)args; } int closest_colors_source_register(ColorSourceManager *csm) { ColorSource *color_source = new ColorSource; color_source_init(color_source, "closest_colors", _("Closest colors")); color_source->implement = source_implement; color_source->default_accelerator = GDK_KEY_c; color_source_manager_add_source(csm, color_source); return 0; } gpick-gpick-0.2.6/source/ClosestColors.h000066400000000000000000000033151377073231300201660ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_CLOSEST_COLORS_H_ #define GPICK_CLOSEST_COLORS_H_ struct ColorSourceManager; int closest_colors_source_register(ColorSourceManager *csm); #endif /* GPICK_CLOSEST_COLORS_H_ */ gpick-gpick-0.2.6/source/Color.cpp000066400000000000000000000512661377073231300170110ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Color.h" #include #include "MathUtil.h" #include using namespace std; // Constant used for lab->xyz transform. Should be calculated with maximum accuracy possible. #define EPSILON (216.0 / 24389.0) static vector3 references[][2] = { {{{{109.850, 100.000, 35.585}}}, {{{111.144, 100.000, 35.200}}}}, {{{{ 98.074, 100.000, 118.232}}}, {{{ 97.285, 100.000, 116.145}}}}, {{{{ 96.422, 100.000, 82.521}}}, {{{ 96.720, 100.000, 81.427}}}}, {{{{ 95.682, 100.000, 92.149}}}, {{{ 95.799, 100.000, 90.926}}}}, {{{{ 95.047, 100.000, 108.883}}}, {{{ 94.811, 100.000, 107.304}}}}, {{{{ 94.972, 100.000, 122.638}}}, {{{ 94.416, 100.000, 120.641}}}}, {{{{ 99.187, 100.000, 67.395}}}, {{{103.280, 100.000, 69.026}}}}, {{{{ 95.044, 100.000, 108.755}}}, {{{ 95.792, 100.000, 107.687}}}}, {{{{100.966, 100.000, 64.370}}}, {{{103.866, 100.000, 65.627}}}}, }; static matrix3x3 sRGB_transformation; static matrix3x3 sRGB_transformation_inverted; static matrix3x3 d65_d50_adaptation_matrix; static matrix3x3 d50_d65_adaptation_matrix; void color_init() { // constants used below are sRGB working space red, green and blue primaries for D65 reference white color_get_working_space_matrix(0.6400, 0.3300, 0.3000, 0.6000, 0.1500, 0.0600, color_get_reference(REFERENCE_ILLUMINANT_D65, REFERENCE_OBSERVER_2), &sRGB_transformation); matrix3x3_inverse(&sRGB_transformation, &sRGB_transformation_inverted); color_get_chromatic_adaptation_matrix(color_get_reference(REFERENCE_ILLUMINANT_D65, REFERENCE_OBSERVER_2), color_get_reference(REFERENCE_ILLUMINANT_D50, REFERENCE_OBSERVER_2), &d65_d50_adaptation_matrix); color_get_chromatic_adaptation_matrix(color_get_reference(REFERENCE_ILLUMINANT_D50, REFERENCE_OBSERVER_2), color_get_reference(REFERENCE_ILLUMINANT_D65, REFERENCE_OBSERVER_2), &d50_d65_adaptation_matrix); } Color::Color(): ma { 0, 0, 0, 0 } { } Color::Color(float grayValue): ma { grayValue, grayValue, grayValue, 0 } { } Color::Color(float red, float green, float blue): ma { red, green, blue, 0 } { } bool Color::operator==(const Color &color) const { return color_equal(this, &color); } void color_rgb_to_hsv(const Color* a, Color* b) { float min, max, delta; max = max_float_3(a->rgb.red, a->rgb.green, a->rgb.blue); min = min_float_3(a->rgb.red, a->rgb.green, a->rgb.blue); delta = max - min; b->hsv.value = max; if (max != 0.0f) b->hsv.saturation = delta / max; else b->hsv.saturation = 0.0f; if (b->hsv.saturation == 0.0f) { b->hsv.hue = 0.0f; } else { if (a->rgb.red == max) b->hsv.hue = (a->rgb.green - a->rgb.blue) / delta; else if (a->rgb.green == max) b->hsv.hue = 2.0f + (a->rgb.blue - a->rgb.red) / delta; else if (a->rgb.blue == max) b->hsv.hue = 4.0f + (a->rgb.red - a->rgb.green) / delta; b->hsv.hue /= 6.0f; if (b->hsv.hue < 0.0f) b->hsv.hue += 1.0f; if (b->hsv.hue >= 1.0f) b->hsv.hue -= 1.0f; } } void color_hsv_to_rgb(const Color* a, Color* b) { float h,v, f, x, y, z; int i; v = a->hsv.value; if (a->hsv.saturation == 0.0f) { b->rgb.red = b->rgb.green = b->rgb.blue = a->hsv.value; } else { h = (a->hsv.hue - floor(a->hsv.hue)) * 6.0f; i = int(h); f = h - floor(h); x = v * (1.0f - a->hsv.saturation) ; y = v * (1.0f - (a->hsv.saturation * f)); z = v * (1.0f - (a->hsv.saturation * (1.0f - f))); if (i == 0){ b->rgb.red = v; b->rgb.green = z; b->rgb.blue = x; }else if (i == 1){ b->rgb.red = y; b->rgb.green = v; b->rgb.blue = x; }else if (i == 2){ b->rgb.red = x; b->rgb.green = v; b->rgb.blue = z; }else if (i == 3){ b->rgb.red = x; b->rgb.green = y; b->rgb.blue = v; }else if (i == 4){ b->rgb.red = z; b->rgb.green = x; b->rgb.blue = v; }else{ b->rgb.red = v; b->rgb.green = x; b->rgb.blue = y; } } } void color_rgb_to_xyz(const Color* a, Color* b, const matrix3x3* transformation) { float R=a->rgb.red, G=a->rgb.green, B=a->rgb.blue; if (R>0.04045){ R=pow(((R+0.055)/1.055),2.4); }else{ R=R/12.92; } if (G>0.04045){ G=pow(((G+0.055)/1.055),2.4); }else{ G=G/12.92; } if (B>0.04045){ B=pow(((B+0.055)/1.055),2.4); }else{ B=B/12.92; } vector3 rgb; rgb.x = R; rgb.y = G; rgb.z = B; vector3_multiply_matrix3x3(&rgb, transformation, &rgb); b->xyz.x = rgb.x; b->xyz.y = rgb.y; b->xyz.z = rgb.z; } void color_xyz_to_rgb(const Color* a, Color* b, const matrix3x3* transformation_inverted) { vector3 rgb; float R,G,B; vector3_multiply_matrix3x3((vector3*)a, transformation_inverted, &rgb); R=rgb.x; G=rgb.y; B=rgb.z; if (R>0.0031308){ R=1.055*(pow(R,1/2.4f))-0.055; }else{ R=12.92*R; } if (G>0.0031308){ G=1.055*(pow(G,1/2.4f))-0.055; }else{ G=12.92*G; } if(B>0.0031308){ B=1.055*(pow(B,1/2.4f))-0.055; }else{ B=12.92*B; } b->rgb.red=R; b->rgb.green=G; b->rgb.blue=B; } void color_rgb_to_lab(const Color* a, Color* b, const vector3* reference_white, const matrix3x3* transformation, const matrix3x3* adaptation_matrix) { Color c; color_rgb_to_xyz(a, &c, transformation); color_xyz_chromatic_adaptation(&c, &c, adaptation_matrix); color_xyz_to_lab(&c, b, reference_white); } void color_lab_to_rgb(const Color* a, Color* b, const vector3* reference_white, const matrix3x3* transformation_inverted, const matrix3x3* adaptation_matrix_inverted) { Color c; color_lab_to_xyz(a, &c, reference_white); color_xyz_chromatic_adaptation(&c, &c, adaptation_matrix_inverted); color_xyz_to_rgb(&c, b, transformation_inverted); } void color_copy(const Color* a, Color* b) { b->m.m1 = a->m.m1; b->m.m2 = a->m.m2; b->m.m3 = a->m.m3; b->m.m4 = a->m.m4; } void color_add(Color* a, const Color* b) { a->m.m1 += b->m.m1; a->m.m2 += b->m.m2; a->m.m3 += b->m.m3; a->m.m4 += b->m.m4; } void color_multiply(Color* a, float b) { a->m.m1 *= b; a->m.m2 *= b; a->m.m3 *= b; a->m.m4 *= b; } void color_zero(Color* a) { a->m.m1 = 0; a->m.m2 = 0; a->m.m3 = 0; a->m.m4 = 0; } void color_get_contrasting(const Color* a, Color* b) { Color t; color_rgb_to_lab(a, &t, color_get_reference(REFERENCE_ILLUMINANT_D50, REFERENCE_OBSERVER_2), &sRGB_transformation, &d65_d50_adaptation_matrix); if (t.lab.L > 50){ t.hsv.value=0; }else{ t.hsv.value=1; } t.hsv.saturation=0; t.hsv.hue=0; color_hsv_to_rgb(&t, b); } void color_set(Color* a, float value) { a->rgb.red = a->rgb.green = a->rgb.blue = value; a->ma[3] = 0; } void color_set(Color* a, float red, float green, float blue) { a->rgb.red = red; a->rgb.green = green; a->rgb.blue = blue; a->ma[3] = 0; } void color_set(Color* a, int red, int green, int blue) { a->rgb.red = red / 255.0; a->rgb.green = green / 255.0; a->rgb.blue = blue / 255.0; a->ma[3] = 0; } Color* color_new() { return new Color; } void color_destroy(Color *a) { delete a; } void color_rgb_to_hsl(const Color* a, Color* b) { float min, max, delta; min = min_float_3(a->rgb.red, a->rgb.green, a->rgb.blue); max = max_float_3(a->rgb.red, a->rgb.green, a->rgb.blue); delta = max - min; b->hsl.lightness = (max + min) / 2; if (delta == 0) { b->hsl.hue = 0; b->hsl.saturation = 0; } else { if (b->hsl.lightness < 0.5) { b->hsl.saturation = delta / (max + min); } else { b->hsl.saturation = delta / (2 - max - min); } if (a->rgb.red == max) b->hsv.hue = (a->rgb.green - a->rgb.blue) / delta; else if (a->rgb.green == max) b->hsv.hue = 2.0f + (a->rgb.blue - a->rgb.red) / delta; else if (a->rgb.blue == max) b->hsv.hue = 4.0f + (a->rgb.red - a->rgb.green) / delta; b->hsv.hue /= 6.0f; if (b->hsv.hue < 0.0f) b->hsv.hue += 1.0f; if (b->hsv.hue >= 1.0f) b->hsv.hue -= 1.0f; } } void color_hsl_to_rgb(const Color* a, Color* b) { if (a->hsl.saturation == 0) { b->rgb.red = b->rgb.green = b->rgb.blue = a->hsl.lightness; } else { float q, p, R, G, B; if (a->hsl.lightness < 0.5) q = a->hsl.lightness * (1.0 + a->hsl.saturation); else q = a->hsl.lightness + a->hsl.saturation - a->hsl.lightness * a->hsl.saturation; p = 2 * a->hsl.lightness - q; R = a->hsl.hue+1/3.0; G = a->hsl.hue; B = a->hsl.hue-1/3.0; if (R>1) R-=1; if (B<0) B+=1; if (6.0 * R < 1) b->rgb.red = p + (q - p) * 6.0 * R; else if (2.0 * R < 1) b->rgb.red = q; else if (3.0 * R < 2) b->rgb.red = p + (q - p) * ((2.0 / 3.0) - R) * 6.0; else b->rgb.red = p; if (6.0 * G < 1) b->rgb.green = p + (q - p) * 6.0 * G; else if (2.0 * G < 1) b->rgb.green = q; else if (3.0 * G < 2) b->rgb.green = p + (q - p) * ((2.0 / 3.0) - G) * 6.0; else b->rgb.green = p; if (6.0 * B < 1) b->rgb.blue = p + (q - p) * 6.0 * B; else if (2.0 * B < 1) b->rgb.blue = q; else if (3.0 * B < 2) b->rgb.blue = p + (q - p) * ((2.0 / 3.0) - B) * 6.0; else b->rgb.blue = p; } } void color_lab_to_lch(const Color* a, Color* b) { double H; if (a->lab.a == 0 && a->lab.b == 0){ H = 0; }else{ H = atan2(a->lab.b, a->lab.a); } H *= 180.0 / PI; if (H < 0) H += 360; if (H >= 360) H -= 360; b->lch.L = a->lab.L; b->lch.C = sqrt(a->lab.a * a->lab.a + a->lab.b * a->lab.b); b->lch.h = H; } void color_lch_to_lab(const Color* a, Color* b) { b->lab.L = a->lch.L; b->lab.a = a->lch.C * cos(a->lch.h * PI / 180.0); b->lab.b = a->lch.C * sin(a->lch.h * PI / 180.0); } void color_rgb_to_lch_d50(const Color* a, Color* b) { Color c; color_rgb_to_lab(a, &c, color_get_reference(REFERENCE_ILLUMINANT_D50, REFERENCE_OBSERVER_2), &sRGB_transformation, &d65_d50_adaptation_matrix); color_lab_to_lch(&c, b); } void color_lch_to_rgb_d50(const Color* a, Color* b) { Color c; color_lch_to_lab(a, &c); color_lab_to_rgb(&c, b, color_get_reference(REFERENCE_ILLUMINANT_D50, REFERENCE_OBSERVER_2), &sRGB_transformation_inverted, &d50_d65_adaptation_matrix); } void color_rgb_to_lch(const Color* a, Color* b, const vector3* reference_white, const matrix3x3* transformation, const matrix3x3* adaptation_matrix) { Color c; color_rgb_to_lab(a, &c, reference_white, transformation, adaptation_matrix); color_lab_to_lch(&c, b); } void color_lch_to_rgb(const Color* a, Color* b, const vector3* reference_white, const matrix3x3* transformation_inverted, const matrix3x3* adaptation_matrix_inverted) { Color c; color_lch_to_lab(a, &c); color_lab_to_rgb(&c, b, reference_white, transformation_inverted, adaptation_matrix_inverted); } void color_rgb_to_lab_d50(const Color* a, Color* b) { color_rgb_to_lab(a, b, color_get_reference(REFERENCE_ILLUMINANT_D50, REFERENCE_OBSERVER_2), &sRGB_transformation, &d65_d50_adaptation_matrix); } void color_lab_to_rgb_d50(const Color* a, Color* b) { color_lab_to_rgb(a, b, color_get_reference(REFERENCE_ILLUMINANT_D50, REFERENCE_OBSERVER_2), &sRGB_transformation_inverted, &d50_d65_adaptation_matrix); } #define Kk (24389.0 / 27.0) void color_xyz_to_lab(const Color* a, Color* b, const vector3* reference_white) { float X,Y,Z; X = a->xyz.x / reference_white->x; //95.047f; Y = a->xyz.y / reference_white->y; //100.000f; Z = a->xyz.z / reference_white->z; //108.883f; if (X>EPSILON){ X=pow(X,1.0f/3.0f); }else{ X=(Kk*X+16.0f)/116.0f; } if (Y>EPSILON){ Y=pow(Y,1.0f/3.0f); }else{ Y=(Kk*Y+16.0f)/116.0f; } if (Z>EPSILON){ Z=pow(Z,1.0f/3.0f); }else{ Z=(Kk*Z+16.0f)/116.0f; } b->lab.L=(116*Y)-16; b->lab.a=500*(X-Y); b->lab.b=200*(Y-Z); } void color_lab_to_xyz(const Color* a, Color* b, const vector3* reference_white) { float x, y, z; float fy = (a->lab.L + 16) / 116; float fx = a->lab.a / 500 + fy; float fz = fy - a->lab.b / 200; const double K=(24389.0 / 27.0); if (pow(fx, 3)>EPSILON){ x=pow(fx, 3); }else{ x=(116*fx-16)/K; } if (a->lab.L > K*EPSILON){ y=pow((a->lab.L+16)/116, 3); }else{ y=a->lab.L/K; } if (pow(fz, 3)>EPSILON){ z=pow(fz, 3); }else{ z=(116*fz-16)/K; } b->xyz.x = x * reference_white->x; //95.047f; b->xyz.y = y * reference_white->y; //100.000f; b->xyz.z = z * reference_white->z; //108.883f; } void color_get_working_space_matrix(float xr, float yr, float xg, float yg, float xb, float yb, const vector3* reference_white, matrix3x3* result) { float Xr,Yr,Zr; float Xg,Yg,Zg; float Xb,Yb,Zb; Xr=xr/yr; Yr=1; Zr=(1-xr-yr)/yr; Xg=xg/yg; Yg=1; Zg=(1-xg-yg)/yg; Xb=xb/yb; Yb=1; Zb=(1-xb-yb)/yb; vector3 v; v.x=reference_white->x; v.y=reference_white->y; v.z=reference_white->z; matrix3x3 m_inv; m_inv.m[0][0]=Xr; m_inv.m[1][0]=Yr; m_inv.m[2][0]=Zr; m_inv.m[0][1]=Xg; m_inv.m[1][1]=Yg; m_inv.m[2][1]=Zg; m_inv.m[0][2]=Xb; m_inv.m[1][2]=Yb; m_inv.m[2][2]=Zb; matrix3x3_inverse(&m_inv, &m_inv); vector3_multiply_matrix3x3(&v, &m_inv, &v); result->m[0][0]=Xr*v.x; result->m[1][0]=Yr*v.x; result->m[2][0]=Zr*v.x; result->m[0][1]=Xg*v.y; result->m[1][1]=Yg*v.y; result->m[2][1]=Zg*v.y; result->m[0][2]=Xb*v.z; result->m[1][2]=Yb*v.z; result->m[2][2]=Zb*v.z; } void color_get_chromatic_adaptation_matrix(const vector3* source_reference_white, const vector3* destination_reference_white, matrix3x3* result) { matrix3x3 Ma; //Bradford matrix Ma.m[0][0]= 0.8951; Ma.m[1][0]=-0.7502; Ma.m[2][0]= 0.0389; Ma.m[0][1]= 0.2664; Ma.m[1][1]= 1.7135; Ma.m[2][1]=-0.0685; Ma.m[0][2]=-0.1614; Ma.m[1][2]= 0.0367; Ma.m[2][2]= 1.0296; matrix3x3 Ma_inv; //Bradford inverted matrix Ma_inv.m[0][0]= 0.986993; Ma_inv.m[1][0]= 0.432305; Ma_inv.m[2][0]=-0.008529; Ma_inv.m[0][1]=-0.147054; Ma_inv.m[1][1]= 0.518360; Ma_inv.m[2][1]= 0.040043; Ma_inv.m[0][2]= 0.159963; Ma_inv.m[1][2]= 0.049291; Ma_inv.m[2][2]= 0.968487; vector3 Vs, Vd; vector3_multiply_matrix3x3(source_reference_white, &Ma, &Vs); vector3_multiply_matrix3x3(destination_reference_white, &Ma, &Vd); matrix3x3 M; matrix3x3_identity(&M); M.m[0][0]=Vd.x / Vs.x; M.m[1][1]=Vd.y / Vs.y; M.m[2][2]=Vd.z / Vs.z; matrix3x3_multiply(&Ma, &M, &M); matrix3x3_multiply(&M, &Ma_inv, result); } void color_xyz_chromatic_adaptation(const Color* a, Color* result, const matrix3x3* adaptation) { vector3 x; x.x=a->xyz.x; x.y=a->xyz.y; x.z=a->xyz.z; vector3_multiply_matrix3x3(&x, adaptation, &x); result->xyz.x=x.x; result->xyz.y=x.y; result->xyz.z=x.z; } void color_rgb_to_cmy(const Color* a, Color* b) { b->cmy.c = 1 - a->rgb.red; b->cmy.m = 1 - a->rgb.green; b->cmy.y = 1 - a->rgb.blue; } void color_cmy_to_rgb(const Color* a, Color* b) { b->rgb.red = 1 - a->cmy.c; b->rgb.green = 1 - a->cmy.m; b->rgb.blue = 1 - a->cmy.y; } void color_cmy_to_cmyk(const Color* a, Color* b) { float k = 1; if (a->cmy.c < k) k = a->cmy.c; if (a->cmy.m < k) k = a->cmy.m; if (a->cmy.y < k) k = a->cmy.y; if (k == 1){ b->cmyk.c = b->cmyk.m = b->cmyk.y = 0; }else{ b->cmyk.c = (a->cmy.c - k) / (1 - k); b->cmyk.m = (a->cmy.m - k) / (1 - k); b->cmyk.y = (a->cmy.y - k) / (1 - k); } b->cmyk.k = k; } void color_cmyk_to_cmy(const Color* a, Color* b) { b->cmy.c = (a->cmyk.c * (1 - a->cmyk.k) + a->cmyk.k); b->cmy.m = (a->cmyk.m * (1 - a->cmyk.k) + a->cmyk.k); b->cmy.y = (a->cmyk.y * (1 - a->cmyk.k) + a->cmyk.k); } void color_rgb_to_cmyk(const Color* a, Color* b) { Color c; color_rgb_to_cmy(a, &c); color_cmy_to_cmyk(&c, b); } void color_cmyk_to_rgb(const Color* a, Color* b) { Color c; color_cmyk_to_cmy(a, &c); color_cmy_to_rgb(&c, b); } void color_rgb_normalize(Color* a) { a->rgb.red = clamp_float(a->rgb.red, 0, 1); a->rgb.green = clamp_float(a->rgb.green, 0, 1); a->rgb.blue = clamp_float(a->rgb.blue, 0, 1); a->ma[3] = clamp_float(a->ma[3], 0, 1); } void color_hsl_to_hsv(const Color *a, Color *b) { float l = a->hsl.lightness * 2.0; float s = a->hsl.saturation * ((l <= 1.0) ? (l) : (2.0 - l)); b->hsv.hue = a->hsl.hue; if (l + s == 0){ b->hsv.value = 0; b->hsv.saturation = 1; }else{ b->hsv.value = (l + s) / 2.0; b->hsv.saturation = (2.0 * s) / (l + s); } } void color_hsv_to_hsl(const Color *a, Color *b) { float l = (2.0 - a->hsv.saturation) * a->hsv.value; float s = (a->hsv.saturation * a->hsv.value) / ((l <= 1.0) ? (l) : (2 - l)); if (l == 0) s = 0; b->hsl.hue = a->hsv.hue; b->hsl.saturation = s; b->hsl.lightness = l / 2.0; } void color_rgb_get_linear(const Color* a, Color* b) { if (a->rgb.red > 0.04045f) b->rgb.red = pow((a->rgb.red + 0.055f) / 1.055f, 2.4f); else b->rgb.red = a->rgb.red / 12.92f; if (a->rgb.green > 0.04045f) b->rgb.green = pow((a->rgb.green + 0.055f) / 1.055f, 2.4f); else b->rgb.green = a->rgb.green / 12.92f; if (a->rgb.blue > 0.04045f) b->rgb.blue = pow((a->rgb.blue + 0.055f) / 1.055f, 2.4f); else b->rgb.blue = a->rgb.blue / 12.92f; } void color_linear_get_rgb(const Color* a, Color* b) { if (a->rgb.red > 0.0031308f) b->rgb.red = (1.055f * pow(a->rgb.red, 1.0f / 2.4f)) - 0.055f; else b->rgb.red = a->rgb.red * 12.92f; if (a->rgb.green > 0.0031308f) b->rgb.green = (1.055f * pow(a->rgb.green, 1.0f / 2.4f)) - 0.055f; else b->rgb.green = a->rgb.green * 12.92f; if (a->rgb.blue > 0.0031308f) b->rgb.blue = (1.055f * pow(a->rgb.blue, 1.0f / 2.4f)) - 0.055f; else b->rgb.blue = a->rgb.blue * 12.92f; } const matrix3x3* color_get_sRGB_transformation_matrix() { return &sRGB_transformation; } const matrix3x3* color_get_inverted_sRGB_transformation_matrix() { return &sRGB_transformation_inverted; } const matrix3x3* color_get_d65_d50_adaptation_matrix() { return &d65_d50_adaptation_matrix; } const matrix3x3* color_get_d50_d65_adaptation_matrix() { return &d50_d65_adaptation_matrix; } const vector3* color_get_reference(ReferenceIlluminant illuminant, ReferenceObserver observer) { return &references[illuminant][observer]; } const ReferenceIlluminant color_get_illuminant(const std::string &illuminant) { const struct { const char *label; ReferenceIlluminant illuminant; } illuminants[] = { {"A", REFERENCE_ILLUMINANT_A}, {"C", REFERENCE_ILLUMINANT_C}, {"D50", REFERENCE_ILLUMINANT_D50}, {"D55", REFERENCE_ILLUMINANT_D55}, {"D65", REFERENCE_ILLUMINANT_D65}, {"D75", REFERENCE_ILLUMINANT_D75}, {"F2", REFERENCE_ILLUMINANT_F2}, {"F7", REFERENCE_ILLUMINANT_F7}, {"F11", REFERENCE_ILLUMINANT_F11}, {0, REFERENCE_ILLUMINANT_D50}, }; for (int i = 0; illuminants[i].label; i++) { if (illuminants[i].label == illuminant) { return illuminants[i].illuminant; } } return REFERENCE_ILLUMINANT_D50; }; const ReferenceObserver color_get_observer(const std::string &observer) { const struct { const char *label; ReferenceObserver observer; } observers[] = { {"2", REFERENCE_OBSERVER_2}, {"10", REFERENCE_OBSERVER_10}, {0, REFERENCE_OBSERVER_2}, }; for (int i = 0; observers[i].label; i++) { if (observers[i].label == observer) { return observers[i].observer; } } return REFERENCE_OBSERVER_2; } bool color_is_rgb_out_of_gamut(const Color* a) { if (a->rgb.red < 0 || a->rgb.red > 1) return true; if (a->rgb.green < 0 || a->rgb.green > 1) return true; if (a->rgb.blue < 0 || a->rgb.blue > 1) return true; return false; } float color_distance(const Color* a, const Color* b) { Color al, bl; color_rgb_get_linear(a, &al); color_rgb_get_linear(b, &bl); return sqrt( pow(bl.rgb.red - al.rgb.red, 2) + pow(bl.rgb.green - al.rgb.green, 2) + pow(bl.rgb.blue - al.rgb.blue, 2) ); } float color_distance_lch(const Color* a, const Color* b) { Color al, bl; color_lab_to_lch(a, &al); color_lab_to_lch(b, &bl); return sqrt( pow((bl.lch.L - al.lch.L) / 1, 2) + pow((bl.lch.C - al.lch.C) / (1 + 0.045 * al.lch.C), 2) + pow((pow(a->lab.a - b->lab.a, 2) + pow(a->lab.b - b->lab.b, 2) - (bl.lch.C - al.lch.C)) / (1 + 0.015 * al.lch.C), 2) ); } bool color_equal(const Color* a, const Color* b) { for (int i = 0; i < 4; i++){ if (abs_float(a->ma[i] - b->ma[i]) > 1e-6) return false; } return true; } gpick-gpick-0.2.6/source/Color.h000066400000000000000000000411761377073231300164550ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_COLOR_H_ #define GPICK_COLOR_H_ #include "MathUtil.h" #include /** \file source/Color.h * \brief Color structure and functions to convert colors from one color space to another. */ /** \struct Color * \brief Color structure is an union of all available color spaces. */ struct Color { Color(); Color(float grayValue); Color(float red, float green, float blue); bool operator==(const Color &color) const; union{ struct{ float red; /**< Red component */ float green; /**< Green component */ float blue; /**< Blue component */ }rgb; struct{ float hue; float saturation; float value; }hsv; struct{ float hue; float saturation; float lightness; }hsl; struct{ float x; float y; float z; }xyz; struct{ float L; float a; float b; }lab; struct{ float L; float C; float h; }lch; struct{ float c; float m; float y; }cmy; struct{ float c; float m; float y; float k; }cmyk; struct{ float m1; float m2; float m3; float m4; }m; /**< General data access structure */ float ma[4]; /**< General data access array */ }; }; /** \enum ReferenceIlluminant * \brief Reference illuminants. */ enum ReferenceIlluminant { REFERENCE_ILLUMINANT_A = 0, REFERENCE_ILLUMINANT_C = 1, REFERENCE_ILLUMINANT_D50 = 2, REFERENCE_ILLUMINANT_D55 = 3, REFERENCE_ILLUMINANT_D65 = 4, REFERENCE_ILLUMINANT_D75 = 5, REFERENCE_ILLUMINANT_F2 = 6, REFERENCE_ILLUMINANT_F7 = 7, REFERENCE_ILLUMINANT_F11 = 8, }; /** \enum ReferenceObserver * \brief Reference observers. */ enum ReferenceObserver { REFERENCE_OBSERVER_2 = 0, REFERENCE_OBSERVER_10 = 1, }; /** * Initialize things needed for color conversion functions. Must be called before using any other functions. */ void color_init(); /** * Convert RGB color space to HSL color space. * @param[in] a Source color in RGB color space. * @param[out] b Destination color in HSL color space. */ void color_rgb_to_hsl(const Color* a, Color* b); /** * Convert HSL color space to RGB color space. * @param[in] a Source color in HSL color space. * @param[out] b Destination color in RGB color space. */ void color_hsl_to_rgb(const Color* a, Color* b); /** * Convert HSL color space to HSV color space. * @param[in] a Source color in HSL color space. * @param[out] b Destination color in HSV color space. */ void color_hsl_to_hsv(const Color *a, Color *b); /** * Convert HSV color space to HSL color space. * @param[in] a Source color in HSV color space. * @param[out] b Destination color in HSL color space. */ void color_hsv_to_hsl(const Color *a, Color *b); /** * Convert RGB color space to HSV color space. * @param[in] a Source color in RGB color space. * @param[out] b Destination color in HSV color space. */ void color_rgb_to_hsv(const Color* a, Color* b); /** * Convert HSV color space to RGB color space. * @param[in] a Source color in HSV color space. * @param[out] b Destination color in RGB color space. */ void color_hsv_to_rgb(const Color* a, Color* b); /** * Convert RGB color space to XYZ color space. * @param[in] a Source color in RGB color space. * @param[out] b Destination color in XYZ color space. * @param[in] transformation Transformation matrix for RGB to XYZ conversion. */ void color_rgb_to_xyz(const Color* a, Color* b, const matrix3x3* transformation); /** * Convert XYZ color space to RGB color space. * @param[in] a Source color in XYZ color space. * @param[out] b Destination color in RGB color space. * @param[in] transformation_inverted Transformation matrix for XYZ to RGB conversion. */ void color_xyz_to_rgb(const Color* a, Color* b, const matrix3x3* transformation_inverted); /** * Convert XYZ color space to Lab color space. * @param[in] a Source color in XYZ color space. * @param[out] b Destination color in Lab color space. * @param[in] reference_white Reference white color values. */ void color_xyz_to_lab(const Color* a, Color* b, const vector3* reference_white); /** * Convert Lab color space to XYZ color space. * @param[in] a Source color in Lab color space. * @param[out] b Destination color in XYZ color space. * @param[in] reference_white Reference white color values. */ void color_lab_to_xyz(const Color* a, Color* b, const vector3* reference_white); /** * Convert RGB color space to Lab color space. * @param[in] a Source color in RGB color space. * @param[out] b Destination color in Lab color space. * @param[in] reference_white Reference white color values. * @param[in] transformation Transformation matrix for RGB to XYZ conversion. * @param[in] adaptation_matrix XYZ chromatic adaptation matrix. */ void color_rgb_to_lab(const Color* a, Color* b, const vector3* reference_white, const matrix3x3* transformation, const matrix3x3* adaptation_matrix); /** * Convert Lab color space to RGB color space. * @param[in] a Source color in Lab color space. * @param[out] b Destination color in RGB color space. * @param[in] reference_white Reference white color values. * @param[in] transformation_inverted Transformation matrix for XYZ to RGB conversion. * @param[in] adaptation_matrix_inverted Inverted XYZ chromatic adaptation matrix. */ void color_lab_to_rgb(const Color* a, Color* b, const vector3* reference_white, const matrix3x3* transformation_inverted, const matrix3x3* adaptation_matrix_inverted); /** * Convert RGB color space to Lab color space with illuminant D50, observer 2, sRGB transformation matrix and D65-D50 adaptation matrix. * @param[in] a Source color in RGB color space. * @param[out] b Destination color in Lab color space. */ void color_rgb_to_lab_d50(const Color* a, Color* b); /** * Convert Lab color space to RGB color space with illuminant D50, observer 2, inverted sRGB transformation matrix and D50-D65 adaptation matrix. * @param[in] a Source color in Lab color space. * @param[out] b Destination color in RGB color space. */ void color_lab_to_rgb_d50(const Color* a, Color* b); /** * Convert Lab color space to LCH color space. * @param[in] a Source color in Lab color space. * @param[out] b Destination color in LCH color space. */ void color_lab_to_lch(const Color* a, Color* b); /** * Convert Lab color space to LCH color space. * @param[in] a Source color in Lab color space. * @param[out] b Destination color in LCH color space. */ void color_lch_to_lab(const Color* a, Color* b); /** * Convert RGB color space to LCH color space. * @param[in] a Source color in RGB color space. * @param[out] b Destination color in LCH color space. * @param[in] reference_white Reference white color values. * @param[in] transformation Transformation matrix for RGB to XYZ conversion. * @param[in] adaptation_matrix XYZ chromatic adaptation matrix. */ void color_rgb_to_lch(const Color* a, Color* b, const vector3* reference_white, const matrix3x3* transformation, const matrix3x3* adaptation_matrix); /** * Convert LCH color space to RGB color space. * @param[in] a Source color in LCH color space. * @param[out] b Destination color in RGB color space. * @param[in] reference_white Reference white color values. * @param[in] transformation_inverted Transformation matrix for XYZ to RGB conversion. * @param[in] adaptation_matrix_inverted Inverted XYZ chromatic adaptation matrix. */ void color_lch_to_rgb(const Color* a, Color* b, const vector3* reference_white, const matrix3x3* transformation_inverted, const matrix3x3* adaptation_matrix_inverted); /** * Convert RGB color space to LCH color space with illuminant D50, observer 2, sRGB transformation matrix and D65-D50 adaptation matrix. * @param[in] a Source color in RGB color space. * @param[out] b Destination color in LCH color space. */ void color_rgb_to_lch_d50(const Color* a, Color* b); /** * Convert LCH color space to RGB color space with illuminant D50, observer 2, inverted sRGB transformation matrix and D50-D65 adaptation matrix. * @param[in] a Source color in LCH color space. * @param[out] b Destination color in RGB color space. */ void color_lch_to_rgb_d50(const Color* a, Color* b); /** * Convert RGB color space to CMY color space. * @param[in] a Source color in RGB color space. * @param[out] b Destination color in CMY color space. */ void color_rgb_to_cmy(const Color* a, Color* b); /** * Convert CMY color space to RGB color space. * @param[in] a Source color in CMY color space. * @param[out] b Destination color in RGB color space. */ void color_cmy_to_rgb(const Color* a, Color* b); /** * Convert CMY color space to CMYK color space. * @param[in] a Source color in CMY color space. * @param[out] b Destination color in CMYK color space. */ void color_cmy_to_cmyk(const Color* a, Color* b); /** * Convert CMYK color space to CMY color space. * @param[in] a Source color in CMYK color space. * @param[out] b Destination color in CMY color space. */ void color_cmyk_to_cmy(const Color* a, Color* b); /** * Convert RGB color space to CMYK color space. * @param[in] a Source color in RGB color space. * @param[out] b Destination color in CMYK color space. */ void color_rgb_to_cmyk(const Color* a, Color* b); /** * Convert CMYK color space to RGB color space. * @param[in] a Source color in CMYK color space. * @param[out] b Destination color in RGB color space. */ void color_cmyk_to_rgb(const Color* a, Color* b); /** * Normalize RGB color values. * @param[in,out] a Color in RGB color space. */ void color_rgb_normalize(Color* a); /** * Check whenever the color contains invalid (out of RGB gamut) value. * @param[in] a Color in RGB color space. * @return True, when color is out of RGB gamut. */ bool color_is_rgb_out_of_gamut(const Color* a); /** * Transform RGB color to linear RGB color. * @param[in] a Color in RGB color space. * @param[out] b Linear color in RGB color space. */ void color_rgb_get_linear(const Color* a, Color* b); /** * Transform linear RGB color to RGB color. * @param[in] a Linear color in RGB color space. * @param[out] b Color in RGB color space. */ void color_linear_get_rgb(const Color* a, Color* b); /** * Copy color. * @param[in] a Source color in any color space. * @param[out] b Destination color. */ void color_copy(const Color* a, Color* b); /** * Add color values. * @param[in,out] a Source color in any color space. * @param[in] b Color values. */ void color_add(Color* a, const Color* b); /** * Multiply color values by specified amount. * @param[in,out] a Source color in any color space. * @param[in] b Multiplier. */ void color_multiply(Color* a, float b); /** * Set all color values to zero. * @param[in,out] a Color to be set. */ void color_zero(Color* a); /** * Create new Color structure. * @return Color structure with unspecified values. */ Color* color_new(); /** * Free memory associated with Color structure. * @param[in] a Color to be freed. */ void color_destroy(Color* a); /** * Set all color values to specified value. * @param[in,out] a Color to be set. * @param[in] value Value which is used. */ void color_set(Color* a, float value); /** * Set color values to specified values. * @param[in,out] a Color to be set. * @param[in] red Red value which is used. * @param[in] green Green value which is used. * @param[in] blue Blue value which is used. */ void color_set(Color* a, float red, float green, float blue); /** * Set color values to specified values. * @param[in,out] a Color to be set. * @param[in] red Red value which is used. * @param[in] green Green value which is used. * @param[in] blue Blue value which is used. */ void color_set(Color* a, int red, int green, int blue); /** * Get either black or white color depending on which has more contrast with specified color. * @param[in] a Source color in RGB color space. * @param[out] b Color with most contrast in RGB color space. */ void color_get_contrasting(const Color* a, Color* b); /** * Calculate working space matrix. * @param[in] xr Red primary in x channel. * @param[in] yr Red primary in y channel. * @param[in] xg Green primary in x channel. * @param[in] yg Green primary in y channel. * @param[in] xb Blue primary in x channel. * @param[in] yb Blue primary in y channel. * @param[in] reference_white Reference white vector. * @param[out] result Calculated working space matrix. */ void color_get_working_space_matrix(float xr, float yr, float xg, float yg, float xb, float yb, const vector3* reference_white, matrix3x3* result); /** * Calculate chromatic adaptation matrix from source and destination reference white vectors. * @param[in] source_reference_white Source reference white vector. * @param[in] destination_reference_white Destination reference white vector. * @param[out] result Calculated chromatic adaptation matrix. */ void color_get_chromatic_adaptation_matrix(const vector3* source_reference_white, const vector3* destination_reference_white, matrix3x3* result); /** * Apply chromatic adaptation matrix to the XYZ color. * @param[in] a Source color in XYZ color space. * @param[out] result Pointer to a Color structure where the result is stored in XYZ color space. * @param[in] adaptation Chromatic adaptation matrix. * @see color_get_chromatic_adaptation_matrix. */ void color_xyz_chromatic_adaptation(const Color* a, Color* result, const matrix3x3* adaptation); /** * Get working space matrix for sRGB. * @return Constant reference to sRGB working space matrix. */ const matrix3x3* color_get_sRGB_transformation_matrix(); /** * Get inverted working space matrix for sRGB. * @return Constant reference to inverted sRGB working space matrix. */ const matrix3x3* color_get_inverted_sRGB_transformation_matrix(); /** * Get D65 to D50 chromatic adaptation matrix. * @return Constant reference to chromatic adaptation matrix. */ const matrix3x3* color_get_d65_d50_adaptation_matrix(); /** * Get D50 to D65 chromatic adaptation matrix. * @return Constant reference to chromatic adaptation matrix. */ const matrix3x3* color_get_d50_d65_adaptation_matrix(); /** * Get reference white vector for specified illuminant and observer. * @param[in] illuminant Illuminant. * @param[in] observer Observer. * @return Reference white vector. */ const vector3* color_get_reference(ReferenceIlluminant illuminant, ReferenceObserver observer); /** * Get illuminant by name. * @param[in] illuminant Illuminant name. * @return Reference illuminant. */ const ReferenceIlluminant color_get_illuminant(const char *illuminant); const ReferenceIlluminant color_get_illuminant(const std::string &illuminant); /** * Get observer by name. * @param[in] observer Observer name. * @return Reference observer. */ const ReferenceObserver color_get_observer(const char *observer); const ReferenceObserver color_get_observer(const std::string &observer); /** * Get distance between two colors. * @param[in] a First color. * @param[in] b Second color. * @return Distance. */ float color_distance(const Color* a, const Color* b); /** * Get distance between two colors using CIE94 color difference calculation. * @param[in] a First color. * @param[in] b Second color. * @return Distance. */ float color_distance_lch(const Color* a, const Color* b); /** * Check if colors are equal. * @param[in] a First color. * @param[in] b Second color. * @return Equality. */ bool color_equal(const Color* a, const Color* b); #endif /* GPICK_COLOR_H_ */ gpick-gpick-0.2.6/source/ColorList.cpp000066400000000000000000000130671377073231300176420ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ColorList.h" #include "ColorObject.h" #include using namespace std; ColorList* color_list_new() { ColorList* color_list = new ColorList; color_list->on_insert = nullptr; color_list->on_change = nullptr; color_list->on_delete = nullptr; color_list->on_clear = nullptr; color_list->on_delete_selected = nullptr; color_list->on_get_positions = nullptr; color_list->userdata = nullptr; return color_list; } ColorList* color_list_new(ColorList *color_list) { ColorList *result = color_list_new(); if (color_list) result->options = dynv::Map::create(); return result; } ColorList* color_list_new_with_one_color(ColorList *template_color_list, const Color *color) { ColorList *color_list = color_list_new(); ColorObject *color_object = new ColorObject("", *color); color_list_add_color_object(color_list, color_object, 1); return color_list; } void color_list_destroy(ColorList* color_list) { for (auto color_object: color_list->colors){ color_object->release(); } color_list->colors.clear(); delete color_list; } ColorObject* color_list_new_color_object(ColorList* color_list, const Color *color) { return new ColorObject("", *color); } ColorObject* color_list_add_color(ColorList *color_list, const Color *color) { ColorObject *color_object = new ColorObject("", *color); int r = color_list_add_color_object(color_list, color_object, 1); if (r == 0){ color_object->release(); return color_object; }else{ delete color_object; return 0; } } int color_list_add_color_object(ColorList *color_list, ColorObject *color_object, bool add_to_palette) { color_list->colors.push_back(color_object->reference()); if (add_to_palette && color_list->on_insert) color_list->on_insert(color_list, color_object); return 0; } int color_list_add_color_object(ColorList *color_list, const ColorObject &colorObject, bool add_to_palette) { ColorObject *reference; color_list->colors.push_back((reference = colorObject.copy())); if (add_to_palette && color_list->on_insert) color_list->on_insert(color_list, reference); return 0; } int color_list_add(ColorList *color_list, ColorList *items, bool add_to_palette) { for (auto color_object: items->colors){ color_list->colors.push_back(color_object->reference()); if (add_to_palette && color_list->on_insert && color_object->isVisible()) color_list->on_insert(color_list, color_object); } return 0; } int color_list_remove_color_object(ColorList *color_list, ColorObject *color_object) { list::iterator i = std::find(color_list->colors.begin(), color_list->colors.end(), color_object); if (i != color_list->colors.end()){ if (color_list->on_delete) color_list->on_delete(color_list, color_object); color_list->colors.erase(i); color_object->release(); return 0; }else return -1; } int color_list_remove_selected(ColorList *color_list) { ColorList::iter i=color_list->colors.begin(); while (i != color_list->colors.end()){ if ((*i)->isSelected()){ (*i)->release(); i = color_list->colors.erase(i); }else ++i; } color_list->on_delete_selected(color_list); return 0; } int color_list_set_selected(ColorList *color_list, bool selected) { for (auto &color : color_list->colors) color->setSelected(false); return 0; } int color_list_remove_all(ColorList *color_list) { ColorList::iter i; if (color_list->on_clear){ color_list->on_clear(color_list); for (i = color_list->colors.begin(); i != color_list->colors.end(); ++i){ (*i)->release(); } }else{ for (i = color_list->colors.begin(); i != color_list->colors.end(); ++i){ if (color_list->on_delete) color_list->on_delete(color_list, *i); (*i)->release(); } } color_list->colors.clear(); return 0; } size_t color_list_get_count(ColorList *color_list) { return color_list->colors.size(); } int color_list_get_positions(ColorList *color_list) { if (color_list->on_get_positions){ for (auto color: color_list->colors){ color->resetPosition(); } color_list->on_get_positions(color_list); }else{ size_t position = 0; for (auto color: color_list->colors){ color->setPosition(position++); } } return 0; } gpick-gpick-0.2.6/source/ColorList.h000066400000000000000000000063061377073231300173050ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_COLOR_LIST_H_ #define GPICK_COLOR_LIST_H_ #include "Color.h" #include "dynv/Map.h" #include #include struct ColorObject; struct ColorList { std::list colors; typedef std::list::iterator iter; dynv::Ref options; int (*on_insert)(ColorList *color_list, ColorObject *color_object); int (*on_delete)(ColorList *color_list, ColorObject *color_object); int (*on_delete_selected)(ColorList *color_list); int (*on_change)(ColorList *color_list, ColorObject *color_object); int (*on_clear)(ColorList *color_list); int (*on_get_positions)(ColorList *color_list); void* userdata; }; ColorList* color_list_new(); ColorList* color_list_new(ColorList *color_list); ColorList* color_list_new_with_one_color(ColorList *template_color_list, const Color *color); void color_list_destroy(ColorList *color_list); ColorObject* color_list_new_color_object(ColorList *color_list, const Color *color); ColorObject* color_list_add_color(ColorList *color_list, const Color *color); int color_list_add_color_object(ColorList *color_list, ColorObject *color_object, bool add_to_palette); int color_list_add_color_object(ColorList *color_list, const ColorObject &colorObject, bool add_to_palette); int color_list_add(ColorList *color_list, ColorList *items, bool add_to_palette); int color_list_remove_color_object(ColorList *color_list, ColorObject *color_object); int color_list_remove_selected(ColorList *color_list); int color_list_set_selected(ColorList *color_list, bool selected); int color_list_remove_all(ColorList *color_list); size_t color_list_get_count(ColorList *color_list); int color_list_get_positions(ColorList *color_list); #endif /* GPICK_COLOR_LIST_H_ */ gpick-gpick-0.2.6/source/ColorMixer.cpp000066400000000000000000000411741377073231300200130ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ColorMixer.h" #include "ColorObject.h" #include "ColorSource.h" #include "ColorSourceManager.h" #include "DragDrop.h" #include "GlobalState.h" #include "ToolColorNaming.h" #include "uiUtilities.h" #include "ColorList.h" #include "MathUtil.h" #include "gtk/ColorWidget.h" #include "dynv/Map.h" #include "I18N.h" #include "color_names/ColorNames.h" #include "StandardEventHandler.h" #include "IMenuExtension.h" #include "common/Format.h" #include #include #include const int Rows = 5; enum class Mode { normal = 1, multiply, difference, add, hue, saturation, lightness, }; struct Type { const char *id; const char *name; Mode mode; }; const Type types[] = { { "normal", N_("Normal"), Mode::normal }, { "multiply", N_("Multiply"), Mode::multiply }, { "add", N_("Add"), Mode::add }, { "difference", N_("Difference"), Mode::difference }, { "hue", N_("Hue"), Mode::hue }, { "saturation", N_("Saturation"), Mode::saturation }, { "lightness", N_("Lightness"), Mode::lightness }, }; struct ColorMixerColorNameAssigner: public ToolColorNameAssigner { ColorMixerColorNameAssigner(GlobalState *gs): ToolColorNameAssigner(gs) { } void assign(ColorObject *colorObject, const Color *color, const char *ident) { m_ident = ident; ToolColorNameAssigner::assign(colorObject, color); } virtual std::string getToolSpecificName(ColorObject *colorObject, const Color *color) { m_stream.str(""); m_stream << color_names_get(m_gs->getColorNames(), color, false) << " " << _("color mixer") << " " << m_ident; return m_stream.str(); } protected: std::stringstream m_stream; const char *m_ident; }; struct ColorMixerArgs; struct ColorMixerArgs { ColorSource source; GtkWidget *main, *statusBar, *secondaryColor, *opacityRange, *lastFocusedColor, *colorPreviews; const Type *mixerType; struct { GtkWidget *input; GtkWidget *output; } rows[Rows]; dynv::Ref options; GlobalState *gs; void addToPalette() { color_list_add_color_object(gs->getColorList(), getColor(), true); } void addToPalette(ColorMixerColorNameAssigner &nameAssigner, Color &color, GtkWidget *widget) { gtk_color_get_color(GTK_COLOR(widget), &color); colorObject.setColor(color); auto widgetName = identifyColorWidget(widget); nameAssigner.assign(&colorObject, &color, widgetName.c_str()); color_list_add_color_object(gs->getColorList(), colorObject, true); } void addAllToPalette() { ColorMixerColorNameAssigner nameAssigner(gs); Color color; for (int i = 0; i < Rows; ++i) addToPalette(nameAssigner, color, rows[i].input); addToPalette(nameAssigner, color, secondaryColor); for (int i = 0; i < Rows; ++i) addToPalette(nameAssigner, color, rows[i].output); } void setColor(const ColorObject &colorObject) { gtk_color_set_color(GTK_COLOR(lastFocusedColor), colorObject.getColor()); update(); } ColorObject colorObject; const ColorObject &getColor() { Color color; gtk_color_get_color(GTK_COLOR(lastFocusedColor), &color); auto widgetName = identifyColorWidget(lastFocusedColor); colorObject.setColor(color); ColorMixerColorNameAssigner nameAssigner(gs); nameAssigner.assign(&colorObject, &color, widgetName.c_str()); return colorObject; } std::string identifyColorWidget(GtkWidget *widget) { if (secondaryColor == widget) { return _("secondary"); } else for (int i = 0; i < Rows; ++i) { if (rows[i].input == widget) { return common::format(_("primary {}"), i + 1); } else if (rows[i].output == widget) { return common::format(_("result {}"), i + 1); } } return "unknown"; } static gboolean onFocusEvent(GtkWidget *widget, GdkEventFocus *, ColorMixerArgs *args) { args->lastFocusedColor = widget; return false; } void setActiveWidget(GtkWidget *widget) { lastFocusedColor = widget; } void setMode(const Type *type) { mixerType = type; gtk_color_set_text(GTK_COLOR(secondaryColor), _(mixerType->name)); update(); } static void onModeChange(GtkWidget *widget, ColorMixerArgs *args) { if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) return; return args->setMode(static_cast(g_object_get_data(G_OBJECT(widget), "color_mixer_type"))); } static void onColorActivate(GtkWidget *, ColorMixerArgs *args) { args->addToPalette(); } static void onChange(GtkWidget *, ColorMixerArgs *args) { args->update(); } bool isEditable() { if (lastFocusedColor == secondaryColor) return true; for (int i = 0; i < Rows; ++i) if (lastFocusedColor == rows[i].input) return true; return false; } void update(bool saveSettings = false) { float opacity = static_cast(gtk_range_get_value(GTK_RANGE(opacityRange))); if (saveSettings) { options->set("opacity", opacity); } Color color, color2, r, hsv1, hsv2; gtk_color_get_color(GTK_COLOR(secondaryColor), &color2); for (int i = 0; i < Rows; ++i) { gtk_color_get_color(GTK_COLOR(rows[i].input), &color); switch (mixerType->mode) { case Mode::normal: r.rgb.red = color2.rgb.red; r.rgb.green = color2.rgb.green; r.rgb.blue = color2.rgb.blue; break; case Mode::multiply: r.rgb.red = color.rgb.red * color2.rgb.red; r.rgb.green = color.rgb.green * color2.rgb.green; r.rgb.blue = color.rgb.blue * color2.rgb.blue; break; case Mode::add: r.rgb.red = clamp_float(color.rgb.red + color2.rgb.red, 0, 1); r.rgb.green = clamp_float(color.rgb.green + color2.rgb.green, 0, 1); r.rgb.blue = clamp_float(color.rgb.blue + color2.rgb.blue, 0, 1); break; case Mode::difference: r.rgb.red = std::fabs(color.rgb.red - color2.rgb.red); r.rgb.green = std::fabs(color.rgb.green - color2.rgb.green); r.rgb.blue = std::fabs(color.rgb.blue - color2.rgb.blue); break; case Mode::hue: color_rgb_to_hsv(&color, &hsv1); color_rgb_to_hsv(&color2, &hsv2); hsv1.hsv.hue = hsv2.hsv.hue; color_hsv_to_rgb(&hsv1, &r); break; case Mode::saturation: color_rgb_to_hsv(&color, &hsv1); color_rgb_to_hsv(&color2, &hsv2); hsv1.hsv.saturation = hsv2.hsv.saturation; color_hsv_to_rgb(&hsv1, &r); break; case Mode::lightness: color_rgb_to_hsl(&color, &hsv1); color_rgb_to_hsl(&color2, &hsv2); hsv1.hsl.lightness = hsv2.hsl.lightness; color_hsl_to_rgb(&hsv1, &r); break; } r.rgb.red = (color.rgb.red * (100 - opacity) + r.rgb.red * opacity) / 100; r.rgb.green = (color.rgb.green * (100 - opacity) + r.rgb.green * opacity) / 100; r.rgb.blue = (color.rgb.blue * (100 - opacity) + r.rgb.blue * opacity) / 100; gtk_color_set_color(GTK_COLOR(rows[i].output), r); } } struct Editable: IEditableColorsUI, IMenuExtension { Editable(ColorMixerArgs *args): args(args) { } virtual ~Editable() = default; virtual void addToPalette(const ColorObject &) override { args->addToPalette(); } virtual void addAllToPalette() override { args->addAllToPalette(); } virtual void setColor(const ColorObject &colorObject) override { args->setColor(colorObject.getColor()); } virtual const ColorObject &getColor() override { return args->getColor(); } virtual std::vector getColors(bool selected) override { std::vector colors; colors.push_back(getColor()); return colors; } virtual bool isEditable() override { return args->isEditable(); } virtual bool hasColor() override { return true; } virtual bool hasSelectedColor() override { return true; } virtual void extendMenu(GtkWidget *menu, Position position) { if (position != Position::end || !isEditable()) return; gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); GSList *group = nullptr; for (size_t i = 0; i < sizeof(types) / sizeof(Type); i++) { auto item = gtk_radio_menu_item_new_with_label(group, _(types[i].name)); group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item)); if (args->mixerType == &types[i]) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), true); g_object_set_data(G_OBJECT(item), "color_mixer_type", const_cast(&types[i])); g_signal_connect(G_OBJECT(item), "toggled", G_CALLBACK(ColorMixerArgs::onModeChange), args); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); } } private: ColorMixerArgs *args; }; boost::optional editable; }; static int destroy(ColorMixerArgs *args) { Color c; char tmp[32]; args->options->set("mixer_type", args->mixerType->id); for (int i = 0; i < Rows; ++i) { sprintf(tmp, "color%d", i); gtk_color_get_color(GTK_COLOR(args->rows[i].input), &c); args->options->set(tmp, c); } gtk_color_get_color(GTK_COLOR(args->secondaryColor), &c); args->options->set("secondary_color", c); gtk_widget_destroy(args->main); delete args; return 0; } static int getColor(ColorMixerArgs *args, ColorObject **color) { auto colorObject = args->getColor(); *color = colorObject.copy(); return 0; } static int setColor(ColorMixerArgs *args, ColorObject *colorObject) { args->setColor(*colorObject); return 0; } static int activate(ColorMixerArgs *args) { auto chain = args->gs->getTransformationChain(); gtk_color_set_transformation_chain(GTK_COLOR(args->secondaryColor), chain); for (int i = 0; i < Rows; ++i) { gtk_color_set_transformation_chain(GTK_COLOR(args->rows[i].input), chain); gtk_color_set_transformation_chain(GTK_COLOR(args->rows[i].output), chain); } gtk_statusbar_push(GTK_STATUSBAR(args->statusBar), gtk_statusbar_get_context_id(GTK_STATUSBAR(args->statusBar), "empty"), ""); return 0; } static int deactivate(ColorMixerArgs *args) { args->update(true); return 0; } static ColorObject *getColorObject(DragDrop *dd) { auto *args = static_cast(dd->userdata); return args->getColor().copy(); } static int setColorObjectAt(DragDrop *dd, ColorObject *colorObject, int, int, bool, bool) { auto *args = static_cast(dd->userdata); args->setActiveWidget(dd->widget); args->setColor(*colorObject); return 0; } static ColorSource *source_implement(ColorSource *source, GlobalState *gs, const dynv::Ref &options) { auto *args = new ColorMixerArgs; args->editable = ColorMixerArgs::Editable(args); args->options = options; args->statusBar = gs->getStatusBar(); args->gs = gs; color_source_init(&args->source, source->identificator, source->hr_name); args->source.destroy = (int (*)(ColorSource *))destroy; args->source.get_color = (int (*)(ColorSource *, ColorObject **))getColor; args->source.set_color = (int (*)(ColorSource *, ColorObject *))setColor; args->source.deactivate = (int (*)(ColorSource *))deactivate; args->source.activate = (int (*)(ColorSource *))activate; GtkWidget *table, *vbox, *hbox, *widget, *hbox2; hbox = gtk_hbox_new(false, 0); vbox = gtk_vbox_new(false, 0); gtk_box_pack_start(GTK_BOX(hbox), vbox, true, true, 5); args->colorPreviews = gtk_table_new(Rows, 3, false); gtk_box_pack_start(GTK_BOX(vbox), args->colorPreviews, true, true, 0); DragDrop dd; dragdrop_init(&dd, gs); dd.converterType = Converters::Type::display; dd.userdata = args; dd.get_color_object = getColorObject; dd.set_color_object_at = setColorObjectAt; widget = gtk_color_new(); gtk_color_set_rounded(GTK_COLOR(widget), true); gtk_color_set_hcenter(GTK_COLOR(widget), true); gtk_color_set_roundness(GTK_COLOR(widget), 5); gtk_table_attach(GTK_TABLE(args->colorPreviews), widget, 1, 2, 0, Rows, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL | GTK_EXPAND), 0, 0); args->secondaryColor = widget; g_signal_connect(G_OBJECT(widget), "activated", G_CALLBACK(ColorMixerArgs::onColorActivate), args); g_signal_connect(G_OBJECT(widget), "focus-in-event", G_CALLBACK(ColorMixerArgs::onFocusEvent), args); StandardEventHandler::forWidget(widget, args->gs, &*args->editable); gtk_widget_set_size_request(widget, 50, 50); //setup drag&drop gtk_drag_dest_set(widget, GtkDestDefaults(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT), 0, 0, GDK_ACTION_COPY); gtk_drag_source_set(widget, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY); dd.userdata2 = (void *)-1; dragdrop_widget_attach(widget, DragDropFlags(DRAGDROP_SOURCE | DRAGDROP_DESTINATION), &dd); for (intptr_t i = 0; i < Rows; ++i) { for (intptr_t j = 0; j < 2; ++j) { widget = gtk_color_new(); gtk_color_set_rounded(GTK_COLOR(widget), true); gtk_color_set_hcenter(GTK_COLOR(widget), true); gtk_color_set_roundness(GTK_COLOR(widget), 5); gtk_table_attach(GTK_TABLE(args->colorPreviews), widget, j * 2, j * 2 + 1, i, i + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL | GTK_EXPAND), 0, 0); if (j) { args->rows[i].output = widget; } else { args->rows[i].input = widget; } g_signal_connect(G_OBJECT(widget), "activated", G_CALLBACK(ColorMixerArgs::onColorActivate), args); g_signal_connect(G_OBJECT(widget), "focus-in-event", G_CALLBACK(ColorMixerArgs::onFocusEvent), args); StandardEventHandler::forWidget(widget, args->gs, &*args->editable); if (j == 0) { //setup drag&drop gtk_widget_set_size_request(widget, 30, 30); gtk_drag_dest_set(widget, GtkDestDefaults(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT), 0, 0, GDK_ACTION_COPY); gtk_drag_source_set(widget, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY); dd.userdata2 = (void *)i; dragdrop_widget_attach(widget, DragDropFlags(DRAGDROP_SOURCE | DRAGDROP_DESTINATION), &dd); } else { gtk_widget_set_size_request(widget, 30, 30); gtk_drag_source_set(widget, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY); dd.userdata2 = (void *)i; dragdrop_widget_attach(widget, DragDropFlags(DRAGDROP_SOURCE), &dd); } } } Color c; color_set(&c, 0.5); char tmp[32]; auto type_name = options->getString("mixer_type", "normal"); for (uint32_t j = 0; j < sizeof(types) / sizeof(Type); j++) { if (types[j].id == type_name) { args->mixerType = &types[j]; break; } } for (gint i = 0; i < Rows; ++i) { sprintf(tmp, "color%d", i); gtk_color_set_color(GTK_COLOR(args->rows[i].input), options->getColor(tmp, c)); } gtk_color_set_color(GTK_COLOR(args->secondaryColor), options->getColor("secondary_color", c), _(args->mixerType->name)); hbox2 = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox2, false, false, 0); gint table_y; table = gtk_table_new(5, 2, false); gtk_box_pack_start(GTK_BOX(hbox2), table, true, true, 0); table_y = 0; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Opacity:"), 0, 0.5, 0, 0), 0, 1, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 0, 0); args->opacityRange = gtk_hscale_new_with_range(1, 100, 1); gtk_range_set_value(GTK_RANGE(args->opacityRange), options->getFloat("opacity", 50)); g_signal_connect(G_OBJECT(args->opacityRange), "value-changed", G_CALLBACK(ColorMixerArgs::onChange), args); gtk_table_attach(GTK_TABLE(table), args->opacityRange, 1, 2, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 0, 0); table_y++; gtk_widget_show_all(hbox); args->update(); args->main = hbox; args->source.widget = hbox; return (ColorSource *)args; } int color_mixer_source_register(ColorSourceManager *csm) { ColorSource *color_source = new ColorSource; color_source_init(color_source, "color_mixer", _("Color mixer")); color_source->implement = source_implement; color_source->default_accelerator = GDK_KEY_m; color_source_manager_add_source(csm, color_source); return 0; } gpick-gpick-0.2.6/source/ColorMixer.h000066400000000000000000000033031377073231300174500ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_COLOR_MIXER_H_ #define GPICK_COLOR_MIXER_H_ struct ColorSourceManager; int color_mixer_source_register(ColorSourceManager *csm); #endif /* GPICK_COLOR_MIXER_H_ */ gpick-gpick-0.2.6/source/ColorObject.cpp000066400000000000000000000073431377073231300201350ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ColorObject.h" using namespace std; ColorObject::ColorObject(): m_refcnt(0), m_name(), m_color(), m_position(0), m_position_set(false), m_selected(false), m_visited(false), m_visible(true) { } ColorObject::ColorObject(const char *name, const Color &color): m_refcnt(0), m_name(name), m_color(color), m_position(0), m_position_set(false), m_selected(false), m_visited(false), m_visible(true) { } ColorObject::ColorObject(const Color &color): m_refcnt(0), m_color(color), m_position(0), m_position_set(false), m_selected(false), m_visited(false), m_visible(true) { } ColorObject::ColorObject(const std::string &name, const Color &color): m_refcnt(0), m_name(name), m_color(color), m_position(0), m_position_set(false), m_selected(false), m_visited(false), m_visible(true) { } ColorObject *ColorObject::reference() { m_refcnt++; return this; } void ColorObject::release() { if (m_refcnt == 0){ delete this; }else{ m_refcnt--; } } const Color &ColorObject::getColor() const { return m_color; } void ColorObject::setColor(const Color &color) { m_color = color; } const std::string &ColorObject::getName() const { return m_name; } void ColorObject::setName(const std::string &name) { m_name = name; } ColorObject* ColorObject::copy() const { ColorObject *color_object = new ColorObject(); color_object->m_name = m_name; color_object->m_color = m_color; color_object->m_selected = m_selected; color_object->m_visited = m_visited; return color_object; } bool ColorObject::isSelected() const { return m_selected; } bool ColorObject::isVisited() const { return m_visited; } size_t ColorObject::getPosition() const { return m_position; } bool ColorObject::isPositionSet() const { return m_position_set; } bool ColorObject::isVisible() const { return m_visible; } void ColorObject::setPosition(size_t position) { m_position = position; m_position_set = true; } void ColorObject::resetPosition() { m_position_set = false; } void ColorObject::setSelected(bool selected) { m_selected = selected; } void ColorObject::setVisited(bool visited) { m_visited = visited; } void ColorObject::setVisible(bool visible) { m_visible = visible; } size_t ColorObject::getReferenceCount() const { return m_refcnt; } gpick-gpick-0.2.6/source/ColorObject.h000066400000000000000000000050141377073231300175730ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_COLOR_OBJECT_H_ #define GPICK_COLOR_OBJECT_H_ #include "Color.h" #include struct ColorObject { ColorObject(); ColorObject(const char *name, const Color &color); ColorObject(const Color &color); ColorObject(const std::string &name, const Color &color); ColorObject *reference(); void release(); const Color &getColor() const; void setColor(const Color &color); const std::string &getName() const; void setName(const std::string &name); ColorObject* copy() const; bool isSelected() const; bool isVisited() const; size_t getPosition() const; bool isPositionSet() const; void setPosition(size_t position); void resetPosition(); void setSelected(bool selected); void setVisited(bool visited); size_t getReferenceCount() const; void setVisible(bool visible); bool isVisible() const; private: size_t m_refcnt; std::string m_name; Color m_color; size_t m_position; bool m_position_set; bool m_selected; bool m_visited; bool m_visible; }; #endif /* GPICK_COLOR_OBJECT_H_ */ gpick-gpick-0.2.6/source/ColorPicker.cpp000066400000000000000000001511261377073231300201430ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ColorPicker.h" #include "ColorObject.h" #include "GlobalState.h" #include "ColorList.h" #include "ColorSource.h" #include "ColorSourceManager.h" #include "DragDrop.h" #include "Converters.h" #include "dynv/Map.h" #include "FloatingPicker.h" #include "ColorRYB.h" #include "ColorWheelType.h" #include "ColorSpaceType.h" #include "gtk/Swatch.h" #include "gtk/Zoomed.h" #include "gtk/ColorComponent.h" #include "gtk/ColorWidget.h" #include "Clipboard.h" #include "uiUtilities.h" #include "uiColorInput.h" #include "uiConverter.h" #include "StandardEventHandler.h" #include "I18N.h" #include "color_names/ColorNames.h" #include "ScreenReader.h" #include "Sampler.h" #include #include #ifdef _MSC_VER #define M_PI 3.14159265359 #endif #include #include #include #include #include #include using namespace std; using namespace math; struct ColorPickerArgs; static void updateDisplays(ColorPickerArgs *args, GtkWidget *except_widget); struct ColorPickerArgs { ColorSource source; GtkWidget* main; GtkWidget* expanderRGB; GtkWidget* expanderHSV; GtkWidget* expanderHSL; GtkWidget* expanderCMYK; GtkWidget* expanderXYZ; GtkWidget* expanderLAB; GtkWidget* expanderLCH; GtkWidget* expanderInfo; GtkWidget* expanderInput; GtkWidget* expanderMain; GtkWidget* expanderSettings; GtkWidget *swatch_display; GtkWidget *zoomed_display; GtkWidget *color_code; GtkWidget *hsl_control; GtkWidget *hsv_control; GtkWidget *rgb_control; GtkWidget *cmyk_control; GtkWidget *lab_control; GtkWidget *lch_control; GtkWidget *color_name; GtkWidget *statusbar; GtkWidget *contrastCheck; GtkWidget *contrastCheckMsg; GtkWidget *pick_button; GtkWidget *colorWidget; GtkWidget *colorInput; guint timeout_source_id; FloatingPicker floating_picker; dynv::Ref options; dynv::Ref mainOptions; GlobalState* gs; bool ignore_callback; ColorObject *getActive() { Color color; gtk_swatch_get_active_color(GTK_SWATCH(swatch_display), &color); std::string name = color_names_get(gs->getColorNames(), &color, gs->settings().getBool("gpick.color_names.imprecision_postfix", false)); return new ColorObject(name, color); } void getActive(ColorObject &colorObject) { Color color; gtk_swatch_get_active_color(GTK_SWATCH(swatch_display), &color); std::string name = color_names_get(gs->getColorNames(), &color, gs->settings().getBool("gpick.color_names.imprecision_postfix", false)); colorObject.setName(name); colorObject.setColor(color); } void addToPalette(ColorObject *colorObject) { color_list_add_color_object(gs->getColorList(), colorObject, true); } void addToPalette(const Color &color) { auto name = color_names_get(gs->getColorNames(), &color, gs->settings().getBool("gpick.color_names.imprecision_postfix", false)); auto colorObject = new ColorObject(name, color); addToPalette(colorObject); colorObject->release(); } void copy(const Color &color) { auto name = color_names_get(gs->getColorNames(), &color, gs->settings().getBool("gpick.color_names.imprecision_postfix", false)); auto colorObject = new ColorObject(name, color); clipboard::set(colorObject, gs, Converters::Type::copy); colorObject->release(); } void addToPalette() { addToPalette(getActive()); } void addAllToPalette() { Color color; for (int i = 1; i < 7; ++i) { gtk_swatch_get_color(GTK_SWATCH(swatch_display), i, &color); addToPalette(color); } } void setColor(const Color &color) { Color copy = color; gtk_swatch_set_active_color(GTK_SWATCH(swatch_display), ©); updateDisplays(this, nullptr); } void setColor(ColorObject *colorObject) { Color copy = colorObject->getColor(); gtk_swatch_set_active_color(GTK_SWATCH(swatch_display), ©); updateDisplays(this, nullptr); } struct SwatchEditable: public IEditableColorsUI { SwatchEditable(ColorPickerArgs *args): args(args) { } virtual ~SwatchEditable() = default; virtual void addToPalette(const ColorObject &) override { args->addToPalette(); } virtual void addAllToPalette() override { args->addAllToPalette(); } virtual void setColor(const ColorObject &colorObject) override { args->setColor(colorObject.getColor()); } virtual const ColorObject &getColor() override { args->getActive(colorObject); return colorObject; } virtual std::vector getColors(bool selected) override { if (selected) { args->getActive(colorObject); return std::vector { colorObject }; } else { std::vector result; //TODO: get all six colors return result; } } virtual bool isEditable() override { return true; } virtual bool hasColor() override { return true; } virtual bool hasSelectedColor() override { return true; } private: ColorPickerArgs *args; ColorObject colorObject; }; boost::optional swatchEditable; struct ColorInputReadonly: public IReadonlyColorUI { ColorInputReadonly(ColorPickerArgs *args): args(args) { } virtual ~ColorInputReadonly() = default; virtual void addToPalette(const ColorObject &) override { Color color; gtk_color_get_color(GTK_COLOR(args->colorWidget), &color); args->addToPalette(color); } virtual const ColorObject &getColor() override { Color color; gtk_color_get_color(GTK_COLOR(args->colorWidget), &color); colorObject.setColor(color); return colorObject; } virtual bool hasSelectedColor() override { return true; } private: ColorPickerArgs *args; ColorObject colorObject; }; boost::optional colorInputEditable; }; struct ColorCompItem{ GtkWidget *widget; GtkColorComponentComp component; int component_id; }; static int source_set_color(ColorPickerArgs *args, ColorObject* color); static int source_set_nth_color(ColorPickerArgs *args, uint32_t color_n, ColorObject* color); static int source_get_nth_color(ColorPickerArgs *args, uint32_t color_n, ColorObject** color); static void updateMainColorNow(ColorPickerArgs* args) { if (!args->options->getBool("zoomed_enabled", true)){ Color c; gtk_swatch_get_active_color(GTK_SWATCH(args->swatch_display), &c); string text = args->gs->converters().serialize(c, Converters::Type::display); gtk_color_set_color(GTK_COLOR(args->color_code), &c, text.c_str()); gtk_swatch_set_main_color(GTK_SWATCH(args->swatch_display), &c); } } static gboolean updateMainColor( gpointer data ){ ColorPickerArgs* args=(ColorPickerArgs*)data; GdkScreen *screen; GdkModifierType state; int x, y; gdk_display_get_pointer(gdk_display_get_default(), &screen, &x, &y, &state); int monitor = gdk_screen_get_monitor_at_point(screen, x, y); GdkRectangle monitor_geometry; gdk_screen_get_monitor_geometry(screen, monitor, &monitor_geometry); Vec2 pointer(x,y); Rect2 screen_rect(monitor_geometry.x, monitor_geometry.y, monitor_geometry.x + monitor_geometry.width, monitor_geometry.y + monitor_geometry.height); auto screen_reader = args->gs->getScreenReader(); screen_reader_reset_rect(screen_reader); Rect2 sampler_rect, zoomed_rect, final_rect; sampler_get_screen_rect(args->gs->getSampler(), pointer, screen_rect, &sampler_rect); screen_reader_add_rect(screen_reader, screen, sampler_rect); bool zoomed_enabled = args->options->getBool("zoomed_enabled", true); if (zoomed_enabled){ gtk_zoomed_get_screen_rect(GTK_ZOOMED(args->zoomed_display), pointer, screen_rect, &zoomed_rect); screen_reader_add_rect(screen_reader, screen, zoomed_rect); } screen_reader_update_surface(screen_reader, &final_rect); Vec2 offset; offset = sampler_rect.position() - final_rect.position(); Color c; sampler_get_color_sample(args->gs->getSampler(), pointer, screen_rect, offset, &c); string text = args->gs->converters().serialize(c, Converters::Type::display); gtk_color_set_color(GTK_COLOR(args->color_code), &c, text.c_str()); gtk_swatch_set_main_color(GTK_SWATCH(args->swatch_display), &c); if (zoomed_enabled){ offset = final_rect.position() - zoomed_rect.position(); gtk_zoomed_update(GTK_ZOOMED(args->zoomed_display), pointer, screen_rect, offset, screen_reader_get_surface(screen_reader)); } return TRUE; } static gboolean updateMainColorTimer(ColorPickerArgs* args) { updateMainColor(args); return true; } static void updateComponentText(ColorPickerArgs *args, GtkColorComponent *component, const char *type) { Color transformed_color; gtk_color_component_get_transformed_color(component, &transformed_color); lua::Script &script = args->gs->script(); list str = color_space_color_to_text(type, &transformed_color, script, args->gs); int j = 0; const char *text[4]; memset(text, 0, sizeof(text)); for (list::iterator i = str.begin(); i != str.end(); i++){ text[j] = (*i).c_str(); j++; if (j > 3) break; } gtk_color_component_set_text(component, text); } static void updateDisplays(ColorPickerArgs *args, GtkWidget *except_widget) { updateMainColorNow(args); Color c, c2; gtk_swatch_get_active_color(GTK_SWATCH(args->swatch_display),&c); if (except_widget != args->hsl_control) gtk_color_component_set_color(GTK_COLOR_COMPONENT(args->hsl_control), &c); if (except_widget != args->hsv_control) gtk_color_component_set_color(GTK_COLOR_COMPONENT(args->hsv_control), &c); if (except_widget != args->rgb_control) gtk_color_component_set_color(GTK_COLOR_COMPONENT(args->rgb_control), &c); if (except_widget != args->cmyk_control) gtk_color_component_set_color(GTK_COLOR_COMPONENT(args->cmyk_control), &c); if (except_widget != args->lab_control) gtk_color_component_set_color(GTK_COLOR_COMPONENT(args->lab_control), &c); if (except_widget != args->lch_control) gtk_color_component_set_color(GTK_COLOR_COMPONENT(args->lch_control), &c); updateComponentText(args, GTK_COLOR_COMPONENT(args->hsl_control), "hsl"); updateComponentText(args, GTK_COLOR_COMPONENT(args->hsv_control), "hsv"); updateComponentText(args, GTK_COLOR_COMPONENT(args->rgb_control), "rgb"); updateComponentText(args, GTK_COLOR_COMPONENT(args->cmyk_control), "cmyk"); updateComponentText(args, GTK_COLOR_COMPONENT(args->lab_control), "lab"); updateComponentText(args, GTK_COLOR_COMPONENT(args->lch_control), "lch"); string color_name = color_names_get(args->gs->getColorNames(), &c, true); gtk_entry_set_text(GTK_ENTRY(args->color_name), color_name.c_str()); gtk_color_get_color(GTK_COLOR(args->contrastCheck), &c2); gtk_color_set_text_color(GTK_COLOR(args->contrastCheck), &c); stringstream ss; ss.setf(ios::fixed, ios::floatfield); Color c_lab, c2_lab; color_rgb_to_lab_d50(&c, &c_lab); color_rgb_to_lab_d50(&c2, &c2_lab); const ColorWheelType *wheel = &color_wheel_types_get()[0]; Color hsl1, hsl2; double hue1, hue2; color_rgb_to_hsl(&c, &hsl1); color_rgb_to_hsl(&c2, &hsl2); wheel->rgbhue_to_hue(hsl1.hsl.hue, &hue1); wheel->rgbhue_to_hue(hsl2.hsl.hue, &hue2); double complementary = std::abs(hue1 - hue2); complementary -= std::floor(complementary); complementary *= std::sin(hsl1.hsl.lightness * M_PI) * std::sin(hsl2.hsl.lightness * M_PI); complementary *= std::sin(hsl1.hsl.saturation * M_PI / 2) * std::sin(hsl2.hsl.saturation * M_PI / 2); ss << std::setprecision(1) << std::abs(c_lab.lab.L - c2_lab.lab.L) + complementary * 50 << "%"; auto message = ss.str(); gtk_label_set_text(GTK_LABEL(args->contrastCheckMsg), message.c_str()); } static void on_swatch_active_color_changed(GtkWidget *widget, gint32 new_active_color, gpointer data) { ColorPickerArgs* args = (ColorPickerArgs*)data; updateDisplays(args, widget); } static void on_swatch_color_changed(GtkWidget *widget, gpointer data) { ColorPickerArgs* args = (ColorPickerArgs*)data; updateDisplays(args, widget); } static void on_swatch_color_activated(GtkWidget *widget, ColorPickerArgs *args) { args->addToPalette(); } static void on_swatch_center_activated(GtkWidget *widget, ColorPickerArgs *args) { floating_picker_activate(args->floating_picker, true, false, nullptr); } static void on_picker_toggled(GtkWidget *widget, ColorPickerArgs *args) { if (args->ignore_callback) return; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))){ if (args->options->getBool("always_use_floating_picker", true)){ floating_picker_activate(args->floating_picker, false, false, nullptr); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), false); }else{ gtk_swatch_set_active(GTK_SWATCH(args->swatch_display), true); } }else{ gtk_swatch_set_active(GTK_SWATCH(args->swatch_display), false); } } static gboolean on_swatch_focus_change(GtkWidget *widget, GdkEventFocus *event, gpointer data) { ColorPickerArgs* args = (ColorPickerArgs*)data; if (event->in){ gtk_statusbar_push(GTK_STATUSBAR(args->statusbar), gtk_statusbar_get_context_id(GTK_STATUSBAR(args->statusbar), "swatch_focused"), _("Press Spacebar to sample color under mouse pointer")); if (!args->options->getBool("always_use_floating_picker", true)){ args->ignore_callback = true; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(args->pick_button), true); args->ignore_callback = false; gtk_swatch_set_active(GTK_SWATCH(args->swatch_display), true); } }else{ gtk_statusbar_pop(GTK_STATUSBAR(args->statusbar), gtk_statusbar_get_context_id(GTK_STATUSBAR(args->statusbar), "swatch_focused")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(args->pick_button), false); gtk_swatch_set_active(GTK_SWATCH(args->swatch_display), false); } return FALSE; } static void onColorInputChanged(GtkWidget *entry, ColorPickerArgs *args) { ColorObject *colorObject; if (args->gs->converters().deserialize((char*)gtk_entry_get_text(GTK_ENTRY(entry)), &colorObject)) { auto color = colorObject->getColor(); auto text = args->gs->converters().serialize(colorObject, Converters::Type::display); gtk_color_set_color(GTK_COLOR(args->colorWidget), color, text); colorObject->release(); gtk_widget_set_sensitive(GTK_WIDGET(args->colorWidget), true); } else { gtk_widget_set_sensitive(GTK_WIDGET(args->colorWidget), false); } } static void pick(ColorPickerArgs *args) { updateMainColor(args); gtk_swatch_set_color_to_main(GTK_SWATCH(args->swatch_display)); if (args->options->getBool("sampler.add_to_palette", true)) { Color color; gtk_swatch_get_active_color(GTK_SWATCH(args->swatch_display), &color); ColorObject *color_object = color_list_new_color_object(args->gs->getColorList(), &color); string name=color_names_get(args->gs->getColorNames(), &color, args->gs->settings().getBool("gpick.color_names.imprecision_postfix", false)); color_object->setName(name); color_list_add_color_object(args->gs->getColorList(), color_object, 1); color_object->release(); } if (args->options->getBool("sampler.copy_to_clipboard", true)) { Color color; gtk_swatch_get_active_color(GTK_SWATCH(args->swatch_display), &color); clipboard::set(color, args->gs, Converters::Type::copy); } if (args->options->getBool("sampler.rotate_swatch_after_sample", true)) { gtk_swatch_move_active(GTK_SWATCH(args->swatch_display), 1); } updateDisplays(args, args->swatch_display); } static gboolean onSwatchKeyPress(GtkWidget *widget, GdkEventKey *event, ColorPickerArgs *args) { guint modifiers = gtk_accelerator_get_default_mod_mask(); auto key = getKeyval(*event, args->gs->latinKeysGroup); switch (key) { case GDK_KEY_m: { int x, y; gdk_display_get_pointer(gdk_display_get_default(), nullptr, &x, &y, nullptr); math::Vec2 position(x, y); if ((event->state & modifiers) == GDK_CONTROL_MASK){ gtk_zoomed_set_mark(GTK_ZOOMED(args->zoomed_display), 1, position); }else{ gtk_zoomed_set_mark(GTK_ZOOMED(args->zoomed_display), 0, position); } } break; case GDK_KEY_1: case GDK_KEY_2: case GDK_KEY_3: case GDK_KEY_4: case GDK_KEY_5: case GDK_KEY_6: gtk_swatch_set_active_index(GTK_SWATCH(args->swatch_display), key - GDK_KEY_1 + 1); updateDisplays(args, widget); return true; case GDK_KEY_Right: gtk_swatch_move_active(GTK_SWATCH(args->swatch_display), 1); updateDisplays(args, widget); return true; case GDK_KEY_Left: gtk_swatch_move_active(GTK_SWATCH(args->swatch_display), -1); updateDisplays(args, widget); return true; case GDK_KEY_space: pick(args); return true; } return false; } void color_picker_pick(ColorSource* color_source) { auto args = reinterpret_cast(color_source); pick(args); } void color_picker_add_to_palette(ColorSource* color_source) { auto args = reinterpret_cast(color_source); updateMainColor(args); Color color; gtk_swatch_get_main_color(GTK_SWATCH(args->swatch_display), &color); args->addToPalette(color); } void color_picker_copy(ColorSource* color_source) { auto args = reinterpret_cast(color_source); updateMainColor(args); Color color; gtk_swatch_get_main_color(GTK_SWATCH(args->swatch_display), &color); args->copy(color); } void color_picker_set(ColorSource *color_source, int index) { auto args = reinterpret_cast(color_source); updateMainColor(args); gtk_swatch_set_active_index(GTK_SWATCH(args->swatch_display), index + 1); gtk_swatch_set_color_to_main(GTK_SWATCH(args->swatch_display)); updateDisplays(args, nullptr); } static void on_oversample_value_changed(GtkRange *slider, gpointer data){ ColorPickerArgs* args=(ColorPickerArgs*)data; sampler_set_oversample(args->gs->getSampler(), (int)gtk_range_get_value(GTK_RANGE(slider))); } static void on_zoom_value_changed(GtkRange *slider, gpointer data){ ColorPickerArgs* args=(ColorPickerArgs*)data; gtk_zoomed_set_zoom(GTK_ZOOMED(args->zoomed_display), static_cast(gtk_range_get_value(GTK_RANGE(slider)))); } static void color_component_change_value(GtkWidget *widget, Color* c, ColorPickerArgs* args){ gtk_swatch_set_active_color(GTK_SWATCH(args->swatch_display), c); updateDisplays(args, widget); } static void color_component_input_clicked(GtkWidget *widget, int component_id, ColorPickerArgs* args){ dialog_color_component_input_show(GTK_WINDOW(gtk_widget_get_toplevel(args->main)), GTK_COLOR_COMPONENT(widget), component_id, args->options->getOrCreateMap("component_edit")); } static void ser_decimal_get(GtkColorComponentComp component, int component_id, Color* color, const char *text){ double v; stringstream ss(text); ss >> v; switch (component){ case GtkColorComponentComp::hsv: case GtkColorComponentComp::hsl: if (component_id == 0){ color->ma[component_id] = static_cast(v / 360); }else{ color->ma[component_id] = static_cast(v / 100); } break; default: color->ma[component_id] = static_cast(v / 100); } } static string ser_decimal_set(GtkColorComponentComp component, int component_id, Color* color){ stringstream ss; switch (component){ case GtkColorComponentComp::hsv: case GtkColorComponentComp::hsl: if (component_id == 0){ ss << setprecision(0) << fixed << color->ma[component_id] * 360; }else{ ss << setprecision(0) << fixed << color->ma[component_id] * 100; } break; default: ss << setprecision(0) << fixed << color->ma[component_id] * 100; } return ss.str(); } static struct{ const char *name; const char *human_name; void (*get)(GtkColorComponentComp component, int component_id, Color* color, const char *text); string (*set)(GtkColorComponentComp component, int component_id, Color* color); }serial[] = { {"decimal", "Decimal", ser_decimal_get, ser_decimal_set}, }; static void color_component_copy(GtkWidget *widget, ColorPickerArgs* args){ struct ColorCompItem *comp_item = (struct ColorCompItem*)g_object_get_data(G_OBJECT(gtk_widget_get_parent(widget)), "comp_item"); const char *text = gtk_color_component_get_text(GTK_COLOR_COMPONENT(comp_item->widget), comp_item->component_id); if (text){ gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), text, strlen(text)); gtk_clipboard_store(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD)); gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), text, strlen(text)); } } static void color_component_paste(GtkWidget *widget, ColorPickerArgs* args){ Color color; struct ColorCompItem *comp_item = (struct ColorCompItem*)g_object_get_data(G_OBJECT(gtk_widget_get_parent(widget)), "comp_item"); gtk_color_component_get_transformed_color(GTK_COLOR_COMPONENT(comp_item->widget), &color); gchar *text = gtk_clipboard_wait_for_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD)); if (text){ serial[0].get(comp_item->component, comp_item->component_id, &color, text); gtk_color_component_set_transformed_color(GTK_COLOR_COMPONENT(comp_item->widget), &color); g_free(text); gtk_color_component_get_color(GTK_COLOR_COMPONENT(comp_item->widget), &color); gtk_swatch_set_active_color(GTK_SWATCH(args->swatch_display), &color); updateDisplays(args, comp_item->widget); } } static void color_component_edit(GtkWidget *widget, ColorPickerArgs* args){ struct ColorCompItem *comp_item = (struct ColorCompItem*)g_object_get_data(G_OBJECT(gtk_widget_get_parent(widget)), "comp_item"); dialog_color_component_input_show(GTK_WINDOW(gtk_widget_get_toplevel(args->main)), GTK_COLOR_COMPONENT(comp_item->widget), comp_item->component_id, args->options->getOrCreateMap("component_edit")); } static void destroy_comp_item(struct ColorCompItem *comp_item){ delete comp_item; } static gboolean color_component_key_up_cb(GtkWidget *widget, GdkEventButton *event, ColorPickerArgs* args){ if ((event->type == GDK_BUTTON_RELEASE) && (event->button == 3)){ auto menu = gtk_menu_new(); struct ColorCompItem *comp_item = new struct ColorCompItem; comp_item->widget = widget; comp_item->component_id = gtk_color_component_get_component_id_at(GTK_COLOR_COMPONENT(widget), static_cast(event->x), static_cast(event->y)); comp_item->component = gtk_color_component_get_component(GTK_COLOR_COMPONENT(widget)); g_object_set_data_full(G_OBJECT(menu), "comp_item", comp_item, (GDestroyNotify)destroy_comp_item); auto item = newMenuItem(_("Copy"), GTK_STOCK_COPY); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(color_component_copy), args); item = newMenuItem(_("Paste"), GTK_STOCK_PASTE); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(color_component_paste), args); gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); item = newMenuItem(_("Edit"), GTK_STOCK_EDIT); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(color_component_edit), args); showContextMenu(menu, event); return true; } return false; } static void on_oversample_falloff_changed(GtkWidget *widget, gpointer data) { GtkTreeIter iter; if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter)) { GtkTreeModel* model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget)); gint32 falloff_id; gtk_tree_model_get(model, &iter, 2, &falloff_id, -1); ColorPickerArgs* args = (ColorPickerArgs*)data; sampler_set_falloff(args->gs->getSampler(), (SamplerFalloff) falloff_id); } } static GtkWidget* create_falloff_type_list() { GtkListStore *store = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT); GtkWidget *widget = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); gtk_combo_box_set_add_tearoffs(GTK_COMBO_BOX(widget), 0); GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget),renderer, 0); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(widget), renderer, "pixbuf", 0, nullptr); renderer = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, 0); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(widget), renderer, "text", 1, nullptr); g_object_unref(GTK_TREE_MODEL(store)); struct{ const char *icon; const char *label; SamplerFalloff falloff; }falloff_types[] = { {"gpick-falloff-none", _("None"), SamplerFalloff::none}, {"gpick-falloff-linear", _("Linear"), SamplerFalloff::linear}, {"gpick-falloff-quadratic", _("Quadratic"), SamplerFalloff::quadratic}, {"gpick-falloff-cubic", _("Cubic"), SamplerFalloff::cubic}, {"gpick-falloff-exponential", _("Exponential"), SamplerFalloff::exponential}, }; GtkIconTheme *icon_theme = gtk_icon_theme_get_default(); gint icon_size; gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, 0, &icon_size); for (size_t i = 0; i < sizeof(falloff_types) / sizeof(falloff_types[0]); ++i){ GError *error = nullptr; GdkPixbuf* pixbuf = gtk_icon_theme_load_icon(icon_theme, falloff_types[i].icon, icon_size, GtkIconLookupFlags(0), &error); if (error) g_error_free(error); GtkTreeIter iter1; gtk_list_store_append(store, &iter1); gtk_list_store_set(store, &iter1, 0, pixbuf, 1, falloff_types[i].label, 2, falloff_types[i].falloff, -1); if (pixbuf) g_object_unref (pixbuf); } return widget; } static int source_destroy(ColorPickerArgs *args) { args->options->set("swatch.active_color", gtk_swatch_get_active_index(GTK_SWATCH(args->swatch_display))); Color c; char tmp[32]; for (gint i=1; i<7; ++i){ sprintf(tmp, "swatch.color%d", i); gtk_swatch_get_color(GTK_SWATCH(args->swatch_display), i, &c); args->options->set(tmp, c); } args->options->set("sampler.oversample", sampler_get_oversample(args->gs->getSampler())); args->options->set("sampler.falloff", static_cast(sampler_get_falloff(args->gs->getSampler()))); args->options->set("zoom", static_cast(gtk_zoomed_get_zoom(GTK_ZOOMED(args->zoomed_display)))); args->options->set("zoom_size", gtk_zoomed_get_size(GTK_ZOOMED(args->zoomed_display))); args->options->set("expander.settings", gtk_expander_get_expanded(GTK_EXPANDER(args->expanderSettings))); args->options->set("expander.rgb", gtk_expander_get_expanded(GTK_EXPANDER(args->expanderRGB))); args->options->set("expander.hsv", gtk_expander_get_expanded(GTK_EXPANDER(args->expanderHSV))); args->options->set("expander.hsl", gtk_expander_get_expanded(GTK_EXPANDER(args->expanderHSL))); args->options->set("expander.lab", gtk_expander_get_expanded(GTK_EXPANDER(args->expanderLAB))); args->options->set("expander.lch", gtk_expander_get_expanded(GTK_EXPANDER(args->expanderLCH))); args->options->set("expander.cmyk", gtk_expander_get_expanded(GTK_EXPANDER(args->expanderCMYK))); args->options->set("expander.info", gtk_expander_get_expanded(GTK_EXPANDER(args->expanderInfo))); args->options->set("expander.input", gtk_expander_get_expanded(GTK_EXPANDER(args->expanderInput))); gtk_color_get_color(GTK_COLOR(args->contrastCheck), &c); args->options->set("contrast.color", c); args->options->set("color_input_text", gtk_entry_get_text(GTK_ENTRY(args->colorInput))); gtk_widget_destroy(args->main); delete args; return 0; } static int source_get_color(ColorPickerArgs *args, ColorObject** color_object) { Color color; gtk_swatch_get_active_color(GTK_SWATCH(args->swatch_display), &color); ColorObject *new_color_object = color_list_new_color_object(args->gs->getColorList(), &color); string name = color_names_get(args->gs->getColorNames(), &color, args->gs->settings().getBool("gpick.color_names.imprecision_postfix", false)); new_color_object->setName(name); *color_object = new_color_object; return 0; } static int source_set_nth_color(ColorPickerArgs *args, uint32_t color_n, ColorObject* color_object) { if (color_n < 0 || color_n > 6) return -1; Color color = color_object->getColor(); gtk_swatch_set_color(GTK_SWATCH(args->swatch_display), color_n + 1, &color); updateDisplays(args, 0); return 0; } static int source_get_nth_color(ColorPickerArgs *args, uint32_t color_n, ColorObject** color_object) { if (color_n < 0 || color_n > 6) return -1; Color color; gtk_swatch_get_color(GTK_SWATCH(args->swatch_display), color_n + 1, &color); ColorObject *new_color_object = color_list_new_color_object(args->gs->getColorList(), &color); string name = color_names_get(args->gs->getColorNames(), &color, args->gs->settings().getBool("gpick.color_names.imprecision_postfix", false)); new_color_object->setName(name); *color_object = new_color_object; return 0; } static int source_set_color(ColorPickerArgs *args, ColorObject* color_object) { Color color = color_object->getColor(); gtk_swatch_set_active_color(GTK_SWATCH(args->swatch_display), &color); updateDisplays(args, 0); return 0; } static int source_activate(ColorPickerArgs *args) { if (args->timeout_source_id > 0) { g_source_remove(args->timeout_source_id); args->timeout_source_id = 0; } struct{ GtkWidget *widget; const char *setting; }color_spaces[] = { {args->expanderCMYK, "color_space.cmyk"}, {args->expanderHSL, "color_space.hsl"}, {args->expanderHSV, "color_space.hsv"}, {args->expanderLAB, "color_space.lab"}, {args->expanderLCH, "color_space.lch"}, {args->expanderRGB, "color_space.rgb"}, {0, 0}, }; for (int i = 0; color_spaces[i].setting; i++){ if (args->options->getBool(color_spaces[i].setting, true)) gtk_widget_show(color_spaces[i].widget); else gtk_widget_hide(color_spaces[i].widget); } bool out_of_gamut_mask = args->options->getBool("out_of_gamut_mask", true); gtk_color_component_set_out_of_gamut_mask(GTK_COLOR_COMPONENT(args->lab_control), out_of_gamut_mask); gtk_color_component_set_lab_illuminant(GTK_COLOR_COMPONENT(args->lab_control), color_get_illuminant(args->options->getString("lab.illuminant", "D50"))); gtk_color_component_set_lab_observer(GTK_COLOR_COMPONENT(args->lab_control), color_get_observer(args->options->getString("lab.observer", "2"))); updateComponentText(args, GTK_COLOR_COMPONENT(args->lab_control), "lab"); gtk_color_component_set_out_of_gamut_mask(GTK_COLOR_COMPONENT(args->lch_control), out_of_gamut_mask); gtk_color_component_set_lab_illuminant(GTK_COLOR_COMPONENT(args->lch_control), color_get_illuminant(args->options->getString("lab.illuminant", "D50"))); gtk_color_component_set_lab_observer(GTK_COLOR_COMPONENT(args->lch_control), color_get_observer(args->options->getString("lab.observer", "2"))); updateComponentText(args, GTK_COLOR_COMPONENT(args->lch_control), "lch"); auto chain = args->gs->getTransformationChain(); gtk_swatch_set_transformation_chain(GTK_SWATCH(args->swatch_display), chain); gtk_color_set_transformation_chain(GTK_COLOR(args->color_code), chain); gtk_color_set_transformation_chain(GTK_COLOR(args->contrastCheck), chain); if (args->options->getBool("zoomed_enabled", true)){ auto refresh_rate = args->mainOptions->getInt32("refresh_rate", 30); args->timeout_source_id = g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, static_cast(1000 / refresh_rate), (GSourceFunc)updateMainColorTimer, args, (GDestroyNotify)nullptr); } gtk_zoomed_set_size(GTK_ZOOMED(args->zoomed_display), args->options->getInt32("zoom_size", 150)); gtk_statusbar_push(GTK_STATUSBAR(args->statusbar), gtk_statusbar_get_context_id(GTK_STATUSBAR(args->statusbar), "focus_swatch"), _("Click on swatch area to begin adding colors to palette")); return 0; } static int source_deactivate(ColorPickerArgs *args){ gtk_statusbar_pop(GTK_STATUSBAR(args->statusbar), gtk_statusbar_get_context_id(GTK_STATUSBAR(args->statusbar), "focus_swatch")); if (args->timeout_source_id > 0){ g_source_remove(args->timeout_source_id); args->timeout_source_id = 0; } return 0; } static ColorObject* get_color_object(struct DragDrop* dd){ ColorPickerArgs* args=(ColorPickerArgs*)dd->userdata; ColorObject *color_object; source_get_color(args, &color_object); return color_object; } static int set_color_object_at(struct DragDrop* dd, ColorObject* color_object, int x, int y, bool, bool) { gint color_index = gtk_swatch_get_color_at(GTK_SWATCH(dd->widget), x, y); Color color = color_object->getColor(); gtk_swatch_set_color(GTK_SWATCH(dd->widget), color_index, &color); updateDisplays((ColorPickerArgs*)dd->userdata, 0); return 0; } static bool test_at(struct DragDrop* dd, int x, int y){ gint color_index = gtk_swatch_get_color_at(GTK_SWATCH(dd->widget), x, y); if (color_index>0) return true; return false; } void color_picker_set_floating_picker(ColorSource *color_source, FloatingPicker floating_picker){ ColorPickerArgs* args = (ColorPickerArgs*)color_source; args->floating_picker = floating_picker; } static ColorObject* getColorObjectForColorInput(struct DragDrop* dd) { ColorPickerArgs* args = static_cast(dd->userdata); Color color; gtk_color_get_color(GTK_COLOR(args->colorWidget), &color); string name = color_names_get(args->gs->getColorNames(), &color, args->gs->settings().getBool("gpick.color_names.imprecision_postfix", false)); return new ColorObject(name, color); } static ColorObject* get_color_object_contrast(struct DragDrop* dd) { ColorPickerArgs* args = static_cast(dd->userdata); Color color; gtk_color_get_color(GTK_COLOR(dd->widget), &color); string name = color_names_get(args->gs->getColorNames(), &color, args->gs->settings().getBool("gpick.color_names.imprecision_postfix", false)); return new ColorObject(name, color); } static int set_color_object_at_contrast(struct DragDrop* dd, ColorObject* color_object, int x, int y, bool, bool) { ColorPickerArgs* args = static_cast(dd->userdata); Color color = color_object->getColor(); gtk_color_set_color(GTK_COLOR(args->contrastCheck), &color, "Sample"); updateDisplays((ColorPickerArgs*)dd->userdata, 0); return 0; } static void show_dialog_converter(GtkWidget *widget, ColorPickerArgs *args){ dialog_converter_show(GTK_WINDOW(gtk_widget_get_toplevel(args->main)), args->gs); return; } static void on_zoomed_activate(GtkWidget *widget, ColorPickerArgs *args){ if (args->options->getBool("zoomed_enabled", true)){ gtk_zoomed_set_fade(GTK_ZOOMED(args->zoomed_display), true); args->options->set("zoomed_enabled", false); if (args->timeout_source_id > 0){ g_source_remove(args->timeout_source_id); args->timeout_source_id = 0; } }else{ gtk_zoomed_set_fade(GTK_ZOOMED(args->zoomed_display), false); args->options->set("zoomed_enabled", true); if (args->timeout_source_id > 0){ g_source_remove(args->timeout_source_id); args->timeout_source_id = 0; } auto refresh_rate = args->mainOptions->getInt32("refresh_rate", 30); args->timeout_source_id = g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, static_cast(1000 / refresh_rate), (GSourceFunc)updateMainColorTimer, args, (GDestroyNotify)nullptr); } return; } static ColorSource* source_implement(ColorSource *source, GlobalState *gs, const dynv::Ref &options){ ColorPickerArgs* args = new ColorPickerArgs; args->swatchEditable = ColorPickerArgs::SwatchEditable(args); args->colorInputEditable = ColorPickerArgs::ColorInputReadonly(args); args->options = options; args->mainOptions = gs->settings().getOrCreateMap("gpick.picker"); args->statusbar = gs->getStatusBar(); args->floating_picker = 0; args->ignore_callback = false; color_source_init(&args->source, source->identificator, source->hr_name); args->source.destroy = (int (*)(ColorSource *source))source_destroy; args->source.get_color = (int (*)(ColorSource *source, ColorObject** color))source_get_color; args->source.set_color = (int (*)(ColorSource *source, ColorObject* color))source_set_color; args->source.get_nth_color = (int (*)(ColorSource *source, size_t color_n, ColorObject** color))source_get_nth_color; args->source.set_nth_color = (int (*)(ColorSource *source, size_t color_n, ColorObject* color))source_set_nth_color; args->source.activate = (int (*)(ColorSource *source))source_activate; args->source.deactivate = (int (*)(ColorSource *source))source_deactivate; args->gs = gs; args->timeout_source_id = 0; GtkWidget *vbox, *widget, *expander, *table, *main_hbox, *scrolled; int table_y; main_hbox = gtk_hbox_new(false, 5); vbox = gtk_vbox_new(false, 0); gtk_box_pack_start(GTK_BOX(main_hbox), vbox, false, false, 0); args->pick_button = widget = gtk_toggle_button_new_with_label(_("Pick color")); gtk_box_pack_start(GTK_BOX(vbox), widget, false, false, 0); g_signal_connect(G_OBJECT(widget), "toggled", G_CALLBACK(on_picker_toggled), args); g_signal_connect(G_OBJECT(widget), "key_press_event", G_CALLBACK(onSwatchKeyPress), args); g_signal_connect(G_OBJECT(widget), "focus-out-event", G_CALLBACK(on_swatch_focus_change), args); StandardEventHandler::forWidget(widget, args->gs, &*args->swatchEditable); args->swatch_display = widget = gtk_swatch_new(); gtk_box_pack_start(GTK_BOX(vbox), widget, false, false, 0); g_signal_connect(G_OBJECT(widget), "focus-in-event", G_CALLBACK(on_swatch_focus_change), args); g_signal_connect(G_OBJECT(widget), "focus-out-event", G_CALLBACK(on_swatch_focus_change), args); g_signal_connect(G_OBJECT(widget), "key_press_event", G_CALLBACK(onSwatchKeyPress), args); g_signal_connect(G_OBJECT(widget), "active_color_changed", G_CALLBACK(on_swatch_active_color_changed), args); g_signal_connect(G_OBJECT(widget), "color_changed", G_CALLBACK(on_swatch_color_changed), args); g_signal_connect(G_OBJECT(widget), "color_activated", G_CALLBACK(on_swatch_color_activated), args); g_signal_connect(G_OBJECT(widget), "center_activated", G_CALLBACK(on_swatch_center_activated), args); StandardEventHandler::forWidget(widget, args->gs, &*args->swatchEditable); gtk_swatch_set_active_index(GTK_SWATCH(widget), options->getInt32("swatch.active_color", 1)); gtk_drag_dest_set(widget, GtkDestDefaults(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT), 0, 0, GDK_ACTION_COPY); gtk_drag_source_set(widget, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY); struct DragDrop dd; dragdrop_init(&dd, gs); dd.converterType = Converters::Type::display; dd.userdata = args; dd.get_color_object = get_color_object; dd.set_color_object_at = set_color_object_at; dd.test_at = test_at; dragdrop_widget_attach(widget, DragDropFlags(DRAGDROP_SOURCE | DRAGDROP_DESTINATION), &dd); { char tmp[32]; Color color; for (gint i=1; i<7; ++i){ sprintf(tmp, "swatch.color%d", i); Color color, result; color.hsl.hue = (i - 1) / 15.f; color.hsl.saturation = 0.8f; color.hsl.lightness = 0.5f; color_hsl_to_rgb(&color, &result); color = options->getColor(tmp, color); gtk_swatch_set_color(GTK_SWATCH(args->swatch_display), i, color); } } args->color_code = gtk_color_new(); gtk_box_pack_start (GTK_BOX(vbox), args->color_code, false, true, 0); g_signal_connect(G_OBJECT(args->color_code), "activated", G_CALLBACK(show_dialog_converter), args); args->zoomed_display = gtk_zoomed_new(); if (!options->getBool("zoomed_enabled", true)){ gtk_zoomed_set_fade(GTK_ZOOMED(args->zoomed_display), true); } gtk_zoomed_set_size(GTK_ZOOMED(args->zoomed_display), options->getInt32("zoom_size", 150)); gtk_zoomed_set_zoom(GTK_ZOOMED(args->zoomed_display), options->getInt32("zoom", 20)); gtk_box_pack_start (GTK_BOX(vbox), args->zoomed_display, false, false, 0); g_signal_connect(G_OBJECT(args->zoomed_display), "activated", G_CALLBACK(on_zoomed_activate), args); scrolled = gtk_scrolled_window_new(0, 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start (GTK_BOX(main_hbox), scrolled, true, true, 0); vbox = gtk_vbox_new(false, 5); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled), vbox); expander=gtk_expander_new(_("Settings")); gtk_expander_set_expanded(GTK_EXPANDER(expander), options->getBool("expander.settings", false)); args->expanderSettings=expander; gtk_box_pack_start (GTK_BOX(vbox), expander, FALSE, FALSE, 0); table = gtk_table_new(6, 2, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(expander), table); gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Oversample:"),0,0.5,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); widget = gtk_hscale_new_with_range (0,16,1); g_signal_connect (G_OBJECT (widget), "value-changed", G_CALLBACK (on_oversample_value_changed), args); gtk_range_set_value(GTK_RANGE(widget), options->getInt32("sampler.oversample", 0)); gtk_table_attach(GTK_TABLE(table), widget,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Falloff:"),0,0.5,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); widget = create_falloff_type_list(); g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (on_oversample_falloff_changed), args); gtk_combo_box_set_active(GTK_COMBO_BOX(widget), options->getInt32("sampler.falloff", static_cast(SamplerFalloff::none))); gtk_table_attach(GTK_TABLE(table), widget,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Zoom:"),0,0.5,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); widget = gtk_hscale_new_with_range (0, 100, 1); g_signal_connect (G_OBJECT (widget), "value-changed", G_CALLBACK (on_zoom_value_changed), args); gtk_range_set_value(GTK_RANGE(widget), options->getInt32("zoom", 20)); gtk_table_attach(GTK_TABLE(table), widget,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); table_y++; expander=gtk_expander_new("HSV"); gtk_expander_set_expanded(GTK_EXPANDER(expander), options->getBool("expander.hsv", false)); args->expanderHSV=expander; gtk_box_pack_start(GTK_BOX(vbox), expander, FALSE, FALSE, 0); widget = gtk_color_component_new(GtkColorComponentComp::hsv); const char *hsv_labels[] = {"H", _("Hue"), "S", _("Saturation"), "V", _("Value"), nullptr}; gtk_color_component_set_label(GTK_COLOR_COMPONENT(widget), hsv_labels); args->hsv_control = widget; g_signal_connect(G_OBJECT(widget), "color-changed", G_CALLBACK(color_component_change_value), args); g_signal_connect(G_OBJECT(widget), "button_release_event", G_CALLBACK(color_component_key_up_cb), args); g_signal_connect(G_OBJECT(widget), "input-clicked", G_CALLBACK(color_component_input_clicked), args); gtk_container_add(GTK_CONTAINER(expander), widget); expander=gtk_expander_new("HSL"); gtk_expander_set_expanded(GTK_EXPANDER(expander), options->getBool("expander.hsl", false)); args->expanderHSL = expander; gtk_box_pack_start(GTK_BOX(vbox), expander, FALSE, FALSE, 0); widget = gtk_color_component_new(GtkColorComponentComp::hsl); const char *hsl_labels[] = {"H", _("Hue"), "S", _("Saturation"), "L", _("Lightness"), nullptr}; gtk_color_component_set_label(GTK_COLOR_COMPONENT(widget), hsl_labels); args->hsl_control = widget; g_signal_connect(G_OBJECT(widget), "color-changed", G_CALLBACK(color_component_change_value), args); g_signal_connect(G_OBJECT(widget), "button_release_event", G_CALLBACK(color_component_key_up_cb), args); g_signal_connect(G_OBJECT(widget), "input-clicked", G_CALLBACK(color_component_input_clicked), args); gtk_container_add(GTK_CONTAINER(expander), widget); expander=gtk_expander_new("RGB"); gtk_expander_set_expanded(GTK_EXPANDER(expander), options->getBool("expander.rgb", false)); args->expanderRGB = expander; gtk_box_pack_start (GTK_BOX(vbox), expander, FALSE, FALSE, 0); widget = gtk_color_component_new(GtkColorComponentComp::rgb); const char *rgb_labels[] = {"R", _("Red"), "G", _("Green"), "B", _("Blue"), nullptr}; gtk_color_component_set_label(GTK_COLOR_COMPONENT(widget), rgb_labels); args->rgb_control = widget; g_signal_connect(G_OBJECT(widget), "color-changed", G_CALLBACK(color_component_change_value), args); g_signal_connect(G_OBJECT(widget), "button_release_event", G_CALLBACK(color_component_key_up_cb), args); g_signal_connect(G_OBJECT(widget), "input-clicked", G_CALLBACK(color_component_input_clicked), args); gtk_container_add(GTK_CONTAINER(expander), widget); expander=gtk_expander_new("CMYK"); gtk_expander_set_expanded(GTK_EXPANDER(expander), options->getBool("expander.cmyk", false)); args->expanderCMYK = expander; gtk_box_pack_start(GTK_BOX(vbox), expander, FALSE, FALSE, 0); widget = gtk_color_component_new(GtkColorComponentComp::cmyk); const char *cmyk_labels[] = {"C", _("Cyan"), "M", _("Magenta"), "Y", _("Yellow"), "K", _("Key"), nullptr}; gtk_color_component_set_label(GTK_COLOR_COMPONENT(widget), cmyk_labels); args->cmyk_control = widget; g_signal_connect(G_OBJECT(widget), "color-changed", G_CALLBACK(color_component_change_value), args); g_signal_connect(G_OBJECT(widget), "button_release_event", G_CALLBACK(color_component_key_up_cb), args); g_signal_connect(G_OBJECT(widget), "input-clicked", G_CALLBACK(color_component_input_clicked), args); gtk_container_add(GTK_CONTAINER(expander), widget); expander = gtk_expander_new("Lab"); gtk_expander_set_expanded(GTK_EXPANDER(expander), options->getBool("expander.lab", false)); args->expanderLAB = expander; gtk_box_pack_start (GTK_BOX(vbox), expander, FALSE, FALSE, 0); widget = gtk_color_component_new(GtkColorComponentComp::lab); const char *lab_labels[] = {"L", _("Lightness"), "a", "a", "b", "b", nullptr}; gtk_color_component_set_label(GTK_COLOR_COMPONENT(widget), lab_labels); args->lab_control = widget; g_signal_connect(G_OBJECT(widget), "color-changed", G_CALLBACK(color_component_change_value), args); g_signal_connect(G_OBJECT(widget), "button_release_event", G_CALLBACK(color_component_key_up_cb), args); g_signal_connect(G_OBJECT(widget), "input-clicked", G_CALLBACK(color_component_input_clicked), args); gtk_container_add(GTK_CONTAINER(expander), widget); expander = gtk_expander_new("LCH"); gtk_expander_set_expanded(GTK_EXPANDER(expander), options->getBool("expander.lch", false)); args->expanderLCH = expander; gtk_box_pack_start (GTK_BOX(vbox), expander, FALSE, FALSE, 0); widget = gtk_color_component_new(GtkColorComponentComp::lch); const char *lch_labels[] = {"L", _("Lightness"), "C", "Chroma", "H", "Hue", nullptr}; gtk_color_component_set_label(GTK_COLOR_COMPONENT(widget), lch_labels); args->lch_control = widget; g_signal_connect(G_OBJECT(widget), "color-changed", G_CALLBACK(color_component_change_value), args); g_signal_connect(G_OBJECT(widget), "button_release_event", G_CALLBACK(color_component_key_up_cb), args); g_signal_connect(G_OBJECT(widget), "input-clicked", G_CALLBACK(color_component_input_clicked), args); gtk_container_add(GTK_CONTAINER(expander), widget); expander=gtk_expander_new(_("Info")); gtk_expander_set_expanded(GTK_EXPANDER(expander), options->getBool("expander.info", false)); args->expanderInfo=expander; gtk_box_pack_start (GTK_BOX(vbox), expander, FALSE, FALSE, 0); table = gtk_table_new(3, 2, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(expander), table); gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Color name:"),0,0.5,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); widget = gtk_entry_new(); gtk_table_attach(GTK_TABLE(table), widget,1,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); gtk_editable_set_editable(GTK_EDITABLE(widget), FALSE); //gtk_widget_set_sensitive(GTK_WIDGET(widget), FALSE); args->color_name = widget; table_y++; dragdrop_init(&dd, gs); dd.converterType = Converters::Type::display; dd.userdata = args; dd.get_color_object = get_color_object_contrast; dd.set_color_object_at = set_color_object_at_contrast; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Contrast:"),0,0.5,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); widget = gtk_color_new(); auto color = options->getColor("contrast.color", Color(1)); gtk_color_set_color(GTK_COLOR(widget), color, _("Sample")); gtk_color_set_rounded(GTK_COLOR(widget), true); gtk_color_set_hcenter(GTK_COLOR(widget), true); gtk_color_set_roundness(GTK_COLOR(widget), 5); gtk_table_attach(GTK_TABLE(table), widget,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); args->contrastCheck = widget; gtk_drag_dest_set(widget, GtkDestDefaults(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT), 0, 0, GDK_ACTION_COPY); gtk_drag_source_set(widget, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY); dd.userdata2 = 0; dragdrop_widget_attach(widget, DragDropFlags(DRAGDROP_SOURCE | DRAGDROP_DESTINATION), &dd); gtk_table_attach(GTK_TABLE(table), args->contrastCheckMsg = gtk_label_new(""),2,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,5); table_y++; expander=gtk_expander_new(_("Input")); gtk_expander_set_expanded(GTK_EXPANDER(expander), options->getBool("expander.input", false)); args->expanderInput=expander; gtk_box_pack_start(GTK_BOX(vbox), expander, false, false, 0); table = gtk_table_new(3, 2, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(expander), table); gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Value:"), 0, 0.5, 0, 0), 0, 1, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 5, 5); args->colorInput = widget = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(widget), options->getString("color_input_text", "").c_str()); gtk_table_attach(GTK_TABLE(table), widget, 1, 3, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 5, 0); g_signal_connect(G_OBJECT(widget), "changed", G_CALLBACK(onColorInputChanged), args); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Color:"), 0, 0.5, 0, 0), 0, 1, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 5, 5); args->colorWidget = widget = gtk_color_new(); gtk_color_set_rounded(GTK_COLOR(widget), true); gtk_color_set_hcenter(GTK_COLOR(widget), true); gtk_color_set_roundness(GTK_COLOR(widget), 5); gtk_widget_set_size_request(widget, 30, 30); gtk_table_attach(GTK_TABLE(table), widget, 1, 3, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 5, 0); StandardEventHandler::forWidget(widget, args->gs, &*args->colorInputEditable); dragdrop_init(&dd, gs); dd.converterType = Converters::Type::display; dd.userdata = args; dd.get_color_object = getColorObjectForColorInput; gtk_drag_source_set(widget, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY); dragdrop_widget_attach(widget, DragDropFlags(DRAGDROP_SOURCE), &dd); table_y++; onColorInputChanged(args->colorInput, args); updateDisplays(args, 0); args->main = main_hbox; gtk_widget_show_all(main_hbox); args->source.widget = main_hbox; return (ColorSource*)args; } int color_picker_source_register(ColorSourceManager *csm) { ColorSource *color_source = new ColorSource; color_source_init(color_source, "color_picker", _("Color picker")); color_source->implement = (ColorSource* (*)(ColorSource *source, GlobalState *gs, const dynv::Ref &options))source_implement; color_source->single_instance_only = true; color_source->default_accelerator = GDK_KEY_c; color_source_manager_add_source(csm, color_source); return 0; } void color_picker_set_current_color(ColorSource* color_source) { ColorPickerArgs* args = (ColorPickerArgs*)color_source; updateMainColor(args); gtk_swatch_set_color_to_main(GTK_SWATCH(args->swatch_display)); updateDisplays(args, nullptr); } void color_picker_rotate_swatch(ColorSource* color_source) { ColorPickerArgs* args = (ColorPickerArgs*)color_source; gtk_swatch_move_active(GTK_SWATCH(args->swatch_display), 1); updateDisplays(args, nullptr); } void color_picker_focus_swatch(ColorSource *color_source) { ColorPickerArgs* args = (ColorPickerArgs*)color_source; gtk_widget_grab_focus(args->swatch_display); } bool is_color_picker(ColorSource *color_source) { return color_source->identificator == "color_picker"; } gpick-gpick-0.2.6/source/ColorPicker.h000066400000000000000000000045771377073231300176170ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_COLOR_PICKER_H_ #define GPICK_COLOR_PICKER_H_ #include "FloatingPicker.h" #include struct ColorSource; struct ColorSourceManager; int color_picker_source_register(ColorSourceManager *csm); int color_picker_key_up(ColorSource* color_source, GdkEventKey *event); void color_picker_set_current_color(ColorSource* color_source); void color_picker_rotate_swatch(ColorSource* color_source); void color_picker_set_floating_picker(ColorSource *color_source, FloatingPicker floating_picker); void color_picker_focus_swatch(ColorSource *color_source); bool is_color_picker(ColorSource *color_source); void color_picker_pick(ColorSource *color_source); void color_picker_copy(ColorSource *color_source); void color_picker_add_to_palette(ColorSource *color_source); void color_picker_set(ColorSource *color_source, int index); #endif /* GPICK_COLOR_PICKER_H_ */ gpick-gpick-0.2.6/source/ColorRYB.cpp000066400000000000000000000203141377073231300173540ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ColorRYB.h" #include "MathUtil.h" #include "BezierCubicCurve.h" #include "Vector2.h" #include #include #include #include using namespace std; typedef math::Vec2 point; typedef math::BezierCubicCurve bezier; double bezier_eval_at_x(list& channel, double x, double delta){ for (list::iterator i=channel.begin(); i != channel.end(); ++i){ if (x>=(*i)->p0.x && x<=(*i)->p3.x){ double width = ((*i)->p3.x-(*i)->p0.x); double t = (x-(*i)->p0.x)/width; double d; point v; for (int limit=50; limit>0; --limit){ v = (**i)(t); d = v.x - x; if (fabs(d)1) t=1; else if (t<0) t=0; } } } return 0; } static void color_get_ryb_curves(list &red, list &green, list &blue){ static bezier red_v[]={ bezier( point(0.0, 1.0), point(1.0, 1.0), point(13.0, 1.0), point(14.0, 1.0) ), bezier( point(14.0, 1.0), point(16.0, 0.6405), point(16.9, 0.0), point(21.0, 0.0) ), bezier( point(21.0, 0.0), point(28.0, 0.0), point(33.0, 1.0), point(36.0, 1.0) ) }; static bezier green_v[]={ bezier( point(0.0, 0.0), point(4.0, 0.4), point(13.0, 1.0), point(14.0, 1.0) ), bezier( point(14.0, 1.0), point(14.85, 1.0), point(17.05, 0.9525), point(19.0, 0.7) ), bezier( point(19.0, 0.7), point(24.0, 0.05), point(31.0, 0.0), point(36.0, 0.0) ) }; static bezier blue_v[]={ bezier( point(0.0, 0.0), point(1.0, 0.0), point(18.0, 0.0), point(19.0, 0.0) ), bezier( point(19.0, 0.0), point(22.0, 1.0), point(33.0, 1.0), point(36.0, 0.0) ) }; for (uint32_t i=0; i red, green, blue; color_get_ryb_curves(red, green, blue); double hue = rgb_hue; double d; double delta = 1/3600.0; Color color, color2; for (int limit=100; limit>0; --limit){ color.rgb.red = bezier_eval_at_x(red, hue*36, 0.01), color.rgb.green = bezier_eval_at_x(green, hue*36, 0.01), color.rgb.blue = bezier_eval_at_x(blue, hue*36, 0.01); color_rgb_to_hsv(&color, &color2); d = rgb_hue - color2.hsv.hue; if (fabs(d)1) hue=1; else if (hue<0) hue=0; } *ryb_hue = hue; return -1; } double color_rybhue_to_rgbhue_f(double hue){ if (hue>=4.0/6.0 && hue<=6.0/6.0){ return ((285.12*hue*hue)-(81.252*hue)+155.18)/360.0; }else if (hue>=0.0/6.0 && hue<=1.0/6.0){ return ((-544.32*hue*hue)+(301.896*hue))/360.0; }else if (hue>=1.0/6.0 && hue<=3.0/6.0){ return ((609.12*hue*hue)-(153.72*hue)+45.166)/360.0; }else if (hue>=3.0/6.0 && hue<=4.0/6.0){ return ((-1088.64*hue*hue)+(1916.46*hue)-567.45)/360.0; } return 0; } int color_rgbhue_to_rybhue_f(double rgb_hue, double* ryb_hue){ double hue = rgb_hue; double d; double delta = 1/3600.0; for (int limit=100; limit>0; --limit){ d = rgb_hue - color_rybhue_to_rgbhue_f(hue); if (fabs(d)1) hue=1; else if (hue<0) hue=0; } *ryb_hue = hue; return -1; } void color_rybhue_to_rgb(double hue, Color* color){ list red, green, blue; color_get_ryb_curves(red, green, blue); color->rgb.red = bezier_eval_at_x(red, hue*36, 0.01), color->rgb.green = bezier_eval_at_x(green, hue*36, 0.01), color->rgb.blue = bezier_eval_at_x(blue, hue*36, 0.01); } double color_ryb_transform_lightness(double hue1, double hue2){ double t; hue1 = modf(hue1, &t); hue2 = modf(hue2, &t); double values[]={ 0.50000000, 0.50000000, 0.50000000, 0.50000000, 0.50000000, 0.50000000, 0.50000000, 0.50000000, 0.50000000, 0.50000000, 0.50000000, 0.50000000, 0.50000000, 0.46470600, 0.42745101, 0.39215699, 0.37450999, 0.35490200, 0.33725500, 0.35294101, 0.36862749, 0.38431349, 0.37254900, 0.36078450, 0.34901950, 0.34313750, 0.33529401, 0.32941201, 0.32549000, 0.31960800, 0.31568649, 0.33921549, 0.36470601, 0.38823551, 0.42548999, 0.46274501, 0.50000000, }; int32_t samples=sizeof(values)/sizeof(double)-1; double n; return mix_double(values[int(floor(hue2*samples))], values[int(floor(hue2*samples))+1], modf(hue2*samples,&n))/ mix_double(values[int(floor(hue2*samples))], values[int(floor(hue1*samples))+1], modf(hue1*samples,&n)); } double color_ryb_transform_hue(double hue, bool forward){ double values[]={ 0.00000000, 0.02156867, 0.04248367, 0.06405234, 0.07385617, 0.08431367, 0.09411767, 0.10653600, 0.11830067, 0.13071899, 0.14248367, 0.15490200, 0.16666667, 0.18354435, 0.19954120, 0.21666662, 0.25130904, 0.28545108, 0.31976745, 0.38981494, 0.46010628, 0.53061217, 0.54649121, 0.56159425, 0.57771534, 0.60190469, 0.62573093, 0.64980155, 0.68875504, 0.72801632, 0.76708061, 0.80924863, 0.85215056, 0.89478123, 0.92933953, 0.96468931, 1.00000000, 1.00000000, }; int32_t samples=sizeof(values)/sizeof(double)-2; double new_hue; double t; hue = modf(hue, &t); if (!forward){ for (int32_t i=0; i=hue){ int index1, index2; double value1, value2, mix; index1=i; index2=i+1; value1=index1 / (double)samples; value2=index2 / (double)samples; mix = (hue-values[index1])/(values[index2]-values[index1]); new_hue= mix_double(value1, value2, mix); return new_hue; } } return 1; }else{ double value1=values[int(hue*samples)]; double value2=values[int(hue*samples+1)]; double n; double mix = modf(hue*samples, &n); new_hue = mix_double(value1, value2, mix); return new_hue; } return 0; } gpick-gpick-0.2.6/source/ColorRYB.h000066400000000000000000000040021377073231300170150ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef COLORRYB_H_ #define COLORRYB_H_ #include "Color.h" #ifndef _MSC_VER #include #endif #include double color_ryb_transform_lightness(double hue1, double hue2); double color_ryb_transform_hue(double hue, bool forward); void color_rybhue_to_rgb(double hue, Color* color); int color_rgbhue_to_rybhue(double rgb_hue, double* ryb_hue); double color_rybhue_to_rgbhue_f(double hue); int color_rgbhue_to_rybhue_f(double rgb_hue, double* ryb_hue); #endif /* COLORRYB_H_ */ gpick-gpick-0.2.6/source/ColorSource.cpp000066400000000000000000000076651377073231300201760ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ColorSource.h" #include #include using namespace std; int color_source_init(ColorSource* source, const std::string &identificator, const char *name) { source->identificator = identificator; source->hr_name = g_strdup(name); source->set_color = 0; source->get_color = 0; source->set_nth_color = 0; source->get_nth_color = 0; source->activate = 0; source->deactivate = 0; source->destroy = 0; source->set_slot_color = 0; source->query_slots = 0; source->userdata = 0; source->implement = 0; source->widget = 0; source->single_instance_only = false; source->needs_viewport = true; return 0; } int color_source_activate(ColorSource *source) { if (source->activate) return source->activate(source); return -1; } int color_source_deactivate(ColorSource *source) { if (source->deactivate) return source->deactivate(source); return -1; } int color_source_set_color(ColorSource *source, ColorObject *color) { if (source && source->set_color) return source->set_color(source, color); else if (!source) cerr << "Color source undefined" << endl; return -1; } int color_source_get_color(ColorSource *source, ColorObject **color) { if (source && source->get_color) return source->get_color(source, color); else if (!source) cerr << "Color source undefined" << endl; return -1; } int color_source_set_nth_color(ColorSource *source, size_t color_n, ColorObject *color) { if (source && source->set_nth_color) return source->set_nth_color(source, color_n, color); else if (!source) cerr << "Color source undefined" << endl; return -1; } int color_source_get_nth_color(ColorSource *source, size_t color_n, ColorObject **color) { if (source && source->get_nth_color) return source->get_nth_color(source, color_n, color); else if (!source) cerr << "Color source undefined" << endl; return -1; } int color_source_get_default_accelerator(ColorSource *source) { if (source && source->default_accelerator) return source->default_accelerator; else if (!source) cerr << "Color source undefined" << endl; return 0; } int color_source_destroy(ColorSource* source) { if (source->destroy) return source->destroy(source); g_free(source->hr_name); delete source; return 0; } ColorSource* color_source_implement(ColorSource* source, GlobalState *gs, const dynv::Ref &options) { return source->implement(source, gs, options); } GtkWidget* color_source_get_widget(ColorSource* source) { return source->widget; } gpick-gpick-0.2.6/source/ColorSource.h000066400000000000000000000066351377073231300176370ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_COLOR_SOURCE_H_ #define GPICK_COLOR_SOURCE_H_ #include "dynv/MapFwd.h" #include #include struct GlobalState; struct ColorObject; struct ColorSourceSlot{ const char *identificator; const char *hr_name; size_t id; struct{ bool read; bool write; }supports; }; struct ColorSource{ std::string identificator; char *hr_name; int (*set_color)(ColorSource *source, ColorObject *color); int (*get_color)(ColorSource *source, ColorObject **color); int (*set_nth_color)(ColorSource *source, size_t color_n, ColorObject *color); int (*get_nth_color)(ColorSource *source, size_t color_n, ColorObject **color); int (*activate)(ColorSource *source); int (*deactivate)(ColorSource *source); int (*query_slots)(ColorSource *source, ColorSourceSlot *slot); int (*set_slot_color)(ColorSource *source, size_t slot_id, ColorObject *color); ColorSource* (*implement)(ColorSource *source, GlobalState *gs, const dynv::Ref &options); int (*destroy)(ColorSource *source); bool single_instance_only; bool needs_viewport; int default_accelerator; GtkWidget *widget; void* userdata; }; int color_source_init(ColorSource* source, const std::string &identificator, const char *name); int color_source_activate(ColorSource *source); int color_source_deactivate(ColorSource *source); int color_source_set_color(ColorSource *source, ColorObject *color); int color_source_set_nth_color(ColorSource *source, size_t color_n, ColorObject *color); int color_source_get_color(ColorSource *source, ColorObject *color); int color_source_get_nth_color(ColorSource *source, size_t color_n, ColorObject **color); int color_source_get_default_accelerator(ColorSource *source); ColorSource* color_source_implement(ColorSource* source, GlobalState *gs, const dynv::Ref &options); GtkWidget* color_source_get_widget(ColorSource* source); int color_source_destroy(ColorSource* source); #endif /* GPICK_COLOR_SOURCE_H_ */ gpick-gpick-0.2.6/source/ColorSourceManager.cpp000066400000000000000000000057661377073231300214710ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ColorSourceManager.h" #include "ColorSource.h" #include #include using namespace std; ColorSourceManager* color_source_manager_create(){ ColorSourceManager *csm = new ColorSourceManager; return csm; } int color_source_manager_add_source(ColorSourceManager *csm, ColorSource *source){ pair::iterator, bool> r; r = csm->colorsource.insert(pair(source->identificator, source)); return r.second; } ColorSource* color_source_manager_get(ColorSourceManager *csm, const char *name){ map::iterator i = csm->colorsource.find(name); if (i != csm->colorsource.end()){ return (*i).second; } return 0; } ColorSource* color_source_manager_get(ColorSourceManager *csm, const std::string &name){ map::iterator i = csm->colorsource.find(name); if (i != csm->colorsource.end()){ return (*i).second; } return 0; } vector color_source_manager_get_all(ColorSourceManager *csm){ vector ret; ret.resize(csm->colorsource.size()); size_t j = 0; for (map::iterator i = csm->colorsource.begin(); i != csm->colorsource.end(); ++i){ ret[j] = (*i).second; j++; } return ret; } int color_source_manager_destroy(ColorSourceManager *csm){ for (map::iterator i = csm->colorsource.begin(); i != csm->colorsource.end(); ++i){ color_source_destroy((*i).second); } csm->colorsource.clear(); delete csm; return 0; } gpick-gpick-0.2.6/source/ColorSourceManager.h000066400000000000000000000043351377073231300211250ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_COLOR_SOURCE_MANAGER_H_ #define GPICK_COLOR_SOURCE_MANAGER_H_ #include #include #include struct ColorSource; struct ColorSourceManager{ std::map colorsource; }; ColorSourceManager* color_source_manager_create(); int color_source_manager_add_source(ColorSourceManager *csm, ColorSource *source); ColorSource* color_source_manager_get(ColorSourceManager *csm, const char *name); ColorSource* color_source_manager_get(ColorSourceManager *csm, const std::string &name); std::vector color_source_manager_get_all(ColorSourceManager *csm); int color_source_manager_destroy(ColorSourceManager *csm); #endif /* GPICK_COLOR_SOURCE_MANAGER_H_ */ gpick-gpick-0.2.6/source/ColorSpaceType.cpp000066400000000000000000000075331377073231300206250ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ColorSpaceType.h" #include "I18N.h" #include "GlobalState.h" #include "lua/Color.h" #include "lua/Script.h" #include "lua/Callbacks.h" extern "C"{ #include } #include using namespace std; const ColorSpaceType color_space_types[] = { {GtkColorComponentComp::hsv, 3, { {_("Hue"), 360, 0, 360, 0.01}, {_("Saturation"), 100, 0, 100, 0.01}, {_("Value"), 100, 0, 100, 0.01}, }, }, {GtkColorComponentComp::hsl, 3, { {_("Hue"), 360, 0, 360, 0.01}, {_("Saturation"), 100, 0, 100, 0.01}, {_("Lightness"), 100, 0, 100, 0.01}, }, }, {GtkColorComponentComp::rgb, 3, { {_("Red"), 255, 0, 255, 0.01}, {_("Green"), 255, 0, 255, 0.01}, {_("Blue"), 255, 0, 255, 0.01}, }, }, {GtkColorComponentComp::cmyk, 4, { {_("Cyan"), 255, 0, 255, 0.01}, {_("Magenta"), 255, 0, 255, 0.01}, {_("Yellow"), 255, 0, 255, 0.01}, {_("Key"), 255, 0, 255, 0.01} } }, {GtkColorComponentComp::lab, 3, { {_("Lightness"), 1, 0, 100, 0.0001}, {"a", 1, -145, 145, 0.0001}, {"b", 1, -145, 145, 0.0001} } }, {GtkColorComponentComp::lch, 3, { {_("Lightness"), 1, 0, 100, 0.0001}, {"Chroma", 1, 0, 100, 0.0001}, {"Hue", 1, 0, 360, 0.0001} } }, }; const ColorSpaceType *color_space_get_types() { return color_space_types; } size_t color_space_count_types() { return sizeof(color_space_types) / sizeof(ColorSpaceType); } std::list color_space_color_to_text(const char *type, const Color *color, lua::Script &script, GlobalState *gs) { list result; if (!gs->callbacks().componentToText().valid()) return result; lua_State *L = script; int stack_top = lua_gettop(L); gs->callbacks().componentToText().get(); lua_pushstring(L, type); lua::pushColor(L, *color); int status = lua_pcall(L, 2, 1, 0); if (status == 0){ if (lua_type(L, -1) == LUA_TTABLE){ for (int i = 0; i < 4; i++){ lua_pushinteger(L, i + 1); lua_gettable(L, -2); if (lua_type(L, -1) == LUA_TSTRING){ const char* converted = lua_tostring(L, -1); result.push_back(string(converted)); } lua_pop(L, 1); } lua_settop(L, stack_top); return result; }else{ cerr << "componentToText: returned not a table value, type is \"" << type << "\"" << endl; } }else{ cerr << "componentToText: " << lua_tostring(L, -1) << endl; } lua_settop(L, stack_top); return result; } gpick-gpick-0.2.6/source/ColorSpaceType.h000066400000000000000000000042711377073231300202660ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_COLOR_SPACE_TYPE_H_ #define GPICK_COLOR_SPACE_TYPE_H_ #include "gtk/ColorComponent.h" #include #include #include #include namespace lua { struct Script; } struct Color; struct GlobalState; struct ColorSpaceType { GtkColorComponentComp comp_type; int8_t n_items; struct { const char *name; double raw_scale; double min_value; double max_value; double step; }items[4]; }; const ColorSpaceType *color_space_get_types(); size_t color_space_count_types(); std::list color_space_color_to_text(const char *type, const Color *color, lua::Script &script, GlobalState *gs); #endif /* GPICK_COLOR_SPACE_TYPE_H_ */ gpick-gpick-0.2.6/source/ColorUtils.h000066400000000000000000000035301377073231300174660ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_COLOR_UTILS_H_ #define GPICK_COLOR_UTILS_H_ #include "Color.h" namespace color_utils { template void mix(const Color &a, const Color &b, T ratio, Color &result) { for (int i = 0; i < 4; i++){ result.ma[i] = a.ma[i] * (1 - ratio) + b.ma[i] * ratio; } }; } #endif /* GPICK_COLOR_UTILS_H_ */ gpick-gpick-0.2.6/source/ColorWheelType.cpp000066400000000000000000000051731377073231300206340ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ColorWheelType.h" #include "ColorRYB.h" #include "MathUtil.h" #include "I18N.h" static void rgb_hue2hue(double hue, Color* hsl){ hsl->hsl.hue = hue; hsl->hsl.saturation = 1; hsl->hsl.lightness = 0.5; } static void rgb_rgbhue2hue(double rgbhue, double *hue){ *hue = rgbhue; } static void ryb1_hue2hue(double hue, Color* hsl){ Color c; color_rybhue_to_rgb(hue, &c); color_rgb_to_hsl(&c, hsl); } static void ryb1_rgbhue2hue(double rgbhue, double *hue){ color_rgbhue_to_rybhue(rgbhue, hue); } static void ryb2_hue2hue(double hue, Color* hsl){ hsl->hsl.hue = color_rybhue_to_rgbhue_f(hue); hsl->hsl.saturation = 1; hsl->hsl.lightness = 0.5; } static void ryb2_rgbhue2hue(double rgbhue, double *hue){ color_rgbhue_to_rybhue_f(rgbhue, hue); } const ColorWheelType color_wheel_types[]={ {N_("RGB"), rgb_hue2hue, rgb_rgbhue2hue}, {N_("RYB v1"), ryb1_hue2hue, ryb1_rgbhue2hue}, {N_("RYB v2"), ryb2_hue2hue, ryb2_rgbhue2hue}, }; const ColorWheelType* color_wheel_types_get(){ return color_wheel_types; } const uint32_t color_wheel_types_get_n(){ return sizeof(color_wheel_types)/sizeof(ColorWheelType); } gpick-gpick-0.2.6/source/ColorWheelType.h000066400000000000000000000053401377073231300202750ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef COLOR_WHEEL_TYPE_H_ #define COLOR_WHEEL_TYPE_H_ #include "Color.h" #include /** \file source/ColorWheelType.h * \brief Color wheel type description structure and functions */ /** \struct ColorWheelType * \brief ColorWheelType structure contains color wheel type name and conversion functions */ typedef struct ColorWheelType{ const char *name; /**< Name of a color wheel */ /** * Callback used to convert color wheel specific hue into the color in a HSL color space * @param[in] hue Color wheel specific hue value * @param[out] hsl Result as a color in HSL color space */ void (*hue_to_hsl)(double hue, Color* hsl); /** * Callback used to convert HSL color space hue into color wheel specific hue * @param[in] rgbhue HSL color space hue value * @param[out] hue Color wheel specific hue value */ void (*rgbhue_to_hue)(double rgbhue, double *hue); }ColorWheelType; /** * Get available color wheel types * @return Constant array of available color wheel types */ const ColorWheelType* color_wheel_types_get(); /** * Get the number of available color wheel types * @return Number of available color wheel types */ const uint32_t color_wheel_types_get_n(); #endif /* COLOR_WHEEL_TYPE_H_ */ gpick-gpick-0.2.6/source/Converter.cpp000066400000000000000000000131731377073231300176750ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Converter.h" #include "GlobalState.h" #include "ColorObject.h" #include "lua/Color.h" #include "lua/ColorObject.h" #include "lua/Script.h" #include #include #include #include #include #include #include #include #include #include #include using namespace std; extern "C"{ #include #include } Converter::Converter(const char *name, const char *label, lua::Ref &&serialize, lua::Ref &&deserialize): m_name(name), m_label(label), m_serialize(move(serialize)), m_deserialize(move(deserialize)), m_copy(false), m_paste(false) { } std::string Converter::serialize(const ColorObject &colorObject, const ConverterSerializePosition &position) { if (!m_serialize.valid()) return ""; lua_State *L = m_serialize.script(); int stack_top = lua_gettop(L); m_serialize.get(); lua::pushColorObject(L, colorObject.copy()); lua_newtable(L); lua_pushboolean(L, position.first()); lua_setfield(L, -2, "first"); lua_pushboolean(L, position.last()); lua_setfield(L, -2, "last"); lua_pushinteger(L, position.index()); lua_setfield(L, -2, "index"); lua_pushinteger(L, position.count()); lua_setfield(L, -2, "count"); int status = lua_pcall(L, 2, 1, 0); if (status == 0){ if (lua_type(L, -1) == LUA_TSTRING){ string result = luaL_checkstring(L, -1); lua_settop(L, stack_top); return result; }else{ cerr << "serialize: returned not a string value \"" << m_name << "\"" << endl; } }else{ cerr << "serialize: " << lua_tostring(L, -1) << endl; } lua_settop(L, stack_top); return ""; } std::string Converter::serialize(const ColorObject *color_object, const ConverterSerializePosition &position) { return serialize(*color_object, position); } bool Converter::deserialize(const char *value, ColorObject *color_object, float &quality) { if (!m_deserialize.valid()) return ""; lua_State *L = m_deserialize.script(); int stack_top = lua_gettop(L); m_deserialize.get(); lua_pushstring(L, value); lua::pushColorObject(L, color_object); int status = lua_pcall(L, 2, 1, 0); if (status == 0){ if (lua_type(L, -1) == LUA_TNUMBER){ quality = static_cast(luaL_checknumber(L, -1)); lua_settop(L, stack_top); return true; }else{ cerr << "deserialize: returned not a number value \"" << m_name <<"\"" << endl; } }else{ cerr << "deserialize: " << lua_tostring(L, -1) << endl; } lua_settop(L, stack_top); return false; } std::string Converter::serialize(const ColorObject *color_object) { ConverterSerializePosition position; return serialize(color_object, position); } std::string Converter::serialize(const ColorObject &colorObject) { ConverterSerializePosition position; return serialize(colorObject, position); } std::string Converter::serialize(const Color &color) { ColorObject color_object("", color); ConverterSerializePosition position; return serialize(&color_object, position); } const std::string &Converter::name() const { return m_name; } const std::string &Converter::label() const { return m_label; } bool Converter::hasSerialize() const { return m_serialize.valid(); } bool Converter::hasDeserialize() const { return m_deserialize.valid(); } void Converter::copy(bool value) { m_copy = value; } void Converter::paste(bool value) { m_paste = value; } bool Converter::copy() const { return m_copy; } bool Converter::paste() const { return m_paste; } ConverterSerializePosition::ConverterSerializePosition(): m_first(true), m_last(true), m_index(0), m_count(1) { } ConverterSerializePosition::ConverterSerializePosition(size_t count): m_first(true), m_last(count <= 1), m_index(0), m_count(count) { } bool ConverterSerializePosition::first() const { return m_first; } bool ConverterSerializePosition::last() const { return m_last; } size_t ConverterSerializePosition::index() const { return m_index; } size_t ConverterSerializePosition::count() const { return m_count; } void ConverterSerializePosition::incrementIndex() { m_index++; } void ConverterSerializePosition::first(bool value) { m_first = value; } void ConverterSerializePosition::last(bool value) { m_last = value; } gpick-gpick-0.2.6/source/Converter.h000066400000000000000000000055621377073231300173450ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_CONVERTER_H_ #define GPICK_CONVERTER_H_ #include #include "lua/Ref.h" struct ColorObject; struct Color; struct ConverterSerializePosition { ConverterSerializePosition(); ConverterSerializePosition(size_t count); bool first() const; bool last() const; size_t index() const; size_t count() const; void incrementIndex(); void first(bool value); void last(bool value); private: bool m_first, m_last; size_t m_index, m_count; }; struct Converter { Converter(const char *name, const char *label, lua::Ref &&serialize, lua::Ref &&deserialize); const std::string &name() const; const std::string &label() const; bool hasSerialize() const; bool hasDeserialize() const; bool copy() const; bool paste() const; void copy(bool value); void paste(bool value); std::string serialize(const ColorObject *color_object, const ConverterSerializePosition &position); std::string serialize(const ColorObject *color_object); std::string serialize(const ColorObject &colorObject, const ConverterSerializePosition &position); std::string serialize(const ColorObject &colorObject); std::string serialize(const Color &color); bool deserialize(const char *value, ColorObject *color_object, float &quality); private: std::string m_name; std::string m_label; lua::Ref m_serialize, m_deserialize; bool m_copy, m_paste; }; #endif /* GPICK_CONVERTER_H_ */ gpick-gpick-0.2.6/source/Converters.cpp000066400000000000000000000160171377073231300200600ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Converters.h" #include "Converter.h" #include "ColorObject.h" #include #include using namespace std; Converters::Converters() { } Converters::~Converters() { for (auto converter: m_all_converters){ delete converter; } } void Converters::add(Converter *converter) { m_all_converters.push_back(converter); if (converter->copy() && converter->hasSerialize()) m_copy_converters.push_back(converter); if (converter->paste() && converter->hasDeserialize()) m_paste_converters.push_back(converter); m_converters[converter->name()] = converter; } void Converters::rebuildCopyPasteArrays() { m_copy_converters.clear(); m_paste_converters.clear(); for (auto converter: m_all_converters){ if (converter->copy() && converter->hasSerialize()) m_copy_converters.push_back(converter); if (converter->paste() && converter->hasDeserialize()) m_paste_converters.push_back(converter); } } const std::vector &Converters::all() const { return m_all_converters; } const std::vector &Converters::allCopy() const { return m_copy_converters; } bool Converters::hasCopy() const { return m_copy_converters.size() != 0; } const std::vector &Converters::allPaste() const { return m_paste_converters; } Converter *Converters::byName(const char *name) const { auto i = m_converters.find(name); if (i != m_converters.end()){ return i->second; } return nullptr; } Converter *Converters::byName(const std::string &name) const { auto i = m_converters.find(name); if (i != m_converters.end()){ return i->second; } return nullptr; } Converter *Converters::display() const { return m_display_converter; } Converter *Converters::colorList() const { return m_color_list_converter; } Converter *Converters::forType(Type type) const { switch (type) { case Type::display: return m_display_converter; case Type::colorList: return m_color_list_converter; case Type::copy: return m_copy_converters.size() != 0 ? m_copy_converters.front() : nullptr; } return nullptr; } void Converters::display(const char *name) { m_display_converter = byName(name); } void Converters::colorList(const char *name) { m_color_list_converter = byName(name); } void Converters::display(const std::string &name) { m_display_converter = byName(name); } void Converters::colorList(const std::string &name) { m_color_list_converter = byName(name); } void Converters::display(Converter *converter) { m_display_converter = converter; } void Converters::colorList(Converter *converter) { m_color_list_converter = converter; } Converter *Converters::firstCopy() const { if (m_copy_converters.size() == 0) return nullptr; return m_copy_converters.front(); } Converter *Converters::firstCopyOrAny() const { if (m_copy_converters.size() == 0){ if (m_all_converters.size() == 0){ return nullptr; } return m_all_converters.front(); } return m_copy_converters.front(); } Converter *Converters::byNameOrFirstCopy(const char *name) const { if (name){ Converter *result = byName(name); if (result) return result; } if (m_copy_converters.size() == 0) return nullptr; return m_copy_converters.front(); } std::string Converters::serialize(ColorObject *color_object, Type type) { Converter *converter; switch (type){ case Type::colorList: converter = colorList(); break; case Type::display: converter = display(); break; default: converter = nullptr; } if (converter){ return converter->serialize(color_object); } converter = firstCopyOrAny(); if (converter){ return converter->serialize(color_object); } return ""; } std::string Converters::serialize(const Color &color, Type type) { ColorObject color_object("", color); return serialize(&color_object, type); } bool Converters::deserialize(const char *value, ColorObject **output_color_object) { ColorObject color_object; multimap> results; if (m_display_converter){ Converter *converter = m_display_converter; if (converter->hasDeserialize()){ float quality; if (converter->deserialize(value, &color_object, quality)){ if (quality > 0){ results.insert(make_pair(quality, color_object.copy())); } } } } for (auto &converter: m_paste_converters){ if (!converter->hasDeserialize()) continue; float quality; if (converter->deserialize(value, &color_object, quality)){ if (quality > 0){ results.insert(make_pair(quality, color_object.copy())); } } } bool first = true; for (auto result: results){ if (first){ first = false; *output_color_object = result.second; }else{ result.second->release(); } } if (first){ return false; }else{ return true; } } void Converters::reorder(const char **names, size_t count) { set used; vector converters; for (size_t i = 0; i < count; i++){ auto converter = byName(names[i]); if (converter){ used.insert(converter); converters.push_back(converter); } } for (auto converter: m_all_converters){ if (used.count(converter) == 0){ converters.push_back(converter); } } m_all_converters.clear(); m_all_converters = converters; } void Converters::reorder(const std::vector &names) { set used; vector converters; for (size_t i = 0; i < names.size(); i++){ auto converter = byName(names[i]); if (converter){ used.insert(converter); converters.push_back(converter); } } for (auto converter: m_all_converters){ if (used.count(converter) == 0){ converters.push_back(converter); } } m_all_converters.clear(); m_all_converters = converters; } gpick-gpick-0.2.6/source/Converters.h000066400000000000000000000061521377073231300175240ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_CONVERTERS_H_ #define GPICK_CONVERTERS_H_ #include #include #include struct ColorObject; struct Converter; struct Color; struct Converters { enum class Type { display, colorList, copy, }; Converters(); ~Converters(); void add(Converter *converter); const std::vector &all() const; const std::vector &allCopy() const; const std::vector &allPaste() const; Converter *byName(const char *name) const; Converter *byName(const std::string &name) const; Converter *display() const; Converter *colorList() const; Converter *forType(Type type) const; void display(const char *name); void colorList(const char *name); void display(const std::string &name); void colorList(const std::string &name); void display(Converter *converter); void colorList(Converter *converter); Converter *firstCopy() const; Converter *firstCopyOrAny() const; Converter *byNameOrFirstCopy(const char *name) const; std::string serialize(ColorObject *color_object, Type type); std::string serialize(const Color &color, Type type); bool deserialize(const char *value, ColorObject **color_object); void rebuildCopyPasteArrays(); void reorder(const char **names, size_t count); void reorder(const std::vector &names); bool hasCopy() const; private: std::map m_converters; std::vector m_all_converters; std::vector m_copy_converters; std::vector m_paste_converters; Converter *m_display_converter; Converter *m_color_list_converter; }; #endif /* GPICK_CONVERTERS_H_ */ gpick-gpick-0.2.6/source/DragDrop.cpp000066400000000000000000000460501377073231300174300ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "DragDrop.h" #include "ColorObject.h" #include "dynv/Map.h" #include "GlobalState.h" #include "gtk/ColorWidget.h" #include "Converters.h" #include "Converter.h" #include "common/Scoped.h" #include #include #include enum class Target : guint { string = 1, color, colorObjectList, serializedColorObjectList, }; static GtkTargetEntry targets[] = { { const_cast("color-object-list"), GTK_TARGET_SAME_APP, static_cast(Target::colorObjectList) }, { const_cast("application/x-color_object-list"), GTK_TARGET_OTHER_APP, static_cast(Target::serializedColorObjectList) }, { const_cast("application/x-color-object-list"), GTK_TARGET_OTHER_APP, static_cast(Target::serializedColorObjectList) }, { const_cast("application/x-color"), 0, static_cast(Target::color) }, { const_cast("text/plain"), 0, static_cast(Target::string) }, { const_cast("UTF8_STRING"), 0, static_cast(Target::string) }, { const_cast("STRING"), 0, static_cast(Target::string) }, }; static const size_t targetCount = sizeof(targets) / sizeof(GtkTargetEntry); struct ColorObjectList { uintptr_t sourceWidgetId; uint64_t colorObjectCount; ColorObject *colorObject[1]; }; static void drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selectionData, Target targetType, guint time, DragDrop *dd); static gboolean drag_motion(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint t, DragDrop *dd); static void drag_leave(GtkWidget *widget, GdkDragContext *context, guint time, DragDrop *dd); static gboolean drag_drop(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, DragDrop *dd); static void drag_data_delete(GtkWidget *widget, GdkDragContext *context, DragDrop *dd); static void drag_data_get(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selectionData, Target targetType, guint time, DragDrop *dd); static void drag_begin(GtkWidget *widget, GdkDragContext *context, DragDrop *dd); static void drag_end(GtkWidget *widget, GdkDragContext *context, DragDrop *dd); static void drag_destroy(GtkWidget *widget, DragDrop *dd); int dragdrop_init(DragDrop *dd, GlobalState *gs) { dd->get_color_object = 0; dd->set_color_object_at = 0; dd->test_at = 0; dd->data_delete = 0; dd->drag_end = 0; dd->get_color_object_list = 0; dd->set_color_object_list_at = 0; dd->data_type = DragDrop::DATA_TYPE_NONE; memset(&dd->data, 0, sizeof(dd->data)); dd->widget = 0; dd->gs = gs; dd->dragwidget = 0; return 0; } int dragdrop_widget_attach(GtkWidget *widget, DragDropFlags flags, DragDrop *user_dd) { DragDrop *dd = new DragDrop; memcpy(dd, user_dd, sizeof(DragDrop)); dd->widget = widget; if (flags & DRAGDROP_SOURCE) { GtkTargetList *target_list = gtk_drag_source_get_target_list(widget); if (target_list) { gtk_target_list_add_table(target_list, targets, targetCount); } else { target_list = gtk_target_list_new(targets, targetCount); gtk_drag_source_set_target_list(widget, target_list); } g_signal_connect(widget, "drag-data-get", G_CALLBACK(drag_data_get), dd); g_signal_connect(widget, "drag-data-delete", G_CALLBACK(drag_data_delete), dd); g_signal_connect(widget, "drag-begin", G_CALLBACK(drag_begin), dd); g_signal_connect(widget, "drag-end", G_CALLBACK(drag_end), dd); } if (flags & DRAGDROP_DESTINATION) { GtkTargetList *target_list = gtk_drag_dest_get_target_list(widget); if (target_list) { gtk_target_list_add_table(target_list, targets, targetCount); } else { target_list = gtk_target_list_new(targets, targetCount); gtk_drag_dest_set_target_list(widget, target_list); } g_signal_connect(widget, "drag-data-received", G_CALLBACK(drag_data_received), dd); g_signal_connect(widget, "drag-leave", G_CALLBACK(drag_leave), dd); g_signal_connect(widget, "drag-motion", G_CALLBACK(drag_motion), dd); g_signal_connect(widget, "drag-drop", G_CALLBACK(drag_drop), dd); } g_signal_connect(widget, "destroy", G_CALLBACK(drag_destroy), dd); return 0; } static void drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selectionData, Target targetType, guint time, DragDrop *dd) { if ((selectionData == nullptr) || (gtk_selection_data_get_length(selectionData) == 0)) { gtk_drag_finish(context, false, gdk_drag_context_get_actions(context) == GDK_ACTION_MOVE, time); return; } bool success = false; switch (targetType) { case Target::colorObjectList: { ColorObjectList data; memcpy(&data, gtk_selection_data_get_data(selectionData), offsetof(ColorObjectList, colorObject)); bool sameWidget = data.sourceWidgetId == reinterpret_cast(dd->widget); if (data.colorObjectCount > 1) { std::vector colorObjects(data.colorObjectCount); memcpy(&colorObjects.front(), gtk_selection_data_get_data(selectionData) + offsetof(ColorObjectList, colorObject), sizeof(ColorObject *) * data.colorObjectCount); if (dd->set_color_object_list_at) dd->set_color_object_list_at(dd, &colorObjects.front(), data.colorObjectCount, x, y, gdk_drag_context_get_actions(context) & GDK_ACTION_MOVE, sameWidget); else if (dd->set_color_object_at) { memcpy(&data, gtk_selection_data_get_data(selectionData), sizeof(ColorObjectList)); dd->set_color_object_at(dd, data.colorObject[0], x, y, gdk_drag_context_get_actions(context) & GDK_ACTION_MOVE, sameWidget); } } else { if (dd->set_color_object_at) { memcpy(&data, gtk_selection_data_get_data(selectionData), sizeof(ColorObjectList)); dd->set_color_object_at(dd, data.colorObject[0], x, y, gdk_drag_context_get_actions(context) & GDK_ACTION_MOVE, sameWidget); } } } break; case Target::serializedColorObjectList: { auto data = gtk_selection_data_get_data(selectionData); auto text = std::string(reinterpret_cast(data), reinterpret_cast(data) + gtk_selection_data_get_length(selectionData)); std::stringstream textStream(text); dynv::Map values; if (!values.deserializeXml(textStream)) break; auto colors = values.getMaps("colors"); if (colors.size() == 0) break; static Color defaultColor = {}; if (colors.size() == 1) { if (dd->set_color_object_at) { auto *colorObject = new ColorObject(); colorObject->setName(colors[0]->getString("name", "")); colorObject->setColor(colors[0]->getColor("color", defaultColor)); dd->set_color_object_at(dd, colorObject, x, y, false, false); colorObject->release(); success = true; break; } } if (dd->set_color_object_list_at) { size_t colorCount = colors.size(); std::vector colorObjects(colorCount); auto releaseColorObjects = common::makeScoped(std::function([&colorObjects]() { for (auto colorObject: colorObjects) if (colorObject) colorObject->release(); })); for (size_t i = 0; i < colorCount; i++) colorObjects[i] = new ColorObject(colors[i]->getString("name", ""), colors[i]->getColor("color", defaultColor)); dd->set_color_object_list_at(dd, &colorObjects.front(), colorCount, x, y, false, false); success = true; } } break; case Target::string: { gchar *data = (gchar *)gtk_selection_data_get_data(selectionData); if (data[gtk_selection_data_get_length(selectionData)] != 0) break; //not null terminated ColorObject *colorObject = nullptr; if (!dd->gs->converters().deserialize(data, &colorObject)) { gtk_drag_finish(context, false, false, time); return; } dd->set_color_object_at(dd, colorObject, x, y, gdk_drag_context_get_actions(context) & GDK_ACTION_MOVE, false); colorObject->release(); success = true; } break; case Target::color: { guint16 *data = (guint16 *)gtk_selection_data_get_data(selectionData); Color color; color.rgb.red = static_cast(data[0] / static_cast(0xFFFF)); color.rgb.green = static_cast(data[1] / static_cast(0xFFFF)); color.rgb.blue = static_cast(data[2] / static_cast(0xFFFF)); color.ma[3] = 0; auto *colorObject = new ColorObject("", color); dd->set_color_object_at(dd, colorObject, x, y, gdk_drag_context_get_actions(context) & GDK_ACTION_MOVE, false); colorObject->release(); success = true; } break; } gtk_drag_finish(context, success, gdk_drag_context_get_actions(context) == GDK_ACTION_MOVE, time); } static gboolean drag_motion(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, DragDrop *dd) { GdkDragAction suggested_action; bool suggested_action_set = true; bool dragging_moves = dd->gs->settings().getBool("gpick.main.dragging_moves", true); if (dragging_moves) { if ((gdk_drag_context_get_actions(context) & GDK_ACTION_MOVE) == GDK_ACTION_MOVE) suggested_action = GDK_ACTION_MOVE; else if ((gdk_drag_context_get_actions(context) & GDK_ACTION_COPY) == GDK_ACTION_COPY) suggested_action = GDK_ACTION_COPY; else suggested_action_set = false; } else { if ((gdk_drag_context_get_actions(context) & GDK_ACTION_COPY) == GDK_ACTION_COPY) suggested_action = GDK_ACTION_COPY; else if ((gdk_drag_context_get_actions(context) & GDK_ACTION_MOVE) == GDK_ACTION_MOVE) suggested_action = GDK_ACTION_MOVE; else suggested_action_set = false; } if (!dd->test_at) { GdkAtom target = gtk_drag_dest_find_target(widget, context, 0); if (target) { gdk_drag_status(context, suggested_action_set ? suggested_action : gdk_drag_context_get_selected_action(context), time); } else { gdk_drag_status(context, suggested_action_set ? suggested_action : GdkDragAction(0), time); } return true; } if (dd->test_at(dd, x, y)) { GdkAtom target = gtk_drag_dest_find_target(widget, context, 0); if (target) { gdk_drag_status(context, suggested_action_set ? suggested_action : gdk_drag_context_get_selected_action(context), time); } else { gdk_drag_status(context, suggested_action_set ? suggested_action : GdkDragAction(0), time); } } else { gdk_drag_status(context, suggested_action_set ? suggested_action : GdkDragAction(0), time); } return true; } static void drag_leave(GtkWidget *widget, GdkDragContext *context, guint time, DragDrop *dd) { } static gboolean drag_drop(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, DragDrop *dd) { GdkAtom target = gtk_drag_dest_find_target(widget, context, 0); if (target != GDK_NONE) { gtk_drag_get_data(widget, context, target, time); if (dd->drag_end) dd->drag_end(dd, widget, context); return true; } if (dd->drag_end) dd->drag_end(dd, widget, context); return false; } static void drag_data_delete(GtkWidget *widget, GdkDragContext *context, DragDrop *dd) { if (dd->data_delete) { dd->data_delete(dd, widget, context); } } static void drag_data_get(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selectionData, Target targetType, guint time, DragDrop *dd) { if (!selectionData) return; if (dd->data_type == DragDrop::DATA_TYPE_COLOR_OBJECT) { ColorObject *colorObject = dd->data.colorObject.colorObject; if (!colorObject) return; Color color; switch (targetType) { case Target::colorObjectList: { ColorObjectList data; data.sourceWidgetId = reinterpret_cast(dd->widget); data.colorObjectCount = 1; data.colorObject[0] = colorObject; gtk_selection_data_set(selectionData, gdk_atom_intern("colorObject", false), 8, (guchar *)&data, sizeof(data)); } break; case Target::serializedColorObjectList: { std::vector colors; auto color = dynv::Map::create(); color->set("name", colorObject->getName()); color->set("color", colorObject->getColor()); colors.push_back(color); dynv::Map values; values.set("colors", colors); std::stringstream str; values.serializeXml(str); auto data = str.str(); gtk_selection_data_set(selectionData, gdk_atom_intern("application/x-color-object-list", false), 8, reinterpret_cast(&data.front()), data.length()); } break; case Target::string: { auto text = dd->gs->converters().serialize(colorObject, Converters::Type::copy); gtk_selection_data_set_text(selectionData, text.c_str(), text.length() + 1); } break; case Target::color: { color = colorObject->getColor(); guint16 data_color[4]; data_color[0] = int(color.rgb.red * 0xFFFF); data_color[1] = int(color.rgb.green * 0xFFFF); data_color[2] = int(color.rgb.blue * 0xFFFF); data_color[3] = 0xffff; gtk_selection_data_set(selectionData, gdk_atom_intern("application/x-color", false), 16, (guchar *)data_color, 8); } break; } } else if (dd->data_type == DragDrop::DATA_TYPE_COLOR_OBJECTS) { ColorObject **colorObjects = dd->data.colorObjects.colorObjects; uint32_t colorObjectCount = dd->data.colorObjects.colorObjectCount; if (!colorObjects) return; Color color; switch (targetType) { case Target::colorObjectList: { size_t dataLength = offsetof(ColorObjectList, colorObject) + sizeof(ColorObject *) * colorObjectCount; std::vector dataBytes(dataLength); auto data = reinterpret_cast(&dataBytes.front()); data->sourceWidgetId = reinterpret_cast(dd->widget); data->colorObjectCount = colorObjectCount; memcpy(&data->colorObject[0], colorObjects, sizeof(ColorObject *) * colorObjectCount); gtk_selection_data_set(selectionData, gdk_atom_intern("color-object", false), 8, reinterpret_cast(&dataBytes.front()), dataLength); } break; case Target::serializedColorObjectList: { std::vector colors; colors.reserve(colorObjectCount); for (uint32_t i = 0; i < colorObjectCount; i++) { auto color = dynv::Map::create(); color->set("name", colorObjects[i]->getName()); color->set("color", colorObjects[i]->getColor()); colors.push_back(color); } dynv::Map values; values.set("colors", colors); std::stringstream str; values.serializeXml(str); auto data = str.str(); gtk_selection_data_set(selectionData, gdk_atom_intern("application/x-color-object-list", false), 8, (guchar *)&data.front(), data.length()); } break; case Target::string: { std::stringstream ss; auto converter = dd->gs->converters().firstCopy(); if (converter) { for (uint32_t i = 0; i != colorObjectCount; i++) { ss << converter->serialize(colorObjects[i]) << "\n"; } } std::string text = ss.str(); gtk_selection_data_set_text(selectionData, text.c_str(), text.length() + 1); } break; case Target::color: { ColorObject *colorObject = colorObjects[0]; color = colorObject->getColor(); guint16 data_color[4]; data_color[0] = int(color.rgb.red * 0xFFFF); data_color[1] = int(color.rgb.green * 0xFFFF); data_color[2] = int(color.rgb.blue * 0xFFFF); data_color[3] = 0xffff; gtk_selection_data_set(selectionData, gdk_atom_intern("application/x-color", false), 16, (guchar *)data_color, 8); } break; } } } static void drag_begin(GtkWidget *widget, GdkDragContext *context, DragDrop *dd) { if (dd->get_color_object_list) { size_t colorObjectCount; auto colorObjects = dd->get_color_object_list(dd, &colorObjectCount); if (colorObjects) { dd->data_type = DragDrop::DATA_TYPE_COLOR_OBJECTS; dd->data.colorObjects.colorObjects = colorObjects; dd->data.colorObjects.colorObjectCount = colorObjectCount; auto dragWindow = gtk_window_new(GTK_WINDOW_POPUP); auto hbox = gtk_vbox_new(true, 0); gtk_container_add(GTK_CONTAINER(dragWindow), hbox); auto showColors = std::min(colorObjectCount, 5); gtk_widget_set_size_request(dragWindow, 164, 24 * showColors); auto converter = dd->gs->converters().forType(dd->converterType); if (converter) { for (size_t i = 0; i < showColors; i++) { auto colorWidget = gtk_color_new(); auto text = converter ? converter->serialize(colorObjects[i]) : ""; Color color = colorObjects[i]->getColor(); gtk_color_set_color(GTK_COLOR(colorWidget), &color, text.c_str()); gtk_box_pack_start(GTK_BOX(hbox), colorWidget, true, true, 0); } } gtk_drag_set_icon_widget(context, dragWindow, 0, 0); gtk_widget_show_all(dragWindow); dd->dragwidget = dragWindow; return; } } if (dd->get_color_object) { ColorObject *colorObject = dd->get_color_object(dd); if (colorObject) { dd->data_type = DragDrop::DATA_TYPE_COLOR_OBJECT; dd->data.colorObject.colorObject = colorObject; auto dragWindow = gtk_window_new(GTK_WINDOW_POPUP); auto colorWidget = gtk_color_new(); gtk_container_add(GTK_CONTAINER(dragWindow), colorWidget); gtk_widget_set_size_request(dragWindow, 164, 24); auto text = dd->gs->converters().serialize(colorObject, dd->converterType); Color color = colorObject->getColor(); gtk_color_set_color(GTK_COLOR(colorWidget), &color, text.c_str()); gtk_drag_set_icon_widget(context, dragWindow, 0, 0); gtk_widget_show_all(dragWindow); dd->dragwidget = dragWindow; return; } } } static void drag_end(GtkWidget *widget, GdkDragContext *context, DragDrop *dd) { if (dd->data_type == DragDrop::DATA_TYPE_COLOR_OBJECT) { if (dd->data.colorObject.colorObject) { dd->data.colorObject.colorObject->release(); memset(&dd->data, 0, sizeof(dd->data)); } dd->data_type = DragDrop::DATA_TYPE_NONE; } if (dd->data_type == DragDrop::DATA_TYPE_COLOR_OBJECTS) { if (dd->data.colorObjects.colorObjects) { for (uint32_t i = 0; i < dd->data.colorObjects.colorObjectCount; i++) { dd->data.colorObjects.colorObjects[i]->release(); } delete[] dd->data.colorObjects.colorObjects; memset(&dd->data, 0, sizeof(dd->data)); } dd->data_type = DragDrop::DATA_TYPE_NONE; } if (dd->dragwidget) { gtk_widget_destroy(dd->dragwidget); dd->dragwidget = 0; } if (dd->drag_end) dd->drag_end(dd, widget, context); } static void drag_destroy(GtkWidget *widget, DragDrop *dd) { delete dd; } gpick-gpick-0.2.6/source/DragDrop.h000066400000000000000000000056011377073231300170720ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_DRAG_DROP_H_ #define GPICK_DRAG_DROP_H_ #include "Converters.h" #include struct GlobalState; struct ColorObject; enum DragDropFlags { DRAGDROP_SOURCE = 1 << 1, DRAGDROP_DESTINATION = 1 << 2, }; struct DragDrop { GtkWidget *widget; void *userdata; ColorObject *(*get_color_object)(DragDrop *dd); int (*set_color_object_at)(DragDrop *dd, ColorObject *colorobject, int x, int y, bool move, bool sameWidget); ColorObject **(*get_color_object_list)(DragDrop *dd, size_t *colorobject_n); int (*set_color_object_list_at)(DragDrop *dd, ColorObject **colorobject, size_t colorobject_n, int x, int y, bool move, bool sameWidget); bool (*test_at)(DragDrop *dd, int x, int y); bool (*data_delete)(DragDrop *dd, GtkWidget *widget, GdkDragContext *context); bool (*drag_end)(DragDrop *dd, GtkWidget *widget, GdkDragContext *context); enum DataType { DATA_TYPE_NONE, DATA_TYPE_COLOR_OBJECT, DATA_TYPE_COLOR_OBJECTS, }; DataType data_type; Converters::Type converterType; union { struct { ColorObject *colorObject; } colorObject; struct { ColorObject **colorObjects; size_t colorObjectCount; } colorObjects; } data; GtkWidget *dragwidget; GlobalState *gs; void *userdata2; }; int dragdrop_init(DragDrop *dd, GlobalState *gs); int dragdrop_widget_attach(GtkWidget *widget, DragDropFlags flags, DragDrop *dd); #endif /* GPICK_DRAG_DROP_H_ */ gpick-gpick-0.2.6/source/ErrorCode.cpp000066400000000000000000000037301377073231300176100ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ErrorCode.h" #include #define E(a, b) case ErrorCode::a: stream << b; break; std::ostream &operator<<(std::ostream &stream, const ErrorCode &errorCode) { switch (errorCode) { E(invalidArguments, "invalid arguments") E(fileCouldNotBeOpened, "file could not be opened") E(writeFailed, "write failed") E(readFailed, "read failed") E(badHeader, "bad header") E(badVersion, "bad version") E(badFile, "bad file") } return stream; } gpick-gpick-0.2.6/source/ErrorCode.h000066400000000000000000000035171377073231300172600ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_ERROR_CODE_H_ #define GPICK_ERROR_CODE_H_ #include enum class ErrorCode : int { invalidArguments, fileCouldNotBeOpened, writeFailed, readFailed, badHeader, badVersion, badFile, }; std::ostream &operator<<(std::ostream &stream, const ErrorCode &errorCode); #endif /* GPICK_ERROR_CODE_H_ */ gpick-gpick-0.2.6/source/FileFormat.cpp000066400000000000000000000250301377073231300177510ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "FileFormat.h" #include "ColorObject.h" #include "ColorList.h" #include "ErrorCode.h" #include "dynv/Map.h" #include "common/Scoped.h" #include "common/Result.h" #include "version/Version.h" #include #include #include #include #include #include #define CHUNK_TYPE_VERSION "GPA version" #define CHUNK_TYPE_HANDLER_MAP "handler_map" #define CHUNK_TYPE_COLOR_LIST "color_list" #define CHUNK_TYPE_COLOR_POSITIONS "color_positions" #define CHUNK_TYPE_COLOR_ACTIONS "color_actions" const uint32_t Version = static_cast(1 * 0x10000 + 0); struct ChunkHeader { void prepareWrite(const std::string &type, uint64_t size) { size_t length = type.length(); if (length >= sizeof(m_type)) length = sizeof(m_type) - 1; memcpy(m_type, type.c_str(), length); memset(m_type + length, 0, sizeof(m_type) - length); m_size = boost::endian::native_to_little(size); } void prepareRead() { m_size = boost::endian::little_to_native(m_size); } bool valid() const { if (m_type[sizeof(m_type) - 1] != 0) return false; return true; } uint64_t size() const { return m_size; } bool is(const std::string &type) const { return m_type == type; } bool startsWith(const std::string &type) const { return boost::starts_with(m_type, type); } private: char m_type[16]; uint64_t m_size; }; static bool colorObjectPositionSort(ColorObject* x, ColorObject* y) { return x->getPosition() < y->getPosition(); } static bool read(std::istream &stream, ChunkHeader &header) { stream.read(reinterpret_cast(&header), sizeof(header)); header.prepareRead(); return stream.good(); } static bool read(std::istream &stream, uint32_t &value) { stream.read(reinterpret_cast(&value), sizeof(value)); value = boost::endian::little_to_native(value); return stream.good(); } static bool read(std::istream &stream, std::string &value) { uint32_t length; if (!read(stream, length)) return false; value.resize(length); stream.read(reinterpret_cast(&value.front()), length); return stream.good(); } common::ResultVoid paletteFileLoad(const char* filename, ColorList* colorList) { using Result = common::ResultVoid; std::ifstream file(filename, std::ios::binary); if (!file.is_open()) return Result(ErrorCode::fileCouldNotBeOpened); ChunkHeader header; if (!read(file, header) || !header.valid() || !header.startsWith(CHUNK_TYPE_VERSION)) return Result(ErrorCode::readFailed); if (header.size() < 4) return Result(ErrorCode::badHeader); uint32_t version; if (!read(file, version)) return Result(ErrorCode::readFailed); if (version != Version) return Result(ErrorCode::badVersion); file.seekg(header.size() - 4, std::ios::cur); if (!file.good()) return Result(ErrorCode::readFailed); if (!read(file, header) || !header.valid()) { return file.eof() ? Result() : Result(ErrorCode::readFailed); } std::vector colorObjects; auto releaseColorObjects = common::makeScoped(std::function([&colorObjects]() { for (auto colorObject: colorObjects) if (colorObject) colorObject->release(); })); std::vector positions; std::unordered_map typeMap; std::vector handlers; bool hasPositions = false; for (;;) { if (header.is(CHUNK_TYPE_HANDLER_MAP)) { uint32_t handlerCount; if (!read(file, handlerCount)) return Result(ErrorCode::readFailed); if (handlerCount > 255) return Result(ErrorCode::badFile); for (size_t i = 0; i < handlerCount; i++) { std::string typeName; if (!read(file, typeName)) return Result(ErrorCode::readFailed); typeMap[static_cast(handlers.size())] = dynv::types::stringToType(typeName); handlers.push_back(typeName); } } else if (header.is(CHUNK_TYPE_COLOR_LIST)) { std::streamoff end = file.tellg() + static_cast(header.size()); while (file.tellg() < end) { dynv::Map options; if (!options.deserialize(file, typeMap)) return file.good() ? Result(ErrorCode::badFile) : Result(ErrorCode::readFailed); auto color = options.getColor("color", Color()); auto name = options.getString("name", ""); colorObjects.push_back(new ColorObject(name, color)); } } else if (header.is(CHUNK_TYPE_COLOR_POSITIONS)) { hasPositions = true; positions.resize(header.size() / sizeof(uint32_t)); file.read(reinterpret_cast(&positions.front()), positions.size() * sizeof(uint32_t)); if (!file.good()) return Result(ErrorCode::readFailed); for (auto &position: positions) { position = boost::endian::little_to_native(position); } } else { file.seekg(header.size(), std::ios::cur); if (file.eof()) break; if (!file.good()) return Result(ErrorCode::readFailed); } if (!read(file, header) || !header.valid()) { if (file.eof()) break; else return Result(ErrorCode::readFailed); } } if (hasPositions) { for (size_t i = 0, end = std::min(colorObjects.size(), positions.size()); i < end; i++) { colorObjects[i]->setPosition(positions[i]); } std::sort(colorObjects.begin(), colorObjects.end(), colorObjectPositionSort); } for (auto colorObject: colorObjects) { bool visible = hasPositions ? colorObject->getPosition() != ~(size_t)0 : true; colorObject->setVisible(visible); color_list_add_color_object(colorList, colorObject, visible); } file.close(); return (file.good() || file.eof()) ? Result() : Result(ErrorCode::readFailed); } static bool write(std::ostream &stream, uint32_t value) { auto data = boost::endian::native_to_little(value); static_assert(sizeof(data) == 4); stream.write(reinterpret_cast(&data), sizeof(uint32_t)); return stream.good(); } static bool write(std::ostream &stream, const ChunkHeader &header) { static_assert(sizeof(header) == 24); stream.write(reinterpret_cast(&header), sizeof(header)); return stream.good(); } static bool write(std::ostream &stream, const std::string &value) { if (!write(stream, static_cast(value.length()))) return false; stream.write(reinterpret_cast(&value.front()), value.length()); return stream.good(); } common::ResultVoid paletteFileSave(const char* filename, ColorList* colorList) { using Result = common::ResultVoid; if (!filename || !colorList) return Result(ErrorCode::invalidArguments); std::ofstream file(filename, std::ios::binary); if (!file.is_open()) return Result(ErrorCode::fileCouldNotBeOpened); ChunkHeader header; header.prepareWrite(std::string(CHUNK_TYPE_VERSION) + " " + gpick_build_version, 4); if (!write(file, header)) return Result(ErrorCode::writeFailed); if (!write(file, Version)) // file format version return Result(ErrorCode::writeFailed); auto handlerMapPosition = file.tellp(); if (!write(file, header)) // write temporary chunk header return Result(ErrorCode::writeFailed); if (!write(file, static_cast(2))) // handler count for colors return Result(ErrorCode::writeFailed); std::unordered_map typeMap; typeMap[dynv::types::typeHandler().type] = 0; if (!write(file, dynv::types::typeHandler().name)) return Result(ErrorCode::writeFailed); typeMap[dynv::types::typeHandler().type] = 1; if (!write(file, dynv::types::typeHandler().name)) return Result(ErrorCode::writeFailed); auto endPosition = file.tellp(); file.seekp(handlerMapPosition); header.prepareWrite(CHUNK_TYPE_HANDLER_MAP, endPosition - handlerMapPosition - sizeof(ChunkHeader)); if (!write(file, header)) // write type handler chunk header return Result(ErrorCode::writeFailed); file.seekp(endPosition); auto colorListPosition = file.tellp(); if (!write(file, header)) // write temporary chunk header return Result(ErrorCode::writeFailed); dynv::Map options; for (auto colorObject: colorList->colors) { options.set("name", colorObject->getName()); options.set("color", colorObject->getColor()); if (!options.serialize(file, typeMap)) return Result(ErrorCode::writeFailed); } endPosition = file.tellp(); file.seekp(colorListPosition); header.prepareWrite(CHUNK_TYPE_COLOR_LIST, endPosition - colorListPosition - sizeof(ChunkHeader)); if (!write(file, header)) // write color list chunk header return Result(ErrorCode::writeFailed); file.seekp(endPosition); color_list_get_positions(colorList); std::vector positions(colorList->colors.size()); size_t i = 0; for (auto color: colorList->colors) { positions[i++] = boost::endian::native_to_little(color->getPosition()); } header.prepareWrite(CHUNK_TYPE_COLOR_POSITIONS, positions.size() * sizeof(uint32_t)); if (!write(file, header)) // write positions chunk header return Result(ErrorCode::writeFailed); file.write(reinterpret_cast(&positions.front()), positions.size() * sizeof(uint32_t)); if (!file.good()) return Result(ErrorCode::writeFailed); file.close(); return file.good() ? Result() : Result(ErrorCode::writeFailed); } gpick-gpick-0.2.6/source/FileFormat.h000066400000000000000000000035501377073231300174210ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_FILE_FORMAT_H_ #define GPICK_FILE_FORMAT_H_ #include "common/Result.h" #include "ErrorCode.h" struct ColorList; common::ResultVoid paletteFileSave(const char *filename, ColorList *color_list); common::ResultVoid paletteFileLoad(const char *filename, ColorList *color_list); #endif /* GPICK_FILE_FORMAT_H_ */ gpick-gpick-0.2.6/source/FloatingPicker.cpp000066400000000000000000000347751377073231300206420ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "FloatingPicker.h" #include "ColorObject.h" #include "ColorList.h" #include "gtk/Zoomed.h" #include "gtk/ColorWidget.h" #include "uiUtilities.h" #include "Clipboard.h" #include "StandardMenu.h" #include "GlobalState.h" #include "ColorPicker.h" #include "Converters.h" #include "Converter.h" #include "dynv/Map.h" #include "ToolColorNaming.h" #include "ScreenReader.h" #include "Sampler.h" #include "color_names/ColorNames.h" #include "common/SetOnScopeEnd.h" #include #include #include using namespace math; using namespace std; typedef struct FloatingPickerArgs { GtkWidget* window; GtkWidget* zoomed; GtkWidget* color_widget; guint timeout_source_id; ColorSource *color_source; Converter *converter; GlobalState* gs; bool release_mode; bool single_pick_mode; bool click_mode; bool perform_custom_pick_action; bool menu_button_pressed; function custom_pick_action; function custom_done_action; }FloatingPickerArgs; struct PickerColorNameAssigner: public ToolColorNameAssigner { protected: stringstream m_stream; public: PickerColorNameAssigner(GlobalState *gs): ToolColorNameAssigner(gs) { } void assign(ColorObject *color_object, const Color *color) { ToolColorNameAssigner::assign(color_object, color); } virtual std::string getToolSpecificName(ColorObject *color_object, const Color *color) { m_stream.str(""); m_stream << color_names_get(m_gs->getColorNames(), color, false); return m_stream.str(); } }; static void get_color_sample(FloatingPickerArgs *args, bool update_widgets, Color* c) { GdkScreen *screen; GdkModifierType state; int x, y; gdk_display_get_pointer(gdk_display_get_default(), &screen, &x, &y, &state); int monitor = gdk_screen_get_monitor_at_point(screen, x, y); GdkRectangle monitor_geometry; gdk_screen_get_monitor_geometry(screen, monitor, &monitor_geometry); Vec2 pointer(x,y); Rect2 screen_rect(monitor_geometry.x, monitor_geometry.y, monitor_geometry.x + monitor_geometry.width, monitor_geometry.y + monitor_geometry.height); auto screen_reader = args->gs->getScreenReader(); screen_reader_reset_rect(screen_reader); Rect2 sampler_rect, zoomed_rect, final_rect; sampler_get_screen_rect(args->gs->getSampler(), pointer, screen_rect, &sampler_rect); screen_reader_add_rect(screen_reader, screen, sampler_rect); if (update_widgets){ gtk_zoomed_get_screen_rect(GTK_ZOOMED(args->zoomed), pointer, screen_rect, &zoomed_rect); screen_reader_add_rect(screen_reader, screen, zoomed_rect); } screen_reader_update_surface(screen_reader, &final_rect); Vec2 offset; offset = sampler_rect.position() - final_rect.position(); sampler_get_color_sample(args->gs->getSampler(), pointer, screen_rect, offset, c); if (update_widgets){ offset = final_rect.position() - zoomed_rect.position(); gtk_zoomed_update(GTK_ZOOMED(args->zoomed), pointer, screen_rect, offset, screen_reader_get_surface(screen_reader)); } } static gboolean update_display(FloatingPickerArgs *args) { GdkScreen *screen; GdkModifierType state; int x, y; int width, height; gdk_display_get_pointer(gdk_display_get_default(), &screen, &x, &y, &state); width = gdk_screen_get_width(screen); height = gdk_screen_get_height(screen); gint sx, sy; gtk_window_get_size(GTK_WINDOW(args->window), &sx, &sy); if (x + sx + sx / 2 > width){ x -= sx + sx / 2; }else{ x += sx / 2; } if (y + sy + sy / 2 > height){ y -= sy + sy / 2; }else{ y += sy / 2; } if (gtk_window_get_screen(GTK_WINDOW(args->window)) != screen){ gtk_window_set_screen(GTK_WINDOW(args->window), screen); } gtk_window_move(GTK_WINDOW(args->window), x, y); Color c; get_color_sample(args, true, &c); string text; auto converter = args->converter; if (!converter){ converter = args->gs->converters().display(); } if (converter) text = converter->serialize(c); gtk_color_set_color(GTK_COLOR(args->color_widget), &c, text.c_str()); return true; } void floating_picker_activate(FloatingPickerArgs *args, bool hide_on_mouse_release, bool single_pick_mode, const char *converter_name) { #ifndef WIN32 //Pointer grabbing in Windows is broken, disabling floating picker for now if (converter_name != nullptr){ args->converter = args->gs->converters().byName(converter_name); }else{ args->converter = nullptr; } args->release_mode = hide_on_mouse_release && !single_pick_mode; args->single_pick_mode = single_pick_mode; args->click_mode = true; GdkCursor* cursor; if (args->gs->settings().getBool("gpick.picker.hide_cursor", false)) cursor = gdk_cursor_new(GDK_BLANK_CURSOR); else cursor = gdk_cursor_new(GDK_TCROSS); update_display(args); gtk_widget_show(args->window); gdk_pointer_grab(gtk_widget_get_window(args->window), false, GdkEventMask(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_SCROLL_MASK), nullptr, cursor, GDK_CURRENT_TIME); gdk_keyboard_grab(gtk_widget_get_window(args->window), false, GDK_CURRENT_TIME); auto refresh_rate = args->gs->settings().getInt32("gpick.picker.refresh_rate", 30); args->timeout_source_id = g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, static_cast(1000 / refresh_rate), (GSourceFunc)update_display, args, (GDestroyNotify)nullptr); #if GTK_MAJOR_VERSION >= 3 g_object_unref(cursor); #else gdk_cursor_unref(cursor); #endif #endif } void floating_picker_deactivate(FloatingPickerArgs *args) { gdk_pointer_ungrab(GDK_CURRENT_TIME); gdk_keyboard_ungrab(GDK_CURRENT_TIME); if (args->timeout_source_id > 0){ g_source_remove(args->timeout_source_id); args->timeout_source_id = 0; } gtk_widget_hide(args->window); } static gboolean scroll_event_cb(GtkWidget *widget, GdkEventScroll *event, FloatingPickerArgs *args) { float zoom = static_cast(gtk_zoomed_get_zoom(GTK_ZOOMED(args->zoomed))); if ((event->direction == GDK_SCROLL_UP) || (event->direction == GDK_SCROLL_RIGHT)) { zoom += 1; gtk_zoomed_set_zoom(GTK_ZOOMED(args->zoomed), zoom); } else if ((event->direction == GDK_SCROLL_DOWN) || (event->direction == GDK_SCROLL_LEFT)) { zoom -= 1; gtk_zoomed_set_zoom(GTK_ZOOMED(args->zoomed), zoom); } else return false; return true; } static void finish_picking(FloatingPickerArgs *args) { floating_picker_deactivate(args); args->gs->settings().set("gpick.floating_picker.zoom", static_cast(gtk_zoomed_get_zoom(GTK_ZOOMED(args->zoomed)))); if (args->custom_done_action) args->custom_done_action(args); } static void complete_picking(FloatingPickerArgs *args) { if (args->release_mode || args->click_mode){ Color c; get_color_sample(args, false, &c); if (args->perform_custom_pick_action){ if (args->custom_pick_action) args->custom_pick_action(args, c); }else{ ColorObject* color_object; color_object = color_list_new_color_object(args->gs->getColorList(), &c); if (args->single_pick_mode){ clipboard::set(color_object, args->gs, args->converter); }else{ if (args->gs->settings().getBool("gpick.picker.sampler.copy_on_release", true)){ clipboard::set(color_object, args->gs, args->converter); } if (args->gs->settings().getBool("gpick.picker.sampler.add_on_release", true)){ PickerColorNameAssigner name_assigner(args->gs); name_assigner.assign(color_object, &c); color_list_add_color_object(args->gs->getColorList(), color_object, 1); } if (args->gs->settings().getBool("gpick.picker.sampler.add_to_swatch_on_release", true)){ color_picker_set_current_color(args->color_source); } if (args->gs->settings().getBool("gpick.picker.sampler.rotate_swatch_on_release", true)){ color_picker_rotate_swatch(args->color_source); } } color_object->release(); } } } static void show_copy_menu(int button, int event_time, FloatingPickerArgs *args) { Color color; get_color_sample(args, false, &color); auto menu = StandardMenu::newMenu(color, args->gs); showContextMenu(menu, nullptr); } static gboolean button_release_cb(GtkWidget *widget, GdkEventButton *event, FloatingPickerArgs *args) { if ((event->type == GDK_BUTTON_RELEASE) && (event->button == 1)) { complete_picking(args); finish_picking(args); }else if ((event->type == GDK_BUTTON_RELEASE) && (event->button == 3) && args->menu_button_pressed) { args->menu_button_pressed = false; show_copy_menu(event->button, event->time, args); finish_picking(args); } return false; } static gboolean button_press_cb(GtkWidget *widget, GdkEventButton *event, FloatingPickerArgs *args) { if ((event->type == GDK_BUTTON_PRESS) && (event->button == 3)) { args->menu_button_pressed = true; } return false; } static gboolean key_up_cb(GtkWidget *widget, GdkEventKey *event, FloatingPickerArgs *args) { guint modifiers = gtk_accelerator_get_default_mod_mask(); gint add_x = 0, add_y = 0; auto key = getKeyval(*event, args->gs->latinKeysGroup); switch (key) { case GDK_KEY_Return: complete_picking(args); finish_picking(args); return true; case GDK_KEY_Escape: finish_picking(args); return true; case GDK_KEY_m: { int x, y; gdk_display_get_pointer(gdk_display_get_default(), nullptr, &x, &y, nullptr); math::Vec2 position(x, y); if ((event->state & modifiers) == GDK_CONTROL_MASK) { gtk_zoomed_set_mark(GTK_ZOOMED(args->zoomed), 1, position); }else{ gtk_zoomed_set_mark(GTK_ZOOMED(args->zoomed), 0, position); } } break; case GDK_KEY_Left: if ((event->state & modifiers) == GDK_SHIFT_MASK) add_x -= 10; else add_x--; break; case GDK_KEY_Right: if ((event->state & modifiers) == GDK_SHIFT_MASK) add_x += 10; else add_x++; break; case GDK_KEY_Up: if ((event->state & modifiers) == GDK_SHIFT_MASK) add_y -= 10; else add_y--; break; case GDK_KEY_Down: if ((event->state & modifiers) == GDK_SHIFT_MASK) add_y += 10; else add_y++; break; } if (args->color_source) { common::SetOnScopeEnd disableReleaseMode(args->release_mode, false); switch (key) { case GDK_KEY_space: color_picker_pick(args->color_source); return true; case GDK_KEY_a: color_picker_add_to_palette(args->color_source); return true; case GDK_KEY_c: if ((event->state & modifiers) == GDK_CONTROL_MASK) { color_picker_copy(args->color_source); return true; } break; case GDK_KEY_1: case GDK_KEY_2: case GDK_KEY_3: case GDK_KEY_4: case GDK_KEY_5: case GDK_KEY_6: color_picker_set(args->color_source, key - GDK_KEY_1); return true; default: disableReleaseMode.cancel(); // pick/copy/add/set key was not pressed, keep release mode value } } if (add_x || add_y){ gint x, y; GdkDisplay *display = nullptr; GdkScreen *screen = nullptr; display = gdk_display_get_default(); screen = gdk_display_get_default_screen(display); gdk_display_get_pointer(display, nullptr, &x, &y, nullptr); x += add_x; y += add_y; gdk_display_warp_pointer(display, screen, x, y); } return FALSE; } static void destroy_cb(GtkWidget *widget, FloatingPickerArgs *args) { delete args; } FloatingPickerArgs* floating_picker_new(GlobalState *gs) { FloatingPickerArgs *args = new FloatingPickerArgs; args->timeout_source_id = 0; args->gs = gs; args->window = gtk_window_new(GTK_WINDOW_POPUP); args->color_source = nullptr; args->perform_custom_pick_action = false; args->menu_button_pressed = false; gtk_window_set_skip_pager_hint(GTK_WINDOW(args->window), true); gtk_window_set_skip_taskbar_hint(GTK_WINDOW(args->window), true); gtk_window_set_decorated(GTK_WINDOW(args->window), false); gtk_widget_set_size_request(args->window, -1, -1); GtkWidget* vbox = gtk_vbox_new(0, 0); gtk_container_add (GTK_CONTAINER(args->window), vbox); gtk_widget_show(vbox); args->zoomed = gtk_zoomed_new(); gtk_zoomed_set_zoom(GTK_ZOOMED(args->zoomed), gs->settings().getInt32("gpick.floating_picker.zoom", 20)); gtk_widget_show(args->zoomed); gtk_box_pack_start(GTK_BOX(vbox), args->zoomed, false, false, 0); args->color_widget = gtk_color_new(); gtk_widget_show(args->color_widget); gtk_box_pack_start(GTK_BOX(vbox), args->color_widget, true, true, 0); g_signal_connect(G_OBJECT(args->window), "scroll_event", G_CALLBACK(scroll_event_cb), args); g_signal_connect(G_OBJECT(args->window), "button-press-event", G_CALLBACK(button_press_cb), args); g_signal_connect(G_OBJECT(args->window), "button-release-event", G_CALLBACK(button_release_cb), args); g_signal_connect(G_OBJECT(args->window), "key_press_event", G_CALLBACK(key_up_cb), args); g_signal_connect(G_OBJECT(args->window), "destroy", G_CALLBACK(destroy_cb), args); return args; } void floating_picker_set_picker_source(FloatingPickerArgs *args, ColorSource* color_source) { args->color_source = color_source; } void floating_picker_free(FloatingPickerArgs *args) { gtk_widget_destroy(args->window); } void floating_picker_enable_custom_pick_action(FloatingPickerArgs *args) { args->perform_custom_pick_action = true; } void floating_picker_set_custom_pick_action(FloatingPickerArgs *args, std::function action) { args->custom_pick_action = action; } void floating_picker_set_custom_done_action(FloatingPickerArgs *args, std::function action) { args->custom_done_action = action; } gpick-gpick-0.2.6/source/FloatingPicker.h000066400000000000000000000046211377073231300202720ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_FLOATING_PICKER_H_ #define GPICK_FLOATING_PICKER_H_ struct Color; #include struct GlobalState; struct ColorSource; typedef struct FloatingPickerArgs* FloatingPicker; FloatingPicker floating_picker_new(GlobalState *gs); void floating_picker_set_picker_source(FloatingPicker fp, ColorSource* color_source); void floating_picker_free(FloatingPicker fp); void floating_picker_activate(FloatingPicker fp, bool hide_on_mouse_release, bool single_pick_mode, const char *converter_name); void floating_picker_deactivate(FloatingPicker fp); void floating_picker_set_custom_pick_action(FloatingPicker fp, std::function action); void floating_picker_set_custom_done_action(FloatingPicker fp, std::function action); void floating_picker_enable_custom_pick_action(FloatingPicker fp); #endif /* GPICK_FLOATING_PICKER_H_ */ gpick-gpick-0.2.6/source/GenerateScheme.cpp000066400000000000000000000617401377073231300206100ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "GenerateScheme.h" #include "ColorObject.h" #include "ColorSourceManager.h" #include "ColorSource.h" #include "DragDrop.h" #include "GlobalState.h" #include "ToolColorNaming.h" #include "uiUtilities.h" #include "MathUtil.h" #include "ColorRYB.h" #include "ColorList.h" #include "gtk/ColorWidget.h" #include "gtk/ColorWheel.h" #include "ColorWheelType.h" #include "Converters.h" #include "dynv/Map.h" #include "I18N.h" #include "Random.h" #include "StandardEventHandler.h" #include "IMenuExtension.h" #include "color_names/ColorNames.h" #include #include const int MaxColors = 6; const SchemeType types[] = { { N_("Complementary"), 1, 1, { 180 } }, { N_("Analogous"), 5, 1, { 30 } }, { N_("Triadic"), 2, 1, { 120 } }, { N_("Split-Complementary"), 2, 2, { 150, 60 } }, { N_("Rectangle (tetradic)"), 3, 2, { 60, 120 } }, { N_("Square"), 3, 1, { 90 } }, { N_("Neutral"), 5, 1, { 15 } }, { N_("Clash"), 2, 2, { 90, 180 } }, { N_("Five-Tone"), 4, 4, { 115, 40, 50, 40 } }, { N_("Six-Tone"), 5, 2, { 30, 90 } }, }; struct GenerateSchemeColorNameAssigner: public ToolColorNameAssigner { GenerateSchemeColorNameAssigner(GlobalState *gs): ToolColorNameAssigner(gs) { } void assign(ColorObject *colorObject, const Color *color, int ident, int schemeType) { m_ident = ident; m_schemeType = schemeType; ToolColorNameAssigner::assign(colorObject, color); } virtual std::string getToolSpecificName(ColorObject *colorObject, const Color *color) { m_stream.str(""); m_stream << _("scheme") << " " << _(generate_scheme_get_scheme_type(m_schemeType)->name) << " #" << m_ident << "[" << color_names_get(m_gs->getColorNames(), color, false) << "]"; return m_stream.str(); } protected: std::stringstream m_stream; int m_ident; int m_schemeType; }; struct GenerateSchemeArgs { ColorSource source; GtkWidget *main, *statusBar, *generationType, *wheelTypeCombo, *colorWheel, *hueRange, *saturationRange, *lightnessRange, *colorPreviews, *lastFocusedColor; struct { GtkWidget *widget; float colorHue, hueShift, saturationShift, valueShift, originalHue, originalSaturation, originalValue; } items[MaxColors]; bool wheelLocked; int colorsVisible; dynv::Ref options; GlobalState *gs; void addToPalette() { color_list_add_color_object(gs->getColorList(), getColor(), true); } void addToPalette(GenerateSchemeColorNameAssigner &nameAssigner, Color &color, GtkWidget *widget) { gtk_color_get_color(GTK_COLOR(widget), &color); colorObject.setColor(color); int type = gtk_combo_box_get_active(GTK_COMBO_BOX(generationType)); nameAssigner.assign(&colorObject, &color, identifyColorWidget(widget), type); color_list_add_color_object(gs->getColorList(), colorObject, true); } void addAllToPalette() { GenerateSchemeColorNameAssigner nameAssigner(gs); Color color; for (int i = 0; i < colorsVisible; ++i) addToPalette(nameAssigner, color, items[i].widget); } void setColor(const ColorObject &colorObject) { int index = 0; for (int i = 0; i < colorsVisible; ++i) { if (items[i].widget == lastFocusedColor) { index = i; break; } } Color color = colorObject.getColor(); float hue, saturation, lightness, shiftedHue; Color hsl, hsv, hslResult; color_rgb_to_hsv(&color, &hsv); color_hsv_to_hsl(&hsv, &hsl); int wheelType = gtk_combo_box_get_active(GTK_COMBO_BOX(wheelTypeCombo)); auto &wheel = color_wheel_types_get()[wheelType]; double tmp; wheel.rgbhue_to_hue(hsl.hsl.hue, &tmp); hue = static_cast(tmp); shiftedHue = wrap_float(hue - items[index].colorHue - items[index].hueShift); wheel.hue_to_hsl(hue, &hslResult); saturation = hsl.hsl.saturation * 1 / hslResult.hsl.saturation; lightness = hsl.hsl.lightness - hslResult.hsl.lightness; shiftedHue *= 360.0f; saturation *= 100.0f; lightness *= 100.0f; gtk_range_set_value(GTK_RANGE(hueRange), shiftedHue); gtk_range_set_value(GTK_RANGE(saturationRange), saturation); gtk_range_set_value(GTK_RANGE(lightnessRange), lightness); update(); } ColorObject colorObject; const ColorObject &getColor() { Color color; gtk_color_get_color(GTK_COLOR(lastFocusedColor), &color); colorObject.setColor(color); GenerateSchemeColorNameAssigner nameAssigner(gs); int type = gtk_combo_box_get_active(GTK_COMBO_BOX(generationType)); nameAssigner.assign(&colorObject, &color, identifyColorWidget(lastFocusedColor), type); return colorObject; } int identifyColorWidget(GtkWidget *widget) { for (int i = 0; i < MaxColors; ++i) { if (items[i].widget == widget) { return i + 1; } } return 0; } static gboolean onFocusEvent(GtkWidget *widget, GdkEventFocus *, GenerateSchemeArgs *args) { args->setActiveWidget(widget); return false; } static gchar *onSaturationFormat(GtkScale *scale, gdouble value) { return g_strdup_printf("%d%%", int(value)); } static gchar *onLightnessFormat(GtkScale *scale, gdouble value) { if (value >= 0) return g_strdup_printf("+%d%%", int(value)); else return g_strdup_printf("-%d%%", -int(value)); } static void onLockToggle(GtkWidget *widget, GenerateSchemeArgs *args) { args->wheelLocked = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)); gtk_color_wheel_set_block_editable(GTK_COLOR_WHEEL(args->colorWheel), !args->wheelLocked); } void setActiveWidget(GtkWidget *widget) { lastFocusedColor = widget; for (int i = 0; i < MaxColors; ++i) { if (widget == items[i].widget) { gtk_color_wheel_set_selected(GTK_COLOR_WHEEL(colorWheel), i); break; } } } static void onReset(GtkWidget *, GenerateSchemeArgs *args) { for (int i = 0; i < args->colorsVisible; ++i) { if (args->items[i].widget == args->lastFocusedColor) { args->items[i].hueShift = 0; args->items[i].saturationShift = 0; args->items[i].valueShift = 0; args->update(); break; } } } static void onResetAll(GtkWidget *, GenerateSchemeArgs *args) { for (int i = 0; i < MaxColors; ++i) { args->items[i].hueShift = 0; args->items[i].saturationShift = 0; args->items[i].valueShift = 0; } args->update(); } static void onColorActivate(GtkWidget *, GenerateSchemeArgs *args) { args->addToPalette(); } static void onHueChange(GtkWidget *widget, gint colorId, GenerateSchemeArgs *args) { if (args->wheelLocked) { float hue = static_cast(gtk_range_get_value(GTK_RANGE(args->hueRange)) / 360.0f); hue = wrap_float(hue - args->items[colorId].hueShift + static_cast(gtk_color_wheel_get_hue(GTK_COLOR_WHEEL(widget), colorId)) - args->items[colorId].originalHue); gtk_range_set_value(GTK_RANGE(args->hueRange), hue * 360.0f); } else { args->items[colorId].hueShift = static_cast(gtk_color_wheel_get_hue(GTK_COLOR_WHEEL(widget), colorId)) - args->items[colorId].originalHue; onChange(widget, args); } } static void onSaturationChange(GtkWidget *widget, gint colorId, GenerateSchemeArgs *args) { if (args->wheelLocked) { double saturation = static_cast(gtk_range_get_value(GTK_RANGE(args->saturationRange)) / 100.0f); double lightness = static_cast(gtk_range_get_value(GTK_RANGE(args->lightnessRange)) / 100.0f); gtk_range_set_value(GTK_RANGE(args->saturationRange), saturation * 100.0f); gtk_range_set_value(GTK_RANGE(args->lightnessRange), lightness * 100.0f); } else { args->items[colorId].saturationShift = static_cast(gtk_color_wheel_get_saturation(GTK_COLOR_WHEEL(widget), colorId)) - args->items[colorId].originalSaturation; args->items[colorId].valueShift = static_cast(gtk_color_wheel_get_value(GTK_COLOR_WHEEL(widget), colorId)) - args->items[colorId].originalValue; onChange(widget, args); } } static void onChange(GtkWidget *, GenerateSchemeArgs *args) { args->update(); } void update(bool saveSettings = false) { int type = gtk_combo_box_get_active(GTK_COMBO_BOX(generationType)); int colorCount = generate_scheme_get_scheme_type(type)->colors + 1; int wheelType = gtk_combo_box_get_active(GTK_COMBO_BOX(wheelTypeCombo)); gtk_color_wheel_set_color_wheel_type(GTK_COLOR_WHEEL(colorWheel), &color_wheel_types_get()[wheelType]); gtk_color_wheel_set_n_colors(GTK_COLOR_WHEEL(colorWheel), colorCount); float hue = static_cast(gtk_range_get_value(GTK_RANGE(hueRange))); float saturation = static_cast(gtk_range_get_value(GTK_RANGE(saturationRange))); float lightness = static_cast(gtk_range_get_value(GTK_RANGE(lightnessRange))); if (saveSettings) { options->set("type", type); options->set("wheel_type", wheelType); options->set("hue", hue); options->set("saturation", saturation); options->set("lightness", lightness); } for (int i = colorsVisible; i > colorCount; --i) gtk_widget_hide(items[i - 1].widget); for (int i = colorsVisible; i < colorCount; ++i) gtk_widget_show(items[i].widget); colorsVisible = colorCount; hue /= 360.0f; saturation /= 100.0f; lightness /= 100.0f; Color hsl, r; auto &wheel = color_wheel_types_get()[wheelType]; float chaos = 0; float hueOffset = 0; float hueStep; Color hsv; for (int i = 0; i < colorCount; ++i) { wheel.hue_to_hsl(wrap_float(hue + items[i].hueShift), &hsl); hsl.hsl.lightness = clamp_float(hsl.hsl.lightness + lightness, 0, 1); hsl.hsl.saturation = clamp_float(hsl.hsl.saturation * saturation, 0, 1); color_hsl_to_hsv(&hsl, &hsv); items[i].originalHue = hue; items[i].originalSaturation = hsv.hsv.saturation; items[i].originalValue = hsv.hsv.value; hsv.hsv.saturation = clamp_float(hsv.hsv.saturation + items[i].saturationShift, 0, 1); hsv.hsv.value = clamp_float(hsv.hsv.value + items[i].valueShift, 0, 1); color_hsv_to_rgb(&hsv, &r); auto text = gs->converters().serialize(r, Converters::Type::display); gtk_color_set_color(GTK_COLOR(items[i].widget), r, text); items[i].colorHue = hueOffset; gtk_color_wheel_set_hue(GTK_COLOR_WHEEL(colorWheel), i, wrap_float(hue + items[i].hueShift)); gtk_color_wheel_set_saturation(GTK_COLOR_WHEEL(colorWheel), i, hsv.hsv.saturation); gtk_color_wheel_set_value(GTK_COLOR_WHEEL(colorWheel), i, hsv.hsv.value); hueStep = (generate_scheme_get_scheme_type(type)->turn[i % generate_scheme_get_scheme_type(type)->turn_types]) / (360.0f) + chaos * static_cast(random_get_double(gs->getRandom()) - 0.5); hue = wrap_float(hue + hueStep); hueOffset = wrap_float(hueOffset + hueStep); } } struct Editable: IEditableColorsUI, IMenuExtension { Editable(GenerateSchemeArgs *args): args(args) { } virtual ~Editable() = default; virtual void addToPalette(const ColorObject &) override { args->addToPalette(); } virtual void addAllToPalette() override { args->addAllToPalette(); } virtual void setColor(const ColorObject &colorObject) override { args->setColor(colorObject.getColor()); } virtual const ColorObject &getColor() override { return args->getColor(); } virtual std::vector getColors(bool selected) override { std::vector colors; colors.push_back(getColor()); return colors; } virtual bool isEditable() override { return true; } virtual bool hasColor() override { return true; } virtual bool hasSelectedColor() override { return true; } virtual void extendMenu(GtkWidget *menu, Position position) { if (position != Position::end) return; gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); auto item = newMenuItem(_("_Reset"), GTK_STOCK_CANCEL); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(GenerateSchemeArgs::onReset), args); item = newMenuItem(_("_Reset scheme"), GTK_STOCK_CANCEL); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(GenerateSchemeArgs::onResetAll), args); } private: GenerateSchemeArgs *args; }; boost::optional editable; }; static void showMenu(GtkWidget *widget, GenerateSchemeArgs *args, GdkEventButton *event) { auto menu = gtk_menu_new(); auto item = gtk_check_menu_item_new_with_mnemonic(_("_Linked")); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), args->wheelLocked); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "toggled", G_CALLBACK(GenerateSchemeArgs::onLockToggle), args); gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); item = newMenuItem(_("_Reset scheme"), GTK_STOCK_CANCEL); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(GenerateSchemeArgs::onResetAll), args); showContextMenu(menu, event); } static gboolean onButtonPress(GtkWidget *widget, GdkEventButton *event, GenerateSchemeArgs *args) { if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { showMenu(widget, args, event); } return false; } static void onPopupMenu(GtkWidget *widget, GenerateSchemeArgs *args) { showMenu(widget, args, nullptr); } static int destroy(GenerateSchemeArgs *args) { gtk_widget_destroy(args->main); delete args; return 0; } static int getColor(GenerateSchemeArgs *args, ColorObject **color) { auto colorObject = args->getColor(); *color = colorObject.copy(); return 0; } static int setColor(GenerateSchemeArgs *args, ColorObject *colorObject) { args->setColor(*colorObject); return 0; } static int setNthColor(GenerateSchemeArgs *args, size_t index, ColorObject *colorObject) { if (index < 0 || index >= MaxColors) return -1; args->setActiveWidget(args->items[index].widget); args->setColor(*colorObject); return 0; } static int activate(GenerateSchemeArgs *args) { auto chain = args->gs->getTransformationChain(); for (int i = 0; i < MaxColors; ++i) { gtk_color_set_transformation_chain(GTK_COLOR(args->items[i].widget), chain); } gtk_statusbar_push(GTK_STATUSBAR(args->statusBar), gtk_statusbar_get_context_id(GTK_STATUSBAR(args->statusBar), "empty"), ""); return 0; } static int deactivate(GenerateSchemeArgs *args) { args->update(true); args->options->set("wheel_locked", args->wheelLocked); float hsvShifts[MaxColors * 3]; for (uint32_t i = 0; i < MaxColors; ++i) { hsvShifts[i * 3 + 0] = args->items[i].hueShift; hsvShifts[i * 3 + 1] = args->items[i].saturationShift; hsvShifts[i * 3 + 2] = args->items[i].valueShift; } args->options->set("hsv_shift", common::Span(hsvShifts, MaxColors * 3)); return 0; } static ColorObject *getColorObject(struct DragDrop *dd) { auto *args = (GenerateSchemeArgs *)dd->userdata; return args->getColor().copy(); } static int setColorObjectAt(struct DragDrop *dd, ColorObject *colorObject, int, int, bool, bool) { auto *args = static_cast(dd->userdata); args->setActiveWidget(dd->widget); args->setColor(*colorObject); return 0; } static int setColorObjectAtColorWheel(struct DragDrop *dd, ColorObject *colorObject, int x, int y, bool, bool) { int index = gtk_color_wheel_get_at(GTK_COLOR_WHEEL(dd->widget), x, y); if (!(index >= 0 && index < MaxColors)) return -1; auto *args = static_cast(dd->userdata); Color color, hsl; float hue; color = colorObject->getColor(); color_rgb_to_hsl(&color, &hsl); int wheelType = gtk_combo_box_get_active(GTK_COMBO_BOX(args->wheelTypeCombo)); auto &wheel = color_wheel_types_get()[wheelType]; double tmp; wheel.rgbhue_to_hue(hsl.hsl.hue, &tmp); hue = static_cast(tmp); if (args->wheelLocked) { float hueShift = (hue - args->items[index].originalHue) - args->items[index].hueShift; hue = wrap_float(static_cast(gtk_range_get_value(GTK_RANGE(args->hueRange))) / 360.0f + hueShift); gtk_range_set_value(GTK_RANGE(args->hueRange), hue * 360.0f); } else { args->items[index].hueShift = hue - args->items[index].originalHue; args->update(); } return 0; } static bool testAtColorWheel(struct DragDrop *dd, int x, int y) { int index = gtk_color_wheel_get_at(GTK_COLOR_WHEEL(dd->widget), x, y); return index >= 0 && index < MaxColors; } static ColorSource *source_implement(ColorSource *source, GlobalState *gs, const dynv::Ref &options) { auto *args = new GenerateSchemeArgs; args->editable = GenerateSchemeArgs::Editable(args); args->options = options; args->statusBar = gs->getStatusBar(); args->gs = gs; color_source_init(&args->source, source->identificator, source->hr_name); args->source.destroy = (int (*)(ColorSource *))destroy; args->source.get_color = (int (*)(ColorSource *, ColorObject **))getColor; args->source.set_color = (int (*)(ColorSource *, ColorObject *))setColor; args->source.set_nth_color = (int (*)(ColorSource *, size_t, ColorObject *))setNthColor; args->source.deactivate = (int (*)(ColorSource *))deactivate; args->source.activate = (int (*)(ColorSource *))activate; auto hsvShifts = args->options->getFloats("hsv_shift"); auto hsvShiftCount = hsvShifts.size() / 3; for (uint32_t i = 0; i < MaxColors; ++i) { if (i < hsvShiftCount) { args->items[i].hueShift = hsvShifts[i * 3 + 0]; args->items[i].saturationShift = hsvShifts[i * 3 + 1]; args->items[i].valueShift = hsvShifts[i * 3 + 2]; } else { args->items[i].hueShift = 0; args->items[i].saturationShift = 0; args->items[i].valueShift = 0; } } GtkWidget *table, *vbox, *hbox, *widget, *hbox2; hbox = gtk_hbox_new(false, 5); vbox = gtk_vbox_new(false, 5); gtk_box_pack_start(GTK_BOX(hbox), vbox, true, true, 5); args->colorPreviews = gtk_table_new(3, 2, false); gtk_box_pack_start(GTK_BOX(vbox), args->colorPreviews, true, true, 0); struct DragDrop dd; dragdrop_init(&dd, gs); dd.converterType = Converters::Type::display; dd.userdata = args; dd.get_color_object = getColorObject; dd.set_color_object_at = setColorObjectAt; for (intptr_t i = 0; i < MaxColors; ++i) { widget = gtk_color_new(); gtk_color_set_rounded(GTK_COLOR(widget), true); gtk_color_set_roundness(GTK_COLOR(widget), 5); gtk_color_set_hcenter(GTK_COLOR(widget), true); gtk_table_attach(GTK_TABLE(args->colorPreviews), widget, i % 2, (i % 2) + 1, i / 2, i / 2 + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL | GTK_EXPAND), 0, 0); args->items[i].widget = widget; g_signal_connect(G_OBJECT(widget), "activated", G_CALLBACK(GenerateSchemeArgs::onColorActivate), args); g_signal_connect(G_OBJECT(widget), "focus-in-event", G_CALLBACK(GenerateSchemeArgs::onFocusEvent), args); StandardEventHandler::forWidget(widget, args->gs, &*args->editable); //setup drag&drop gtk_drag_dest_set(widget, GtkDestDefaults(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT), 0, 0, GDK_ACTION_COPY); gtk_drag_source_set(widget, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY); dragdrop_widget_attach(widget, DragDropFlags(DRAGDROP_SOURCE | DRAGDROP_DESTINATION), &dd); } hbox2 = gtk_hbox_new(false, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox2, false, false, 0); args->colorWheel = gtk_color_wheel_new(); gtk_box_pack_start(GTK_BOX(hbox2), args->colorWheel, false, false, 0); g_signal_connect(G_OBJECT(args->colorWheel), "hue_changed", G_CALLBACK(GenerateSchemeArgs::onHueChange), args); g_signal_connect(G_OBJECT(args->colorWheel), "saturation_value_changed", G_CALLBACK(GenerateSchemeArgs::onSaturationChange), args); g_signal_connect(G_OBJECT(args->colorWheel), "popup-menu", G_CALLBACK(onPopupMenu), args); g_signal_connect(G_OBJECT(args->colorWheel), "button-press-event", G_CALLBACK(onButtonPress), args); args->wheelLocked = options->getBool("wheel_locked", true); gtk_color_wheel_set_block_editable(GTK_COLOR_WHEEL(args->colorWheel), !args->wheelLocked); gtk_drag_dest_set(args->colorWheel, GtkDestDefaults(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT), 0, 0, GDK_ACTION_COPY); dd.userdata = args; dd.set_color_object_at = setColorObjectAtColorWheel; dd.test_at = testAtColorWheel; dragdrop_widget_attach(args->colorWheel, DragDropFlags(DRAGDROP_DESTINATION), &dd); gint table_y; table = gtk_table_new(5, 2, false); gtk_box_pack_start(GTK_BOX(hbox2), table, true, true, 0); table_y = 0; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Hue:"), 0, 0.5, 0, 0), 0, 1, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 5, 5); args->hueRange = widget = gtk_hscale_new_with_range(0, 360, 1); gtk_range_set_value(GTK_RANGE(widget), options->getFloat("hue", 180)); g_signal_connect(G_OBJECT(widget), "value-changed", G_CALLBACK(GenerateSchemeArgs::onChange), args); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 5, 0); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Saturation:"), 0, 0.5, 0, 0), 0, 1, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 5, 5); args->saturationRange = widget = gtk_hscale_new_with_range(0, 120, 1); gtk_range_set_value(GTK_RANGE(widget), options->getFloat("saturation", 100)); g_signal_connect(G_OBJECT(widget), "value-changed", G_CALLBACK(GenerateSchemeArgs::onChange), args); g_signal_connect(G_OBJECT(widget), "format-value", G_CALLBACK(GenerateSchemeArgs::onSaturationFormat), args); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 5, 0); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Lightness:"), 0, 0.5, 0, 0), 0, 1, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 5, 5); args->lightnessRange = widget = gtk_hscale_new_with_range(-50, 80, 1); gtk_range_set_value(GTK_RANGE(widget), options->getFloat("lightness", 0)); g_signal_connect(G_OBJECT(widget), "value-changed", G_CALLBACK(GenerateSchemeArgs::onChange), args); g_signal_connect(G_OBJECT(widget), "format-value", G_CALLBACK(GenerateSchemeArgs::onLightnessFormat), args); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 5, 0); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Type:"), 0, 0.5, 0, 0), 0, 1, table_y, table_y + 1, GTK_FILL, GTK_SHRINK, 5, 5); args->generationType = widget = gtk_combo_box_text_new(); for (size_t i = 0; i < generate_scheme_get_n_scheme_types(); i++) { gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), _(generate_scheme_get_scheme_type(i)->name)); } gtk_combo_box_set_active(GTK_COMBO_BOX(widget), options->getInt32("type", 0)); g_signal_connect(G_OBJECT(widget), "changed", G_CALLBACK(GenerateSchemeArgs::onChange), args); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y + 1, GTK_FILL, GTK_SHRINK, 5, 0); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Color wheel:"), 0, 0.5, 0, 0), 0, 1, table_y, table_y + 1, GTK_FILL, GTK_SHRINK, 5, 5); args->wheelTypeCombo = widget = gtk_combo_box_text_new(); for (size_t i = 0; i < color_wheel_types_get_n(); i++) { gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), _(color_wheel_types_get()[i].name)); } gtk_combo_box_set_active(GTK_COMBO_BOX(widget), options->getInt32("wheel_type", 0)); g_signal_connect(G_OBJECT(widget), "changed", G_CALLBACK(GenerateSchemeArgs::onChange), args); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y + 1, GTK_FILL, GTK_SHRINK, 5, 0); table_y++; args->colorsVisible = MaxColors; gtk_widget_show_all(hbox); args->update(); args->main = hbox; args->source.widget = hbox; return (ColorSource *)args; } int generate_scheme_source_register(ColorSourceManager *csm) { ColorSource *color_source = new ColorSource; color_source_init(color_source, "generate_scheme", _("Scheme generation")); color_source->implement = source_implement; color_source->default_accelerator = GDK_KEY_g; color_source_manager_add_source(csm, color_source); return 0; } const SchemeType *generate_scheme_get_scheme_type(size_t index) { if (index >= 0 && index < generate_scheme_get_n_scheme_types()) return &types[index]; else return 0; } size_t generate_scheme_get_n_scheme_types() { return sizeof(types) / sizeof(SchemeType); } gpick-gpick-0.2.6/source/GenerateScheme.h000066400000000000000000000036541377073231300202550ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_GENERATE_SCHEME_H_ #define GPICK_GENERATE_SCHEME_H_ #include struct ColorSourceManager; struct SchemeType { const char *name; int colors; int turn_types; float turn[4]; }; int generate_scheme_source_register(ColorSourceManager *csm); const SchemeType* generate_scheme_get_scheme_type(size_t index); size_t generate_scheme_get_n_scheme_types(); #endif /* GPICK_GENERATE_SCHEME_H_ */ gpick-gpick-0.2.6/source/GlobalState.cpp000066400000000000000000000221151377073231300201230ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "GlobalState.h" #include "Paths.h" #include "ScreenReader.h" #include "Converters.h" #include "Converter.h" #include "Random.h" #include "color_names/ColorNames.h" #include "Sampler.h" #include "ColorList.h" #include "layout/Layout.h" #include "layout/Layouts.h" #include "transformation/Chain.h" #include "transformation/Factory.h" #include "dynv/Map.h" #include "lua/Script.h" #include "lua/Extensions.h" #include "lua/Callbacks.h" #include #include #include extern "C"{ #include #include } #include #include using namespace std; struct GlobalState::Impl { GlobalState *m_decl; ColorNames *m_color_names; Sampler *m_sampler; ScreenReader *m_screen_reader; ColorList *m_color_list; dynv::Map m_settings; lua::Script m_script; Random *m_random; Converters m_converters; layout::Layouts m_layouts; lua::Callbacks m_callbacks; transformation::Chain *m_transformation_chain; GtkWidget *m_status_bar; ColorSource *m_color_source; Impl(GlobalState *decl): m_decl(decl), m_color_names(nullptr), m_sampler(nullptr), m_screen_reader(nullptr), m_color_list(nullptr), m_random(nullptr), m_transformation_chain(nullptr), m_status_bar(nullptr), m_color_source(nullptr) { } ~Impl() { if (m_transformation_chain != nullptr) delete m_transformation_chain; if (m_color_list != nullptr) color_list_destroy(m_color_list); if (m_random != nullptr) random_destroy(m_random); if (m_color_names != nullptr) color_names_destroy(m_color_names); if (m_sampler != nullptr) sampler_destroy(m_sampler); if (m_screen_reader != nullptr) screen_reader_destroy(m_screen_reader); } bool writeSettings() { auto configFile = buildConfigPath("settings.xml"); std::ofstream settingsFile(configFile.c_str()); if (!settingsFile.is_open()){ return false; } if (!m_settings.serializeXml(settingsFile)) return false; settingsFile.close(); return settingsFile.good(); } bool loadSettings() { auto configFile = buildConfigPath("settings.xml"); std::ifstream settingsFile(configFile.c_str()); if (!settingsFile.is_open()){ return false; } if (!m_settings.deserializeXml(settingsFile)) { return false; } settingsFile.close(); return true; } // Creates configuration directory if it doesn't exist void checkConfigurationDirectory() { namespace fs = boost::filesystem; auto configPath = fs::path(buildConfigPath()); boost::system::error_code ec; fs::create_directory(configPath, ec); } // Check if user has user_init.lua file, if not, then create empty file void checkUserInitFile() { namespace fs = boost::filesystem; auto userInitFilePath = fs::path(buildConfigPath("user_init.lua")); if (fs::exists(fs::status(userInitFilePath))) return; auto pathString = userInitFilePath.string(); std::ofstream newFile(pathString.c_str()); if (!newFile.is_open()) { return; } newFile.close(); } bool loadColorNames() { if (m_color_names != nullptr) return false; m_color_names = color_names_new(); auto options = m_settings.getOrCreateMap("gpick"); color_names_load(m_color_names, *options); return true; } bool initializeRandomGenerator() { m_random = random_new("SHR3"); size_t seed_value = time(0) | 1; random_seed(m_random, &seed_value); return true; } bool createColorList() { if (m_color_list != nullptr) return false; //create color list / callbacks must be defined elsewhere m_color_list = color_list_new(); return true; } bool initializeLua() { lua_State *L = m_script; lua::registerAll(L, *m_decl); std::vector paths; paths.push_back(buildFilename()); paths.push_back(buildConfigPath()); m_script.setPaths(paths); bool result = m_script.load("init"); if (!result){ std::cerr << "Lua load error: " << m_script.getLastError() << "\n"; } return result; } bool loadConverters() { auto converters = m_settings.getOrCreateMap("gpick.converters"); if (converters->size() == 0) { const char* names[] = { "color_web_hex", "color_css_rgb", "color_css_hsl", }; for (size_t i = 0; i != sizeof(names) / sizeof(names[0]); i++) { auto converter = m_converters.byName(names[i]); if (!converter) continue; converter->copy(converter->hasSerialize()); converter->paste(converter->hasDeserialize()); } m_converters.reorder(names, sizeof(names) / sizeof(names[0])); } else { auto names = converters->getStrings("names"); auto copy = converters->getBools("copy"); auto paste = converters->getBools("paste"); for (size_t i = 0, end = names.size(); i != end; i++) { auto converter = m_converters.byName(names[i].c_str()); if (!converter) continue; if (i < copy.size()) converter->copy(converter->hasSerialize() && copy[i]); if (i < paste.size()) converter->paste(converter->hasDeserialize() && paste[i]); } m_converters.reorder(names); } m_converters.rebuildCopyPasteArrays(); m_converters.display(m_settings.getString("gpick.converters.display", "color_web_hex")); m_converters.colorList(m_settings.getString("gpick.converters.color_list", "color_web_hex")); return true; } bool loadTransformationChain() { if (m_transformation_chain != nullptr) return false; transformation::Chain *chain = new transformation::Chain(); chain->setEnabled(m_settings.getBool("gpick.transformations.enabled", false)); auto items = m_settings.getMaps("gpick.transformations.items"); for (auto values: items) { if (!values) continue; auto name = values->getString("name", ""); if (name.empty()) continue; auto transformation = transformation::Factory::create(name); if (!transformation) continue; transformation->deserialize(*values); chain->add(std::move(transformation)); } m_transformation_chain = chain; return true; } bool loadAll() { checkConfigurationDirectory(); checkUserInitFile(); m_screen_reader = screen_reader_new(); m_sampler = sampler_new(m_screen_reader); initializeRandomGenerator(); loadSettings(); loadColorNames(); createColorList(); initializeLua(); loadConverters(); loadTransformationChain(); return true; } }; GlobalState::GlobalState() { m_impl = make_unique(this); } GlobalState::~GlobalState() { } bool GlobalState::loadSettings() { return m_impl->loadSettings(); } bool GlobalState::loadAll() { return m_impl->loadAll(); } bool GlobalState::writeSettings() { return m_impl->writeSettings(); } ColorNames *GlobalState::getColorNames() { return m_impl->m_color_names; } Sampler *GlobalState::getSampler() { return m_impl->m_sampler; } ScreenReader *GlobalState::getScreenReader() { return m_impl->m_screen_reader; } ColorList *GlobalState::getColorList() { return m_impl->m_color_list; } dynv::Map &GlobalState::settings() { return m_impl->m_settings; } lua::Script &GlobalState::script() { return m_impl->m_script; } lua::Callbacks &GlobalState::callbacks() { return m_impl->m_callbacks; } Random *GlobalState::getRandom() { return m_impl->m_random; } Converters &GlobalState::converters() { return m_impl->m_converters; } layout::Layouts &GlobalState::layouts() { return m_impl->m_layouts; } transformation::Chain *GlobalState::getTransformationChain() { return m_impl->m_transformation_chain; } GtkWidget *GlobalState::getStatusBar() { return m_impl->m_status_bar; } void GlobalState::setStatusBar(GtkWidget *status_bar) { m_impl->m_status_bar = status_bar; } ColorSource *GlobalState::getCurrentColorSource() { return m_impl->m_color_source; } void GlobalState::setCurrentColorSource(ColorSource *color_source) { m_impl->m_color_source = color_source; } gpick-gpick-0.2.6/source/GlobalState.h000066400000000000000000000052711377073231300175740ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_GLOBAL_STATE_H_ #define GPICK_GLOBAL_STATE_H_ #include "dynv/MapFwd.h" #include #include #include struct ColorNames; struct Sampler; struct ScreenReader; struct ColorList; struct Random; struct Converters; struct ColorSource; typedef struct _GtkWidget GtkWidget; namespace layout { struct Layouts; } namespace transformation { struct Chain; } namespace lua { struct Script; struct Callbacks; } struct GlobalState { GlobalState(); ~GlobalState(); bool loadSettings(); bool loadAll(); bool writeSettings(); ColorNames *getColorNames(); Sampler *getSampler(); ScreenReader *getScreenReader(); ColorList *getColorList(); dynv::Map &settings(); lua::Script &script(); lua::Callbacks &callbacks(); Converters &converters(); Random *getRandom(); layout::Layouts &layouts(); transformation::Chain *getTransformationChain(); GtkWidget *getStatusBar(); void setStatusBar(GtkWidget *status_bar); ColorSource *getCurrentColorSource(); void setCurrentColorSource(ColorSource *color_source); boost::optional latinKeysGroup; private: struct Impl; std::unique_ptr m_impl; }; #endif /* GPICK_GLOBAL_STATE_H_ */ gpick-gpick-0.2.6/source/HtmlUtils.cpp000066400000000000000000000077131377073231300176560ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "HtmlUtils.h" #include "Color.h" #include #include #include using namespace std; template OutputIterator copy_zero_terminated_string(InputIterator begin, OutputIterator out) { while (*begin != '\0'){ *out++ = *begin++; } return out; } template OutputIterator escape(InputIterator begin, InputIterator end, OutputIterator out) { const char escape_chars[] = {'&', '"', '\'', '<', '>'}; const char *replacements[] = {"&", """, "'", "<", ">"}; const size_t n_escape_chars = sizeof(escape_chars) / sizeof(const char); for (; begin != end; ++begin){ size_t escape_char_index = distance(escape_chars, find(escape_chars, escape_chars + n_escape_chars, *begin)); if (escape_char_index != n_escape_chars){ out = copy_zero_terminated_string(replacements[escape_char_index], out); }else{ *out++ = *begin; } } return out; } string &escapeHtmlInplace(string &str) { string result; result.reserve(str.size()); escape(str.begin(), str.end(), back_inserter(result)); str.swap(result); return str; } string escapeHtml(const string &str) { string result; result.reserve(str.size()); escape(str.begin(), str.end(), back_inserter(result)); return result; } std::ostream& operator<<(std::ostream& os, const HtmlRGB color) { using boost::math::iround; int r, g, b; r = iround(color.color->rgb.red * 255); g = iround(color.color->rgb.green * 255); b = iround(color.color->rgb.blue * 255); auto flags = os.flags(); os << "rgb(" << dec << r << ", " << g << ", " << b << ")"; os.setf(flags); return os; } std::ostream& operator<<(std::ostream& os, const HtmlHEX color) { using boost::math::iround; int r, g, b; r = iround(color.color->rgb.red * 255); g = iround(color.color->rgb.green * 255); b = iround(color.color->rgb.blue * 255); char fill = os.fill(); auto flags = os.flags(); os << "#" << hex << setfill('0') << setw(2) << r << setw(2) << g << setw(2) << b << setfill(fill); os.setf(flags); return os; } std::ostream& operator<<(std::ostream& os, const HtmlHSL color) { using boost::math::iround; int h, s, l; h = iround(color.color->hsl.hue * 360); s = iround(color.color->hsl.saturation * 100); l = iround(color.color->hsl.lightness * 100); auto flags = os.flags(); os << "hsl(" << dec << h << ", " << s << "%, " << l << "%)"; os.setf(flags); return os; } gpick-gpick-0.2.6/source/HtmlUtils.h000066400000000000000000000040561377073231300173200ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_HTML_UTILS_H_ #define GPICK_HTML_UTILS_H_ #include #include std::string &escapeHtmlInplace(std::string &str); std::string escapeHtml(const std::string &str); struct Color; struct HtmlRGB { Color *color; }; struct HtmlHEX { Color *color; }; struct HtmlHSL { Color *color; }; std::ostream& operator<<(std::ostream& os, const HtmlRGB color); std::ostream& operator<<(std::ostream& os, const HtmlHEX color); std::ostream& operator<<(std::ostream& os, const HtmlHSL color); #endif /* GPICK_HTML_UTILS_H_ */ gpick-gpick-0.2.6/source/I18N.h000066400000000000000000000034221377073231300160460ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_I18N_H_ #define GPICK_I18N_H_ #ifdef ENABLE_NLS #include #define _(STRING) gettext(STRING) #define N_(STRING) STRING #else #define _(STRING) STRING #define N_(STRING) STRING #endif void initialize_i18n(); #endif /* GPICK_I18N_H_ */ gpick-gpick-0.2.6/source/IEditableColorUI.h000066400000000000000000000035651377073231300204560ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_IEDITABLE_COLOR_UI_H_ #define GPICK_IEDITABLE_COLOR_UI_H_ #include "IReadonlyColorUI.h" struct IEditableColorUI: virtual IReadonlyColorUI { virtual void setColor(const ColorObject &colorObject) = 0; virtual bool isEditable() = 0; }; struct IEditableColorsUI: IEditableColorUI, IReadonlyColorsUI { }; #endif /* GPICK_IEDITABLE_COLOR_UI_H_ */ gpick-gpick-0.2.6/source/IMenuExtension.h000066400000000000000000000034371377073231300203070ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_IMENU_EXTENSION_UI_H_ #define GPICK_IMENU_EXTENSION_UI_H_ #include struct IMenuExtension { enum class Position { middle, end, }; virtual void extendMenu(GtkWidget *menu, Position position) = 0; }; #endif /* GPICK_IMENU_EXTENSION_UI_H_ */ gpick-gpick-0.2.6/source/IReadonlyColorUI.h000066400000000000000000000040211377073231300205060ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_IREADONLY_COLOR_UI_H_ #define GPICK_IREADONLY_COLOR_UI_H_ #include struct ColorObject; struct IReadonlyColorUI { virtual bool hasSelectedColor() = 0; virtual void addToPalette(const ColorObject &colorObject) = 0; virtual const ColorObject &getColor() = 0; }; struct IReadonlyColorsUI: virtual IReadonlyColorUI { virtual void addAllToPalette() = 0; virtual std::vector getColors(bool selected) = 0; virtual bool hasColor() = 0; }; #endif /* GPICK_IREADONLY_COLOR_UI_H_ */ gpick-gpick-0.2.6/source/ImportExport.cpp000066400000000000000000000677151377073231300204150ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ImportExport.h" #include "ColorObject.h" #include "ColorList.h" #include "FileFormat.h" #include "Converters.h" #include "Converter.h" #include "I18N.h" #include "StringUtils.h" #include "HtmlUtils.h" #include "GlobalState.h" #include "dynv/Map.h" #include "version/Version.h" #include "parser/TextFile.h" #include #include #include #include #include #include #include #include using namespace std; static bool getOrderedColors(ColorList *color_list, vector &ordered) { color_list_get_positions(color_list); size_t max_index = 0; bool index_set = false; for (auto color: color_list->colors){ if (color->isPositionSet()){ if (!index_set){ max_index = color->getPosition(); index_set = true; }else if (color->getPosition() > max_index){ max_index = color->getPosition(); } } } if (!index_set){ return false; }else{ ordered.resize(max_index + 1); for (auto color: color_list->colors){ if (color->isPositionSet()){ ordered[color->getPosition()] = color; } } return true; } } ImportExport::ImportExport(ColorList *color_list, const char* filename, GlobalState *gs): m_color_list(color_list), m_converter(nullptr), m_converters(nullptr), m_filename(filename), m_item_size(ItemSize::medium), m_background(Background::none), m_gs(gs), m_include_color_names(true), m_last_error(Error::none) { } void ImportExport::fixFileExtension(const char *selected_filter) { using namespace boost::filesystem; if (selected_filter && selected_filter[0] == '*'){ string extension = path(m_filename).extension().string(); bool append = false; if (extension.length() == 0){ append = true; }else{ if (getFileTypeByExtension(extension.c_str()) == FileType::unknown) append = true; } if (append){ size_t length = m_filename.length(); m_filename += &selected_filter[1]; size_t additional_extension = m_filename.find_first_of(',', length); if (additional_extension != string::npos){ m_filename = m_filename.substr(0, additional_extension); } } } } void ImportExport::setConverter(Converter *converter) { m_converter = converter; } void ImportExport::setConverters(Converters *converters) { m_converters = converters; } void ImportExport::setItemSize(ItemSize item_size) { m_item_size = item_size; } void ImportExport::setItemSize(const char *item_size) { string v(item_size); if (v == "small") m_item_size = ItemSize::small; else if (v == "medium") m_item_size = ItemSize::medium; else if (v == "big") m_item_size = ItemSize::big; else if (v == "controllable") m_item_size = ItemSize::controllable; else m_item_size = ItemSize::medium; } void ImportExport::setBackground(Background background) { m_background = background; } void ImportExport::setBackground(const char *background) { string v(background); if (v == "none") m_background = Background::none; else if (v == "white") m_background = Background::white; else if (v == "gray") m_background = Background::gray; else if (v == "black") m_background = Background::black; else if (v == "first_color") m_background = Background::first_color; else if (v == "last_color") m_background = Background::last_color; else if (v == "controllable") m_background = Background::controllable; else m_background = Background::none; } void ImportExport::setIncludeColorNames(bool include_color_names) { m_include_color_names = include_color_names; } static void gplColor(ColorObject* color_object, ostream &stream) { using boost::math::iround; Color color = color_object->getColor(); stream << iround(color.rgb.red * 255) << "\t" << iround(color.rgb.green * 255) << "\t" << iround(color.rgb.blue * 255) << "\t" << color_object->getName() << endl; } bool ImportExport::exportGPL() { ofstream f(m_filename, ios::out | ios::trunc); if (!f.is_open()){ m_last_error = Error::could_not_open_file; return false; } boost::filesystem::path path(m_filename); f << "GIMP Palette" << endl; f << "Name: " << path.filename().string() << endl; f << "Columns: 1" << endl; f << "#" << endl; vector ordered; getOrderedColors(m_color_list, ordered); for (auto color: ordered){ gplColor(color, f); if (!f.good()){ f.close(); m_last_error = Error::file_write_error; return false; } } f.close(); return true; } bool ImportExport::importGPL() { ifstream f(m_filename, ios::in); if (!f.is_open()){ m_last_error = Error::could_not_open_file; return false; } string line; getline(f, line); if (f.good() && line != "GIMP Palette"){ f.close(); m_last_error = Error::file_read_error; return false; } do{ getline(f, line); }while (f.good() && ((line.size() < 1) || (((line[0] > '9') || (line[0] < '0')) && line[0] != ' '))); int r, g, b; Color c; ColorObject* color_object; string strip_chars = " \t"; for(;;){ if (!f.good()) break; stripLeadingTrailingChars(line, strip_chars); if (line.length() > 0 && line[0] == '#'){ // skip comment lines getline(f, line); continue; } stringstream ss(line); ss >> r >> g >> b; getline(ss, line); if (!f.good()) line = ""; c.rgb.red = r / 255.0; c.rgb.green = g / 255.0; c.rgb.blue = b / 255.0; color_object = color_list_new_color_object(m_color_list, &c); stripLeadingTrailingChars(line, strip_chars); color_object->setName(line); color_list_add_color_object(m_color_list, color_object, true); color_object->release(); getline(f, line); } if (!f.eof()) { f.close(); m_last_error = Error::file_read_error; return false; } f.close(); return true; } bool ImportExport::importGPA() { return paletteFileLoad(m_filename.c_str(), m_color_list); } bool ImportExport::exportGPA() { return paletteFileSave(m_filename.c_str(), m_color_list); } bool ImportExport::exportTXT() { ofstream f(m_filename.c_str(), ios::out | ios::trunc); if (!f.is_open()){ m_last_error = Error::could_not_open_file; return false; } vector ordered; getOrderedColors(m_color_list, ordered); ConverterSerializePosition position(ordered.size()); for (auto color: ordered){ string line = m_converter->serialize(color, position); if (m_include_color_names) { f << line << " " << color->getName() << endl; } else { f << line << endl; } position.incrementIndex(); if (position.index() + 1 == position.count()){ position.last(true); } if (position.first()) position.first(false); if (!f.good()){ f.close(); m_last_error = Error::file_write_error; return false; } } f.close(); return true; } bool ImportExport::importTXT() { ifstream f(m_filename.c_str(), ios::in); if (!f.is_open()){ m_last_error = Error::could_not_open_file; return false; } ColorObject *color_object; Color dummy_color; multimap> valid_converters; string line; string strip_chars = " \t"; bool imported = false; for(;;){ getline(f, line); stripLeadingTrailingChars(line, strip_chars); if (!line.empty()){ for (auto &converter: m_converters->allPaste()){ if (!converter->hasDeserialize()) continue; color_object = color_list_new_color_object(m_color_list, &dummy_color); float quality; if (converter->deserialize(line.c_str(), color_object, quality)){ if (quality > 0){ valid_converters.insert(make_pair(quality, color_object)); }else{ color_object->release(); } }else{ color_object->release(); } } bool first = true; for (auto result: valid_converters){ if (first){ first = false; color_list_add_color_object(m_color_list, result.second, true); imported = true; } result.second->release(); } valid_converters.clear(); } if (!f.good()) { if (f.eof()) break; f.close(); m_last_error = Error::file_read_error; return false; } } f.close(); if (!imported){ m_last_error = Error::no_colors_imported; } return imported; } static void cssColor(ColorObject* color_object, ostream &stream) { Color color, hsl; color = color_object->getColor(); color_rgb_to_hsl(&color, &hsl); stream << " * " << color_object->getName() << ": " << HtmlHEX{&color} << ", " << HtmlRGB{&color} << ", " << HtmlHSL{&color} << endl; } bool ImportExport::exportCSS() { ofstream f(m_filename.c_str(), ios::out | ios::trunc); if (!f.is_open()){ m_last_error = Error::could_not_open_file; return false; } f << "/**" << endl << " * Generated by Gpick " << gpick_build_version << endl; vector ordered; getOrderedColors(m_color_list, ordered); for (auto color: ordered){ cssColor(color, f); if (!f.good()){ f.close(); m_last_error = Error::file_write_error; return false; } } f << " */" << endl; if (!f.good()){ f.close(); m_last_error = Error::file_write_error; return false; } f.close(); return true; } static void htmlColor(ColorObject* color_object, bool include_color_name, ostream &stream) { Color color, text_color; color = color_object->getColor(); color_get_contrasting(&color, &text_color); stream << "
"; if (include_color_name){ string name = color_object->getName(); escapeHtmlInplace(name); if (!name.empty()) stream << name << ":
"; } stream << "" << HtmlHEX{&color} << "" << "
"; } static string getHtmlColor(ColorObject* color_object) { Color color = color_object->getColor(); stringstream ss; ss << HtmlRGB{&color}; return ss.str(); } bool ImportExport::exportHTML() { ofstream f(m_filename.c_str(), ios::out | ios::trunc); if (!f.is_open()){ m_last_error = Error::could_not_open_file; return false; } boost::filesystem::path path(m_filename); vector ordered; getOrderedColors(m_color_list, ordered); int item_size = 64; switch (m_item_size){ case ItemSize::small: item_size = 32; break; case ItemSize::medium: item_size = 64; break; case ItemSize::big: item_size = 96; break; case ItemSize::controllable: break; } string background = ""; switch (m_background){ case Background::none: break; case Background::white: background = "background-color:white;"; break; case Background::gray: background = "background-color:gray;"; break; case Background::black: background = "background-color:black;"; break; case Background::first_color: if (!ordered.empty()) background = "background-color:" + getHtmlColor(ordered.front()) + ";"; break; case Background::last_color: if (!ordered.empty()) background = "background-color:" + getHtmlColor(ordered.back()) + ";"; break; case Background::controllable: break; } f << "" << path.filename().string() << "" << endl << "" << endl << "" << "" << endl << "" << endl; if (m_item_size == ItemSize::controllable || m_background == Background::controllable){ f << "
" << endl; if (m_item_size == ItemSize::controllable){ f << "
" << _("Item size") << ":" << "
" << endl; } if (m_background == Background::controllable){ f << "
" << _("Background color") << ":" << "
" << endl; } f << "
" << endl; } f << "
" << endl; string hex_case = m_gs->settings().getString("gpick.options.hex_case", "upper"); if (hex_case == "upper"){ f << uppercase; }else{ f << nouppercase; } for (auto color: ordered){ htmlColor(color, m_include_color_names, f); if (!f.good()){ f.close(); m_last_error = Error::file_write_error; return false; } } f << "
" << endl; f << ""; f << "" << endl; if (!f.good()){ f.close(); m_last_error = Error::file_write_error; return false; } f.close(); return true; } bool ImportExport::exportType(FileType type) { switch (type){ case FileType::gpa: return exportGPA(); case FileType::gpl: return exportGPL(); case FileType::ase: return exportASE(); case FileType::txt: return exportTXT(); case FileType::mtl: return exportMTL(); case FileType::css: return exportCSS(); case FileType::html: return exportHTML(); case FileType::rgbtxt: case FileType::unknown: return false; } return false; } static void mtlColor(ColorObject* color_object, ostream &stream) { Color color = color_object->getColor(); stream << "newmtl " << color_object->getName() << endl; stream << "Ns 90.000000" << endl; stream << "Ka 0.000000 0.000000 0.000000" << endl; stream << "Kd " << color.rgb.red << " " << color.rgb.green << " " << color.rgb.blue << endl; stream << "Ks 0.500000 0.500000 0.500000" << endl << endl; } bool ImportExport::exportMTL() { ofstream f(m_filename.c_str(), ios::out | ios::trunc); if (!f.is_open()){ m_last_error = Error::could_not_open_file; return false; } vector ordered; getOrderedColors(m_color_list, ordered); for (auto color: ordered){ mtlColor(color, f); if (!f.good()){ f.close(); m_last_error = Error::file_write_error; return false; } } f.close(); return true; } typedef union FloatInt { float f; uint32_t i; }FloatInt; static void aseColor(ColorObject* color_object, ostream &stream) { Color color = color_object->getColor(); string name = color_object->getName(); glong name_u16_len = 0; gunichar2 *name_u16 = g_utf8_to_utf16(name.c_str(), -1, 0, &name_u16_len, 0); for (glong i = 0; i < name_u16_len; ++i){ name_u16[i] = boost::endian::native_to_big(name_u16[i]); } uint16_t color_entry = boost::endian::native_to_big(0x0001); stream.write((char*)&color_entry, 2); int32_t block_size = 2 + (name_u16_len + 1) * 2 + 4 + (3 * 4) + 2; //name length + name (zero terminated and 2 bytes per char wide) + color name + 3 float values + color type block_size = boost::endian::native_to_big(block_size); stream.write((char*)&block_size, 4); uint16_t name_length = boost::endian::native_to_big(uint16_t(name_u16_len + 1)); stream.write((char*)&name_length, 2); stream.write((char*)name_u16, (name_u16_len + 1) * 2); stream << "RGB "; FloatInt r, g, b; r.f = color.rgb.red; g.f = color.rgb.green; b.f = color.rgb.blue; r.i = boost::endian::native_to_big(r.i); g.i = boost::endian::native_to_big(g.i); b.i = boost::endian::native_to_big(b.i); stream.write((char*)&r, 4); stream.write((char*)&g, 4); stream.write((char*)&b, 4); int16_t color_type = boost::endian::native_to_big(0); stream.write((char*)&color_type, 2); g_free(name_u16); } bool ImportExport::exportASE() { ofstream f(m_filename.c_str(), ios::out | ios::trunc | ios::binary); if (!f.is_open()){ m_last_error = Error::could_not_open_file; return false; } f << "ASEF"; //magic header uint32_t version = boost::endian::native_to_big(0x00010000); f.write((char*)&version, 4); vector ordered; getOrderedColors(m_color_list, ordered); uint32_t blocks = ordered.size(); blocks = boost::endian::native_to_big(blocks); f.write((char*)&blocks, 4); for (auto color: ordered){ aseColor(color, f); if (!f.good()){ f.close(); m_last_error = Error::file_write_error; return false; } } f.close(); return true; } bool ImportExport::importASE() { ifstream f(m_filename.c_str(), ios::binary); if (!f.is_open()){ m_last_error = Error::could_not_open_file; return false; } char magic[4]; f.read(magic, 4); if (memcmp(magic, "ASEF", 4) != 0){ f.close(); m_last_error = Error::file_read_error; return false; } uint32_t version; f.read((char*)&version, 4); version = boost::endian::big_to_native(version); uint32_t blocks; f.read((char*)&blocks, 4); blocks = boost::endian::big_to_native(blocks); uint16_t block_type; uint32_t block_size; int color_supported; for (uint32_t i = 0; i < blocks; ++i){ f.read((char*)&block_type, 2); block_type = boost::endian::big_to_native(block_type); f.read((char*)&block_size, 4); block_size = boost::endian::big_to_native(block_size); switch (block_type){ case 0x0001: //color block { uint16_t name_length; f.read((char*)&name_length, 2); name_length = boost::endian::big_to_native(name_length); gunichar2 *name_u16 = (gunichar2*)g_malloc(name_length*2); f.read((char*)name_u16, name_length*2); for (uint32_t j = 0; j < name_length; ++j){ name_u16[j] = boost::endian::big_to_native(name_u16[j]); } gchar *name = g_utf16_to_utf8(name_u16, name_length, 0, 0, 0); g_free(name_u16); Color c; char color_space[4]; f.read(color_space, 4); color_supported = 0; if (memcmp(color_space, "RGB ", 4) == 0){ FloatInt rgb[3]; f.read((char*)&rgb[0], 4); f.read((char*)&rgb[1], 4); f.read((char*)&rgb[2], 4); rgb[0].i = boost::endian::big_to_native(rgb[0].i); rgb[1].i = boost::endian::big_to_native(rgb[1].i); rgb[2].i = boost::endian::big_to_native(rgb[2].i); c.rgb.red = rgb[0].f; c.rgb.green = rgb[1].f; c.rgb.blue = rgb[2].f; color_supported = 1; }else if (memcmp(color_space, "CMYK", 4) == 0){ Color c2; FloatInt cmyk[4]; f.read((char*)&cmyk[0], 4); f.read((char*)&cmyk[1], 4); f.read((char*)&cmyk[2], 4); f.read((char*)&cmyk[3], 4); cmyk[0].i = boost::endian::big_to_native(cmyk[0].i); cmyk[1].i = boost::endian::big_to_native(cmyk[1].i); cmyk[2].i = boost::endian::big_to_native(cmyk[2].i); cmyk[3].i = boost::endian::big_to_native(cmyk[3].i); c2.cmyk.c = cmyk[0].f; c2.cmyk.m = cmyk[1].f; c2.cmyk.y = cmyk[2].f; c2.cmyk.k = cmyk[3].f; color_cmyk_to_rgb(&c2, &c); color_supported = 1; }else if (memcmp(color_space, "Gray", 4) == 0){ FloatInt gray; f.read((char*)&gray, 4); gray.i = boost::endian::big_to_native(gray.i); c.rgb.red = c.rgb.green = c.rgb.blue = gray.f; color_supported = 1; }else if (memcmp(color_space, "LAB ", 4) == 0){ Color c2; FloatInt lab[3]; f.read((char*)&lab[0], 4); f.read((char*)&lab[1], 4); f.read((char*)&lab[2], 4); lab[0].i = boost::endian::big_to_native(lab[0].i); lab[1].i = boost::endian::big_to_native(lab[1].i); lab[2].i = boost::endian::big_to_native(lab[2].i); c2.lab.L = lab[0].f*100; c2.lab.a = lab[1].f; c2.lab.b = lab[2].f; color_lab_to_rgb_d50(&c2, &c); c.rgb.red = clamp_float(c.rgb.red, 0, 1); c.rgb.green = clamp_float(c.rgb.green, 0, 1); c.rgb.blue = clamp_float(c.rgb.blue, 0, 1); color_supported = 1; } if (color_supported){ ColorObject* color_object; color_object = color_list_new_color_object(m_color_list, &c); color_object->setName(name); color_list_add_color_object(m_color_list, color_object, true); color_object->release(); } uint16_t color_type; f.read((char*)&color_type, 2); g_free(name); } break; default: f.seekg(block_size, ios::cur); } } f.close(); return true; } static string::size_type rfind_first_of_not(string const& str, string::size_type const pos, string const& chars) { auto start = str.rend() - pos - 1; auto found = std::find_first_of(start, str.rend(), chars.begin(), chars.end()); return found == str.rend() ? string::npos : pos - (found - start); } static int hexToInt(char hex) { if (hex >= '0' && hex <= '9') return hex - '0'; if (hex >= 'a' && hex <= 'f') return hex - 'a' + 10; if (hex >= 'A' && hex <= 'F') return hex - 'A' + 10; return 0; } static int hexPairToInt(const char *hex_pair) { return hexToInt(hex_pair[0]) << 4 | hexToInt(hex_pair[1]); } bool ImportExport::importRGBTXT() { ifstream f(m_filename.c_str(), ios::in); if (!f.is_open()){ m_last_error = Error::could_not_open_file; return false; } string line; Color c; ColorObject* color_object; string strip_chars = " \t"; for(;;){ getline(f, line); if (!f.good()) break; stripLeadingTrailingChars(line, strip_chars); if (line.length() > 0 && line[0] == '#'){ // skip comment lines continue; } size_t hash_position = line.find('#'); if (hash_position != string::npos){ size_t last_non_space = rfind_first_of_not(line, hash_position, " \t"); c.rgb.red = hexPairToInt(&line.at(hash_position + 1)) / 255.0; c.rgb.green = hexPairToInt(&line.at(hash_position + 3)) / 255.0; c.rgb.blue = hexPairToInt(&line.at(hash_position + 5)) / 255.0; color_object = color_list_new_color_object(m_color_list, &c); if (last_non_space != string::npos){ color_object->setName(line.substr(0, last_non_space)); } color_list_add_color_object(m_color_list, color_object, true); color_object->release(); } } if (!f.eof()) { f.close(); m_last_error = Error::file_read_error; return false; } f.close(); return true; } static bool compareChunkType(const char *chunk_type, const char *data) { int i; for (i = 0; i < 16; i++){ if (chunk_type[i] != data[i]) return false; if (chunk_type[i] == 0) break; } for (; i < 16; i++){ if (data[i] != 0) return false; } return true; } FileType ImportExport::getFileTypeByContent(const char *filename) { ifstream f(filename, ios::in); if (!f.is_open()) return FileType::unknown; char data[64]; f.read(data, 64); size_t have = f.gcount(); if (have >= 16){ if (compareChunkType("GPA version", data)) return FileType::gpa; } if (have >= 13){ if (strncmp("GIMP Palette", data, 12) == 0 && (data[12] == '\r' || data[12] == '\n')) return FileType::gpl; } return FileType::unknown; } static struct{ FileType type; const char *extension; bool full_name; }extensions[] = { {FileType::gpa, ".gpa", false}, {FileType::gpl, ".gpl", false}, {FileType::ase, ".ase", false}, {FileType::txt, ".txt", false}, {FileType::mtl, ".mtl", false}, {FileType::css, ".css", false}, {FileType::html, ".html", false}, {FileType::html, ".htm", false}, {FileType::rgbtxt, "rgb.txt", true}, {FileType::unknown, nullptr, false}, }; FileType ImportExport::getFileType(const char *filename) { boost::filesystem::path path(filename); string name = path.filename().string(); boost::algorithm::to_lower(name); for (size_t i = 0; extensions[i].type != FileType::unknown; ++i){ if (extensions[i].full_name && name == extensions[i].extension){ return extensions[i].type; } } string extension = path.extension().string(); if (extension.length() == 0) return getFileTypeByContent(filename); boost::algorithm::to_lower(extension); for (size_t i = 0; extensions[i].type != FileType::unknown; ++i){ if (!extensions[i].full_name && extension == extensions[i].extension){ return extensions[i].type; } } return getFileTypeByContent(filename); } FileType ImportExport::getFileTypeByExtension(const char *extension) { string extension_lowercase = extension; boost::algorithm::to_lower(extension_lowercase); for (size_t i = 0; extensions[i].type != FileType::unknown; ++i){ if (!extensions[i].full_name && extension_lowercase == extensions[i].extension){ return extensions[i].type; } } return FileType::unknown; } bool ImportExport::importType(FileType type) { switch (type){ case FileType::gpa: return importGPA(); case FileType::gpl: return importGPL(); case FileType::ase: return importASE(); case FileType::txt: return importTXT(); case FileType::rgbtxt: return importRGBTXT(); case FileType::mtl: case FileType::css: case FileType::html: case FileType::unknown: return false; } return false; } ImportExport::Error ImportExport::getLastError() const { return m_last_error; } struct ImportTextFile: public text_file_parser::TextFile { ifstream m_file; list m_colors; bool m_failed; ImportTextFile(const string &filename) { m_failed = false; m_file.open(filename, ios::in); } bool isOpen() { return m_file.is_open(); } virtual ~ImportTextFile() { m_file.close(); } virtual void outOfMemory() { m_failed = true; } virtual void syntaxError(size_t start_line, size_t start_column, size_t end_line, size_t end_colunn) { m_failed = true; } virtual size_t read(char *buffer, size_t length) { m_file.read(buffer, length); size_t bytes = m_file.gcount(); if (bytes > 0) return bytes; if (m_file.eof()) return 0; if (!m_file.good()){ m_failed = true; } return 0; } virtual void addColor(const Color &color) { m_colors.push_back(color); } }; bool ImportExport::importTextFile(const text_file_parser::Configuration &configuration) { ImportTextFile import_text_file(m_filename); if (!import_text_file.isOpen()){ m_last_error = Error::could_not_open_file; return false; } if (!import_text_file.parse(configuration)){ m_last_error = Error::parsing_failed; return false; } if (import_text_file.m_failed){ m_last_error = Error::parsing_failed; return false; } if (import_text_file.m_colors.size() == 0){ m_last_error = Error::no_colors_imported; return false; } for (auto color: import_text_file.m_colors){ auto color_object = new ColorObject("" ,color); color_list_add_color_object(m_color_list, color_object, true); color_object->release(); } return true; } const std::string &ImportExport::getFilename() const { return m_filename; } gpick-gpick-0.2.6/source/ImportExport.h000066400000000000000000000066761377073231300200610ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_IMPORT_EXPORT_H_ #define GPICK_IMPORT_EXPORT_H_ #include struct ColorList; struct Converter; struct Converters; struct GlobalState; namespace text_file_parser { struct Configuration; } enum class FileType { gpa, gpl, ase, txt, mtl, css, html, rgbtxt, unknown, }; struct ImportExport { enum class Error { none, could_not_open_file, file_read_error, file_write_error, no_colors_imported, parsing_failed, }; enum class ItemSize { small, medium, big, controllable, }; enum class Background { none, white, gray, black, first_color, last_color, controllable, }; ImportExport(ColorList *color_list, const char* filename, GlobalState *gs); void setConverter(Converter *converter); void setConverters(Converters *converters); void setItemSize(ItemSize item_size); void setItemSize(const char *item_size); void setBackground(Background background); void setBackground(const char *background); void setIncludeColorNames(bool include_color_names); bool exportGPL(); bool importGPL(); bool exportASE(); bool importASE(); bool exportCSS(); bool importTXT(); bool exportTXT(); bool importGPA(); bool exportGPA(); bool exportMTL(); bool exportHTML(); bool importTextFile(const text_file_parser::Configuration &configuration); bool importRGBTXT(); bool importType(FileType type); bool exportType(FileType type); Error getLastError() const; static FileType getFileType(const char *filename); static FileType getFileTypeByExtension(const char *extension); static FileType getFileTypeByContent(const char *filename); void fixFileExtension(const char *selected_filter); const std::string &getFilename() const; private: ColorList *m_color_list; Converter *m_converter; Converters *m_converters; std::string m_filename; ItemSize m_item_size; Background m_background; GlobalState *m_gs; bool m_include_color_names; Error m_last_error; }; #endif /* GPICK_IMPORT_EXPORT_H_ */ gpick-gpick-0.2.6/source/LayoutPreview.cpp000066400000000000000000000525521377073231300205510ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "LayoutPreview.h" #include "ColorSourceManager.h" #include "ColorSource.h" #include "DragDrop.h" #include "Converters.h" #include "Converter.h" #include "dynv/Map.h" #include "I18N.h" #include "color_names/ColorNames.h" #include "GlobalState.h" #include "ToolColorNaming.h" #include "uiUtilities.h" #include "ColorList.h" #include "gtk/LayoutPreview.h" #include "layout/Layout.h" #include "layout/Layouts.h" #include "layout/Style.h" #include "StandardEventHandler.h" #include #include #include using namespace layout; struct LayoutPreviewColorNameAssigner: public ToolColorNameAssigner { LayoutPreviewColorNameAssigner(GlobalState *gs): ToolColorNameAssigner(gs) { } void assign(ColorObject *colorObject, const Color *color, const char *ident) { m_ident = ident; ToolColorNameAssigner::assign(colorObject, color); } virtual std::string getToolSpecificName(ColorObject *colorObject, const Color *color) { m_stream.str(""); m_stream << _("layout preview") << " " << m_ident << " [" << color_names_get(m_gs->getColorNames(), color, false) << "]"; return m_stream.str(); } protected: std::stringstream m_stream; const char *m_ident; }; struct LayoutPreviewArgs { ColorSource source; GtkWidget *main, *statusBar, *layoutView; System *layoutSystem; std::string lastFilename; dynv::Ref options; GlobalState *gs; void addToPalette() { if (!isSelected()) return; color_list_add_color_object(gs->getColorList(), getColor(), true); } void addAllToPalette() { if (layoutSystem == nullptr) return; LayoutPreviewColorNameAssigner nameAssigner(gs); for (auto &style: layoutSystem->styles) { ColorObject colorObject(style->color); nameAssigner.assign(&colorObject, &style->color, style->label.c_str()); color_list_add_color_object(gs->getColorList(), colorObject, true); } } void setColor(const ColorObject &colorObject) { Color color = colorObject.getColor(); gtk_layout_preview_set_current_color(GTK_LAYOUT_PREVIEW(layoutView), &color); } ColorObject colorObject; const ColorObject &getColor() { Color color; if (gtk_layout_preview_get_current_color(GTK_LAYOUT_PREVIEW(layoutView), &color) != 0) return colorObject; Style *style = 0; if (gtk_layout_preview_get_current_style(GTK_LAYOUT_PREVIEW(layoutView), &style) != 0) return colorObject; colorObject.setColor(color); LayoutPreviewColorNameAssigner nameAssigner(gs); nameAssigner.assign(&colorObject, &color, style->label.c_str()); return colorObject; } std::vector getColors(bool selected) { if (layoutSystem == nullptr) return std::vector(); LayoutPreviewColorNameAssigner nameAssigner(gs); std::vector colors; if (selected) { auto colorObject = getColor(); colors.push_back(colorObject); } else { for (auto &style: layoutSystem->styles) { ColorObject colorObject(style->color); nameAssigner.assign(&colorObject, &style->color, style->label.c_str()); colors.push_back(colorObject); } } return colors; } bool select(int x, int y) { gtk_layout_preview_set_focus_at(GTK_LAYOUT_PREVIEW(layoutView), x, y); return gtk_layout_preview_is_selected(GTK_LAYOUT_PREVIEW(layoutView)); } bool isSelected() { return gtk_layout_preview_is_selected(GTK_LAYOUT_PREVIEW(layoutView)); } bool isEditable() { if (!gtk_layout_preview_is_selected(GTK_LAYOUT_PREVIEW(layoutView))) return false; return gtk_layout_preview_is_editable(GTK_LAYOUT_PREVIEW(layoutView)); } struct Editable: IEditableColorsUI { Editable(LayoutPreviewArgs *args): args(args) { } virtual ~Editable() = default; virtual void addToPalette(const ColorObject &) override { args->addToPalette(); } virtual void addAllToPalette() override { args->addAllToPalette(); } virtual void setColor(const ColorObject &colorObject) override { args->setColor(colorObject.getColor()); } virtual const ColorObject &getColor() override { return args->getColor(); } virtual std::vector getColors(bool selected) override { return args->getColors(selected); } virtual bool isEditable() override { return args->isEditable(); } virtual bool hasColor() override { return true; } virtual bool hasSelectedColor() override { return args->isSelected(); } private: LayoutPreviewArgs *args; }; boost::optional editable; }; enum LayoutListColumns { LAYOUTLIST_LABEL = 0, LAYOUTLIST_PTR, LAYOUTLIST_N_COLUMNS }; enum StyleListColumns { STYLELIST_LABEL = 0, STYLELIST_CSS_SELECTOR, STYLELIST_PTR, STYLELIST_N_COLUMNS }; static void onSelectorEdit(GtkCellRendererText *cell, gchar *path, gchar *new_text, GtkListStore *store) { GtkTreeIter iter1; gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter1, path); gtk_list_store_set(store, &iter1, STYLELIST_CSS_SELECTOR, new_text, -1); } static void loadColors(LayoutPreviewArgs *args) { if (args->layoutSystem == nullptr) return; auto assignments = args->options->getOrCreateMap("css_selectors.assignments"); for (auto style: args->layoutSystem->styles) style->color = assignments->getColor(style->ident_name + ".color", style->color); } static void saveColors(LayoutPreviewArgs *args) { if (args->layoutSystem == nullptr) return; auto assignments = args->options->getOrCreateMap("css_selectors.assignments"); for (auto style: args->layoutSystem->styles) assignments->set(style->ident_name + ".color", style->color); } static GtkWidget *newSelectorList(LayoutPreviewArgs *args) { auto view = gtk_tree_view_new(); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), true); auto store = gtk_list_store_new(STYLELIST_N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); auto col = gtk_tree_view_column_new(); gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_resizable(col, true); gtk_tree_view_column_set_title(col, _("Style item")); auto renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(col, renderer, true); gtk_tree_view_column_add_attribute(col, renderer, "text", STYLELIST_LABEL); gtk_tree_view_append_column(GTK_TREE_VIEW(view), col); col = gtk_tree_view_column_new(); gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_resizable(col, true); gtk_tree_view_column_set_title(col, _("CSS selector")); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(col, renderer, true); gtk_tree_view_column_add_attribute(col, renderer, "text", STYLELIST_CSS_SELECTOR); gtk_tree_view_append_column(GTK_TREE_VIEW(view), col); g_object_set(renderer, "editable", true, nullptr); g_signal_connect(renderer, "edited", (GCallback)onSelectorEdit, store); gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store)); g_object_unref(GTK_TREE_MODEL(store)); return view; } static void onAssignSelectors(GtkWidget *widget, LayoutPreviewArgs *args) { if (args->layoutSystem == nullptr) return; GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Assign CSS selectors"), GTK_WINDOW(gtk_widget_get_toplevel(args->main)), GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, nullptr); gtk_window_set_default_size(GTK_WINDOW(dialog), args->options->getInt32("css_selectors.window.width", -1), args->options->getInt32("css_selectors.window.height", -1)); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); auto table = gtk_table_new(1, 1, false); int table_y = 0; auto selectorList = newSelectorList(args); gtk_widget_set_size_request(selectorList, 100, 100); gtk_table_attach(GTK_TABLE(table), selectorList, 0, 1, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL | GTK_EXPAND), 5, 0); table_y++; GtkTreeIter iter1; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(selectorList)); auto assignments = args->options->getOrCreateMap("css_selectors.assignments"); for (auto style: args->layoutSystem->styles) { auto css_selector = assignments->getString(style->ident_name + ".selector", style->ident_name); gtk_list_store_append(GTK_LIST_STORE(model), &iter1); gtk_list_store_set(GTK_LIST_STORE(model), &iter1, STYLELIST_LABEL, style->label.c_str(), STYLELIST_CSS_SELECTOR, css_selector.c_str(), STYLELIST_PTR, style, -1); } gtk_widget_show_all(table); setDialogContent(dialog, table); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { auto valid = gtk_tree_model_get_iter_first(model, &iter1); while (valid) { Style *style; char *selector; gtk_tree_model_get(model, &iter1, STYLELIST_PTR, &style, STYLELIST_CSS_SELECTOR, &selector, -1); assignments->set(style->ident_name + ".selector", selector); g_free(selector); valid = gtk_tree_model_iter_next(model, &iter1); } } gint width, height; gtk_window_get_size(GTK_WINDOW(dialog), &width, &height); args->options->set("css_selectors.window.width", width); args->options->set("css_selectors.window.height", height); gtk_widget_destroy(dialog); } static int destroy(LayoutPreviewArgs *args) { saveColors(args); if (args->layoutSystem) System::unref(args->layoutSystem); args->layoutSystem = nullptr; gtk_widget_destroy(args->main); delete args; return 0; } static int getColor(LayoutPreviewArgs *args, ColorObject **color) { if (!args->isSelected()) return -1; auto colorObject = args->getColor(); *color = colorObject.copy(); return 0; } static int setColor(LayoutPreviewArgs *args, ColorObject *colorObject) { args->setColor(*colorObject); return 0; } static int deactivate(LayoutPreviewArgs *args) { return 0; } static ColorObject *getColorObject(DragDrop *dd) { auto *args = static_cast(dd->userdata); if (!args->isSelected()) return nullptr; return args->getColor().copy(); } static int setColorObjectAt(struct DragDrop *dd, ColorObject *colorObject, int x, int y, bool, bool) { auto *args = static_cast(dd->userdata); args->select(x, y); args->setColor(*colorObject); return 0; } static bool testAt(struct DragDrop *dd, int x, int y) { auto *args = static_cast(dd->userdata); return args->select(x, y); } static GtkWidget *newLayoutDropdown() { auto store = gtk_list_store_new(LAYOUTLIST_N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER); auto combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); auto renderer = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, true); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), renderer, "text", LAYOUTLIST_LABEL, nullptr); if (store) g_object_unref(store); return combo; } static void onLayoutChange(GtkWidget *widget, LayoutPreviewArgs *args) { GtkTreeIter iter; if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter)) { GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget)); Layout *layout; gtk_tree_model_get(model, &iter, LAYOUTLIST_PTR, &layout, -1); saveColors(args); System *layoutSystem = layout->build(); gtk_layout_preview_set_system(GTK_LAYOUT_PREVIEW(args->layoutView), layoutSystem); if (args->layoutSystem) System::unref(args->layoutSystem); args->layoutSystem = layoutSystem; args->options->set("layout_name", layout->name()); loadColors(args); } } static int saveCssFile(const char *filename, LayoutPreviewArgs *args) { if (args->layoutSystem == nullptr) return -1; std::ofstream file(filename, std::ios::out); if (!file.is_open()) return -1; auto converter = args->gs->converters().firstCopy(); auto assignments = args->options->getOrCreateMap("css_selectors.assignments"); for (auto style: args->layoutSystem->styles) { auto cssSelector = assignments->getString(style->ident_name + ".selector", style->ident_name); if (cssSelector.empty()) continue; ColorObject colorObject(style->color); std::string text = converter->serialize(colorObject); file << cssSelector << " {\n"; if (style->style_type == Style::TYPE_BACKGROUND) { file << "\tbackground-color: " << text << ";\n"; } else if (style->style_type == Style::TYPE_COLOR) { file << "\tcolor: " << text << ";\n"; } else if (style->style_type == Style::TYPE_BORDER) { file << "\tborder-color: " << text << ";\n"; } file << "}\n\n"; } file.close(); return 0; } static void onExportCss(GtkWidget *widget, LayoutPreviewArgs *args) { if (!args->lastFilename.empty()) { if (saveCssFile(args->lastFilename.c_str(), args) == 0) { } else { GtkWidget *message = gtk_message_dialog_new(GTK_WINDOW(gtk_widget_get_toplevel(widget)), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("File could not be saved")); gtk_dialog_run(GTK_DIALOG(message)); gtk_widget_destroy(message); } return; } auto dialog = gtk_file_chooser_dialog_new(_("Export"), GTK_WINDOW(gtk_widget_get_toplevel(widget)), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, nullptr); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), true); auto default_path = args->options->getString("export_path", ""); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), default_path.c_str()); auto filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("Cascading Style Sheets *.css")); gtk_file_filter_add_pattern(filter, "*.css"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); gboolean finished = false; while (!finished) { if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { gchar *filename; filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gchar *path = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog)); args->options->set("export_path", path); g_free(path); if (saveCssFile(filename, args) == 0) { args->lastFilename = filename; finished = true; } else { GtkWidget *message; message = gtk_message_dialog_new(GTK_WINDOW(dialog), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("File could not be saved")); //gtk_window_set_title(GTK_WINDOW(dialog), "Open"); gtk_dialog_run(GTK_DIALOG(message)); gtk_widget_destroy(message); } g_free(filename); } else break; } gtk_widget_destroy(dialog); } static void onExportCssAs(GtkWidget *widget, LayoutPreviewArgs *args) { args->lastFilename = ""; onExportCss(widget, args); } static GtkWidget *withLabel(GtkWidget *widget, const char *label) { GtkWidget *hbox = gtk_hbox_new(false, 5); gtk_box_pack_start(GTK_BOX(hbox), gtk_label_aligned_new(label, 0, 0.5, 0, 0), false, true, 0); gtk_box_pack_start(GTK_BOX(hbox), widget, true, true, 0); return hbox; } static gboolean onButtonPress(GtkWidget *widget, GdkEventButton *event, LayoutPreviewArgs *args) { if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) { args->addToPalette(); return true; } return false; } static int activate(LayoutPreviewArgs *args) { auto chain = args->gs->getTransformationChain(); gtk_layout_preview_set_transformation_chain(GTK_LAYOUT_PREVIEW(args->layoutView), chain); gtk_statusbar_push(GTK_STATUSBAR(args->statusBar), gtk_statusbar_get_context_id(GTK_STATUSBAR(args->statusBar), "empty"), ""); return 0; } static ColorSource *source_implement(ColorSource *source, GlobalState *gs, const dynv::Ref &options) { auto *args = new LayoutPreviewArgs; args->editable = LayoutPreviewArgs::Editable(args); args->options = options; args->statusBar = gs->getStatusBar(); args->gs = gs; args->layoutSystem = nullptr; color_source_init(&args->source, source->identificator, source->hr_name); args->source.destroy = (int (*)(ColorSource *))destroy; args->source.get_color = (int (*)(ColorSource *, ColorObject **))getColor; args->source.set_color = (int (*)(ColorSource *, ColorObject *))setColor; args->source.deactivate = (int (*)(ColorSource *))deactivate; args->source.activate = (int (*)(ColorSource *))activate; GtkWidget *table, *vbox, *hbox; vbox = gtk_vbox_new(false, 10); hbox = gtk_hbox_new(false, 10); gtk_box_pack_start(GTK_BOX(vbox), hbox, true, true, 5); gint table_y; table = gtk_table_new(4, 4, false); gtk_box_pack_start(GTK_BOX(hbox), table, true, true, 5); table_y = 0; auto toolbar = gtk_toolbar_new(); gtk_table_attach(GTK_TABLE(table), toolbar, 0, 3, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 0, 0); table_y++; auto tool = gtk_tool_item_new(); gtk_tool_item_set_expand(tool, true); GtkWidget *layoutDropdown = newLayoutDropdown(); gtk_container_add(GTK_CONTAINER(tool), withLabel(layoutDropdown, _("Layout:"))); gtk_toolbar_insert(GTK_TOOLBAR(toolbar), tool, -1); g_signal_connect(G_OBJECT(layoutDropdown), "changed", G_CALLBACK(onLayoutChange), args); gtk_toolbar_insert(GTK_TOOLBAR(toolbar), gtk_separator_tool_item_new(), -1); tool = gtk_menu_tool_button_new(newIcon(GTK_STOCK_SAVE, IconSize::toolbar), _("Export CSS File")); gtk_tool_item_set_tooltip_text(tool, _("Export CSS file")); g_signal_connect(G_OBJECT(tool), "clicked", G_CALLBACK(onExportCss), args); gtk_toolbar_insert(GTK_TOOLBAR(toolbar), tool, -1); auto menu = gtk_menu_new(); auto item = newMenuItem(_("_Export CSS File As..."), GTK_STOCK_SAVE_AS); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(onExportCssAs), args); item = gtk_menu_item_new_with_mnemonic(_("_Assign CSS Selectors...")); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(onAssignSelectors), args); gtk_widget_show_all(menu); gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(tool), menu); GtkWidget *scrolled = gtk_scrolled_window_new(0, 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_table_attach(GTK_TABLE(table), scrolled, 0, 3, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL | GTK_EXPAND), 0, 0); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled), args->layoutView = gtk_layout_preview_new()); g_signal_connect_after(G_OBJECT(args->layoutView), "button-press-event", G_CALLBACK(onButtonPress), args); StandardEventHandler::forWidget(args->layoutView, args->gs, &*args->editable); table_y++; struct DragDrop dd; dragdrop_init(&dd, gs); dd.converterType = Converters::Type::display; dd.userdata = args; dd.get_color_object = getColorObject; dd.set_color_object_at = setColorObjectAt; dd.test_at = testAt; gtk_drag_dest_set(args->layoutView, GtkDestDefaults(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT), 0, 0, GDK_ACTION_COPY); gtk_drag_source_set(args->layoutView, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY); dragdrop_widget_attach(args->layoutView, DragDropFlags(DRAGDROP_SOURCE | DRAGDROP_DESTINATION), &dd); // Restore settings and fill list auto layoutName = args->options->getString("layout_name", "std_layout_menu_1"); GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(layoutDropdown)); GtkTreeIter iter1; bool layoutFound = false; for (auto &layout: gs->layouts().all()) { if (layout->mask() != 0) continue; gtk_list_store_append(GTK_LIST_STORE(model), &iter1); gtk_list_store_set(GTK_LIST_STORE(model), &iter1, LAYOUTLIST_LABEL, layout->label().c_str(), LAYOUTLIST_PTR, layout, -1); if (layout->name() == layoutName) { gtk_combo_box_set_active_iter(GTK_COMBO_BOX(layoutDropdown), &iter1); layoutFound = true; } } if (!layoutFound) { gtk_combo_box_set_active(GTK_COMBO_BOX(layoutDropdown), 0); } gtk_widget_show_all(vbox); args->main = vbox; args->source.widget = vbox; return (ColorSource *)args; } int layout_preview_source_register(ColorSourceManager *csm) { ColorSource *color_source = new ColorSource; color_source_init(color_source, "layout_preview", _("Layout preview")); color_source->needs_viewport = false; color_source->implement = source_implement; color_source->default_accelerator = GDK_KEY_l; color_source_manager_add_source(csm, color_source); return 0; } gpick-gpick-0.2.6/source/LayoutPreview.h000066400000000000000000000033171377073231300202110ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_LAYOUT_PREVIEW_H_ #define GPICK_LAYOUT_PREVIEW_H_ struct ColorSourceManager; int layout_preview_source_register(ColorSourceManager *csm); #endif /* GPICK_LAYOUT_PREVIEW_H_ */ gpick-gpick-0.2.6/source/MathUtil.cpp000066400000000000000000000151421377073231300174530ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "MathUtil.h" #include #include float max_float_3(float a, float b, float c) { if (a > b){ if (a > c){ return a; }else{ return c; } }else{ if (b > c){ return b; }else{ return c; } } } float min_float_3(float a, float b, float c) { if (a < b){ if (a < c){ return a; }else{ return c; } }else{ if (b < c){ return b; }else{ return c; } } } float clamp_float(float x, float a, float b) { if (x < a) return a; if (x > b) return b; return x; } int clamp_int(int x, int a, int b) { if (x < a) return a; if (x > b) return b; return x; } int min_int(int a, int b) { if (a > b) return b; return a; } int max_int(int a, int b) { if (a < b) return b; return a; } int abs_int(int a) { if (a < 0) return -a; return a; } float abs_float(float a) { if (a < 0) return -a; return a; } void matrix3x3_identity(matrix3x3* matrix) { int i,j; for (i=0;i<3;++i){ for (j=0;j<3;++j){ matrix->m[i][j]=((i == j)?1:0); } } } void matrix3x3_copy(const matrix3x3* matrix, matrix3x3* result) { memcpy(result, matrix, sizeof(matrix3x3)); } void matrix3x3_multiply(const matrix3x3* matrix1, const matrix3x3* matrix2, matrix3x3* result){ int i,j,k; matrix3x3 matrix_t; if (matrix1 == result){ matrix3x3_copy(matrix1, &matrix_t); matrix1=&matrix_t; }else if (matrix2 == result){ matrix3x3_copy(matrix2, &matrix_t); matrix2=&matrix_t; } for (i=0;i<3;++i){ for (j=0;j<3;++j){ result->m[i][j]=0; for (k=0;k<3;++k){ result->m[i][j] += matrix1->m[k][j]*matrix2->m[i][k]; } } } } double matrix3x3_determinant(const matrix3x3* matrix) { double det=0; double t; int i,j; for (i=0;i<3;++i){ t=1; for (j=0;j<3;++j){ t*=matrix->m[(i+j)%3][j]; } det+=t; } for (i=0;i<3;++i){ t=1; for (j=0;j<3;++j){ t*=matrix->m[(i+2-j)%3][j]; } det-=t; } return det; } void matrix3x3_transpose(const matrix3x3* matrix, matrix3x3* result) { int i,j; matrix3x3 matrix_t; if (matrix == result){ matrix3x3_copy(matrix, &matrix_t); matrix=&matrix_t; } for (i=0;i<3;++i){ for (j=0;j<3;++j){ result->m[j][i]=matrix->m[i][j]; } } } int matrix3x3_inverse(const matrix3x3* matrix, matrix3x3* result){ double det = matrix3x3_determinant(matrix); if (det == 0) return -1; double invdet=1/det; matrix3x3 matrix_t; if (matrix == result){ matrix3x3_copy(matrix, &matrix_t); matrix=&matrix_t; } result->m[0][0] = (matrix->m[1][1] * matrix->m[2][2] - matrix->m[2][1] * matrix->m[1][2]) * invdet; result->m[0][1] = -(matrix->m[0][1] * matrix->m[2][2] - matrix->m[2][1] * matrix->m[0][2]) * invdet; result->m[0][2] = (matrix->m[0][1] * matrix->m[1][2] - matrix->m[1][1] * matrix->m[0][2]) * invdet; result->m[1][0] = -(matrix->m[1][0] * matrix->m[2][2] - matrix->m[2][0] * matrix->m[1][2]) * invdet; result->m[1][1] = (matrix->m[0][0] * matrix->m[2][2] - matrix->m[2][0] * matrix->m[0][2]) * invdet; result->m[1][2] = -(matrix->m[0][0] * matrix->m[1][2] - matrix->m[1][0] * matrix->m[0][2]) * invdet; result->m[2][0] = (matrix->m[1][0] * matrix->m[2][1] - matrix->m[2][0] * matrix->m[1][1]) * invdet; result->m[2][1] = -(matrix->m[0][0] * matrix->m[2][1] - matrix->m[2][0] * matrix->m[0][1]) * invdet; result->m[2][2] = (matrix->m[0][0] * matrix->m[1][1] - matrix->m[1][0] * matrix->m[0][1]) * invdet; return 0; } void vector2_set(vector2* v1, float x, float y) { v1->x = x; v1->y = y; } float vector2_length(const vector2* v1) { return sqrt(v1->x * v1->x + v1->y * v1->y); } void vector2_normalize(const vector2* v1, vector2* r) { float l = vector2_length(v1); r->x = v1->x / l; r->y = v1->y / l; } float vector2_dot(const vector2* v1, const vector2* v2) { return v1->x * v2->x + v1->y * v2->y; } float mix_float(float a, float b, float mix) { return a * (1 - mix) + b * mix; } double mix_double(double a, double b, double mix){ return a * (1 - mix) + b * mix; } float wrap_float(float x) { return x - floor(x); } int wrap_int(int x, int a, int b) { if (x < a){ return b - (a - x) % (b - a); }else if (x >= b){ return a + (x - b) % (b - a); } return x; } void vector3_multiply_matrix3x3(const vector3* vector, const matrix3x3* matrix, vector3* result) { vector3 vector_t; if (vector == result){ vector3_copy(vector, &vector_t); vector=&vector_t; } result->x = vector->x * matrix->m[0][0] + vector->y * matrix->m[0][1] + vector->z * matrix->m[0][2]; result->y = vector->x * matrix->m[1][0] + vector->y * matrix->m[1][1] + vector->z * matrix->m[1][2]; result->z = vector->x * matrix->m[2][0] + vector->y * matrix->m[2][1] + vector->z * matrix->m[2][2]; } void vector3_set(vector3* vector, float x, float y, float z) { vector->x = x; vector->y = y; vector->z = z; } void vector3_copy(const vector3* vector, vector3* result){ memcpy(result, vector, sizeof(vector3)); } float vector3_length(const vector3* vector) { return sqrt(vector->x * vector->x + vector->y * vector->y + vector->z * vector->z); } void vector3_clamp(vector3* vector, float a, float b){ vector->x = clamp_float(vector->x, a, b); vector->y = clamp_float(vector->y, a, b); vector->z = clamp_float(vector->z, a, b); } gpick-gpick-0.2.6/source/MathUtil.h000066400000000000000000000061731377073231300171240ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_MATH_UTIL_H_ #define GPICK_MATH_UTIL_H_ #define PI 3.14159265 float min_float_3(float a, float b, float c); float max_float_3(float a, float b, float c); int min_int(int a, int b); int max_int(int a, int b); int wrap_int(int x, int a, int b); float clamp_float(float x, float a, float b); float wrap_float(float x); float mix_float(float a, float b, float mix); int clamp_int(int x, int a, int b); int abs_int(int a); float abs_float(float a); double mix_double(double a, double b, double mix); typedef struct matrix3x3{ double m[3][3]; }matrix3x3; void matrix3x3_identity(matrix3x3* matrix); void matrix3x3_multiply(const matrix3x3* matrix1, const matrix3x3* matrix2, matrix3x3* result); double matrix3x3_determinant(const matrix3x3* matrix); int matrix3x3_inverse(const matrix3x3* matrix, matrix3x3* result); void matrix3x3_transpose(const matrix3x3* matrix, matrix3x3* result); typedef struct vector2{ float x; float y; }vector2; void vector2_set(vector2* v1, float x, float y); float vector2_length(const vector2* v1); void vector2_normalize(const vector2* v1, vector2* r); float vector2_dot(const vector2* v1, const vector2* v2); typedef struct vector3{ union{ struct{ float x; float y; float z; }; float m[3]; }; }vector3; void vector3_set(vector3* vector, float x, float y, float z); void vector3_copy(const vector3* vector, vector3* result); float vector3_length(const vector3* vector); void vector3_multiply_matrix3x3(const vector3* vector, const matrix3x3* matrix, vector3* result ); void vector3_clamp(vector3* vector, float a, float b); #endif /* GPICK_MATH_UTIL_H_ */ gpick-gpick-0.2.6/source/Noise.cpp000066400000000000000000000112271377073231300170010ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include static int permutation[512] = { 151,160,137,91,90,15, 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180, 151,160,137,91,90,15, 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180, }; static double fade(double t){ return t * t * t * ( t * (t * 6 - 15) +10); } static double lerp(double t, double a, double b){ return a + t * (b - a); } static double grad(int hash, double x, double y, double z){ int h = hash & 15; double u = h < 8 ? x : y; double v = h < 4 ? y : (h == 12 || h == 14) ? x : z; return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v); } /** * Improved Perlin noise algorithm implemented by using reference Java implementation from. * \see http://mrl.nyu.edu/~perlin/noise/ */ double noise(double x, double y, double z){ int X = (int)floor(x) & 255, Y = (int)floor(y) & 255, Z = (int)floor(z) & 255; x -= floor(x); y -= floor(y); z -= floor(z); double u = fade(x), v = fade(y), w = fade(z); int A = permutation[X]+Y, AA = permutation[A]+Z, AB = permutation[A+1]+Z, B = permutation[X+1]+Y, BA = permutation[B]+Z, BB = permutation[B+1]+Z; return lerp(w, lerp(v, lerp(u, grad(permutation[AA], x, y, z), grad(permutation[BA], x-1, y, z)), lerp(u, grad(permutation[AB], x, y-1, z), grad(permutation[BB], x-1, y-1, z))), lerp(v, lerp(u, grad(permutation[AA+1], x, y, z-1), grad(permutation[BA+1], x-1, y, z-1)), lerp(u, grad(permutation[AB+1], x, y-1, z-1), grad(permutation[BB+1], x-1, y-1, z-1))) ); } gpick-gpick-0.2.6/source/Noise.h000066400000000000000000000035551377073231300164530ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef NOISE_H_ #define NOISE_H_ /** \file source/Noise.h * \brief Improved Perlin noise implementation. */ /** * Returns noise value for specified position. * @param[in] x X coordinate. * @param[in] y y coordinate. * @param[in] z Z coordinate. * @return Noise value. */ double noise(double x, double y, double z); #endif /* NOISE_H_ */ gpick-gpick-0.2.6/source/Paths.cpp000066400000000000000000000067461377073231300170150ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Paths.h" #include #include #include #include #include namespace fs = boost::filesystem; using path = fs::path; struct PathException : std::runtime_error { PathException(const char *message): std::runtime_error(message) { } }; #ifdef BOOST_OS_LINUX static std::string getExecutablePath() { std::vector buffer; buffer.resize(4096); while (1) { int count = ::readlink("/proc/self/exe", &buffer.front(), buffer.size()); if (count < 0) throw PathException("could not read executable path"); if ((size_t)count < buffer.size()) return std::string(buffer.begin(), buffer.begin() + count); buffer.resize(buffer.size() * 2); } } #else static std::string getExecutablePath() { return ""; } #endif static path &getUserConfigPath() { static boost::optional configPath; if (configPath) return *configPath; configPath = path(g_get_user_config_dir()); return *configPath; } static path &getDataPath() { static boost::optional dataPath; if (dataPath) return *dataPath; path testPath; try { if (fs::is_directory(fs::status(testPath = (path(getExecutablePath()).remove_filename() / "share" / "gpick")))) return *(dataPath = testPath); } catch (const PathException &) { } if (fs::is_directory(fs::status(testPath = (path(g_get_user_data_dir()) / "gpick")))) return *(dataPath = testPath); auto dataPaths = g_get_system_data_dirs(); for (size_t i = 0; dataPaths[i]; ++i) { if (fs::is_directory(fs::status(testPath = (path(dataPaths[i]) / "gpick")))) return *(dataPath = testPath); } dataPath = path(); return *dataPath; } std::string buildFilename(const char *filename) { if (filename) return (getDataPath() / filename).string(); else return getDataPath().string(); } std::string buildConfigPath(const char *filename) { if (filename) return (getUserConfigPath() / "gpick" / filename).string(); else return (getUserConfigPath() / "gpick").string(); } gpick-gpick-0.2.6/source/Paths.h000066400000000000000000000041371377073231300164520ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_PATHS_H_ #define GPICK_PATHS_H_ #include /** \file source/Paths.h * \brief Data and configuration filename building functions. */ /** * Construct filename to a data file. * @param[in] filename Relative data file name. * @return Filename to the data file. */ std::string buildFilename(const char *filename = nullptr); /** * Construct filename to a configuration file. * @param[in] filename Relative configuration file name. * @return Filename to the configuration file. */ std::string buildConfigPath(const char *filename = nullptr); #endif /* PATHS_H_ */ gpick-gpick-0.2.6/source/Random.cpp000066400000000000000000000074041377073231300171460ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Random.h" #include static unsigned long random_function_znew(struct Random* r, unsigned long seed_offset) { return (r->seed[seed_offset] = 36969 * (r->seed[seed_offset] & 65535) + (r->seed[seed_offset] >> 16)); } static unsigned long random_function_wnew(struct Random* r, unsigned long seed_offset) { return (r->seed[seed_offset] = 18000 * (r->seed[seed_offset] & 65535) + (r->seed[seed_offset] >> 16)); } static unsigned long random_function_MWC(struct Random* r, unsigned long seed_offset) { return (random_function_znew(r, 0) << 16) + random_function_wnew(r, 1); } static unsigned long random_function_SHR3(struct Random* r, unsigned long seed_offset) { r->seed[seed_offset] ^= r->seed[seed_offset] << 17; r->seed[seed_offset] ^= (r->seed[seed_offset] & 0xFFFFFFFF) >> 13; return (r->seed[seed_offset] ^= r->seed[seed_offset] << 5); } struct Random* random_new(const char* random_function) { struct Random* r = new struct Random; struct RandomFunction { const char* name; unsigned long (*function)(struct Random* r, unsigned long seed_offset); unsigned long seed_size; }; struct RandomFunction functions[] = { {"znew", random_function_znew, 1}, {"wnew", random_function_wnew, 1}, {"MWC", random_function_MWC, 2}, {"SHR3", random_function_SHR3, 1}, }; bool found = false; for (unsigned long i = 0; i < sizeof(functions) / sizeof(struct RandomFunction); ++i){ if (strcmp(random_function, functions[i].name) == 0){ r->function = functions[i].function; r->seed_size = functions[i].seed_size; r->seed = new unsigned long [r->seed_size]; found = true; break; } } if (found) return r; delete r; return 0; } struct Random* random_new(const char* random_function, unsigned long seed) { struct Random* random = random_new(random_function); random_seed(random, &seed); random_get(random); return random; } unsigned long random_get(struct Random* r) { if (!r) return 0; return r->function(r, 0); } double random_get_double(struct Random* r) { return (random_get(r) & 0xFFFFFFFF) / (double)0xFFFFFFFF; } void random_seed(struct Random* r, void* seed) { if (!r) return; memcpy(r->seed, seed, r->seed_size * sizeof(unsigned long)); } void random_destroy(struct Random* r) { if (r){ delete [] r->seed; delete r; } } gpick-gpick-0.2.6/source/Random.h000066400000000000000000000040361377073231300166110ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_RANDOM_H_ #define GPICK_RANDOM_H_ struct Random { unsigned long (*function)(struct Random* r, unsigned long seed_offset); unsigned long *seed; unsigned long seed_size; }; struct Random* random_new(const char* random_function); struct Random* random_new(const char* random_function, unsigned long seed); unsigned long random_get(struct Random* r); double random_get_double(struct Random* r); void random_seed(struct Random* r, void* seed); void random_destroy(struct Random* r); #endif /* GPICK_RANDOM_H_ */ gpick-gpick-0.2.6/source/Rect2.h000066400000000000000000000102531377073231300163460ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_RECT2_H_ #define GPICK_RECT2_H_ #include "Vector2.h" namespace math { template struct Rect2 { Rect2() { empty = true; }; Rect2(const T &x1_, const T &y1_, const T &x2_, const T &y2_): x1(x1_), y1(y1_), x2(x2_), y2(y2_) { empty = false; }; const Rect2 operator=(const Rect2 &rect) { x1 = rect.x1; y1 = rect.y1; x2 = rect.x2; y2 = rect.y2; empty = rect.empty; return *this; }; const Rect2 operator+(const Rect2 &rect) const { if (rect.empty) return *this; if (empty) return rect; Rect2 r; if (x1 < rect.x1) r.x1 = x1; else r.x1 = rect.x1; if (y1 < rect.y1) r.y1 = y1; else r.y1 = rect.y1; if (x2 > rect.x2) r.x2 = x2; else r.x2 = rect.x2; if (y2 > rect.y2) r.y2 = y2; else r.y2 = rect.y2; return r; }; const Rect2 operator+=(const Rect2 &rect) { *this = *this+rect; return *this; }; Rect2 impose(const Rect2 &rect) const { Rect2 r; r.x1 = rect.x1 + x1 * rect.getWidth(); r.y1 = rect.y1 + y1 * rect.getHeight(); r.x2 = rect.x1 + x2 * rect.getWidth(); r.y2 = rect.y1 + y2 * rect.getHeight(); r.empty = false; return r; } bool isInside(const T &x, const T &y) const { if (x < x1 || x > x2 || y < y1 || y > y2) return false; else return true; } bool isInside(const Rect2 &r) const { if (empty || r.empty) return false; if (x1 < r.x1 || x2 > r.x2) return false; if (y1 < r.y1 || y2 > r.y2) return false; return true; } Rect2 positionInside(const Rect2& rect) const { Rect2 r; r.empty = false; if (rect.x1 < x1){ r.x1 = x1; r.x2 = x1 + rect.getWidth(); }else if (rect.x2 > x2){ r.x1 = x2 - rect.getWidth(); r.x2 = x2; }else{ r.x1 = rect.x1; r.x2 = rect.x2; } if (rect.y1 < y1){ r.y1 = y1; r.y2 = y1 + rect.getHeight(); }else if (rect.y2 > y2){ r.y1 = y2 - rect.getHeight(); r.y2 = y2; }else{ r.y1 = rect.y1; r.y2 = rect.y2; } return r; } bool isEmpty() const { return empty; }; const T& getX() const { return x1; }; const T& getY() const { return y1; }; T getWidth() const { return x2 - x1; }; T getHeight() const { return y2 - y1; }; T getCenterX() const { return (x1 + x2) / 2; }; T getCenterY() const { return (y1 + y2) / 2; }; const T& getLeft() const { return x1; }; const T& getTop() const { return y1; }; const T& getRight() const { return x2; }; const T& getBottom() const { return y2; }; Vec2 position() const { return Vec2(x1, y1); } Vec2 center() const { return Vec2((x1 + x2) / 2, (y1 + y2) / 2); } Vec2 size() const { return Vec2(x2 - x1, y2 - y1); } private: bool empty; T x1, y1, x2, y2; }; } #endif /* GPICK_RECT2_H_ */ gpick-gpick-0.2.6/source/RegisterSources.cpp000066400000000000000000000041521377073231300210530ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "RegisterSources.h" #include "GenerateScheme.h" #include "ColorPicker.h" #include "LayoutPreview.h" #include "Variations.h" #include "BrightnessDarkness.h" #include "ColorMixer.h" #include "BlendColors.h" #include "ClosestColors.h" int register_sources(ColorSourceManager *csm) { generate_scheme_source_register(csm); color_picker_source_register(csm); layout_preview_source_register(csm); variations_source_register(csm); brightness_darkness_source_register(csm); color_mixer_source_register(csm); blend_colors_source_register(csm); closest_colors_source_register(csm); return 0; } gpick-gpick-0.2.6/source/RegisterSources.h000066400000000000000000000033121377073231300205150ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_REGISTER_SOURCES_H_ #define GPICK_REGISTER_SOURCES_H_ #include "ColorSourceManager.h" int register_sources(ColorSourceManager *csm); #endif /* GPICK_REGISTER_SOURCES_H_ */ gpick-gpick-0.2.6/source/Sampler.cpp000066400000000000000000000132211377073231300173230ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Sampler.h" #include "ScreenReader.h" #include "MathUtil.h" #include #include using namespace math; struct Sampler { int oversample; SamplerFalloff falloff; float (*falloff_fnc)(float distance); ScreenReader* screen_reader; }; static float sampler_falloff_none(float distance) { return 1; } static float sampler_falloff_linear(float distance) { return 1 - distance; } static float sampler_falloff_quadratic(float distance) { return 1 - (distance * distance); } static float sampler_falloff_cubic(float distance) { return 1 - (distance * distance * distance); } static float sampler_falloff_exponential(float distance) { return 1 / exp(5 * distance * distance); } struct Sampler* sampler_new(ScreenReader* screen_reader) { Sampler* sampler = new Sampler; sampler->oversample = 0; sampler_set_falloff(sampler, SamplerFalloff::none); sampler->screen_reader = screen_reader; return sampler; } void sampler_destroy(Sampler *sampler) { delete sampler; } void sampler_set_falloff(Sampler *sampler, SamplerFalloff falloff) { sampler->falloff = falloff; switch (falloff){ case SamplerFalloff::none: sampler->falloff_fnc = sampler_falloff_none; break; case SamplerFalloff::linear: sampler->falloff_fnc = sampler_falloff_linear; break; case SamplerFalloff::quadratic: sampler->falloff_fnc = sampler_falloff_quadratic; break; case SamplerFalloff::cubic: sampler->falloff_fnc = sampler_falloff_cubic; break; case SamplerFalloff::exponential: sampler->falloff_fnc = sampler_falloff_exponential; break; default: sampler->falloff_fnc = 0; } } void sampler_set_oversample(Sampler *sampler, int oversample) { sampler->oversample = oversample; } static void get_pixel(unsigned char *data, int stride, int x, int y, Color* color) { unsigned char *p; p = data + y * stride + x * 4; color->rgb.red = p[2] * (1 / 255.0); color->rgb.green = p[1] * (1 / 255.0); color->rgb.blue = p[0] * (1 / 255.0); } int sampler_get_color_sample(Sampler *sampler, Vec2& pointer, Rect2& screen_rect, Vec2& offset, Color* color) { Color sample, result; float divider = 0; color_zero(&result); cairo_surface_t *surface = screen_reader_get_surface(sampler->screen_reader); int x = pointer.x, y = pointer.y; int left, right, top, bottom; left = max_int(screen_rect.getLeft(), x - sampler->oversample); right = min_int(screen_rect.getRight(), x + sampler->oversample + 1); top = max_int(screen_rect.getTop(), y - sampler->oversample); bottom = min_int(screen_rect.getBottom(), y + sampler->oversample + 1); int width = right - left; int height = bottom - top; int center_x = x - left; int center_y = y - top; float max_distance = 1 / sqrt(2 * pow((double)sampler->oversample, 2)); unsigned char *data = cairo_image_surface_get_data(surface); int stride = cairo_image_surface_get_stride(surface); for (int x=-sampler->oversample; x <= sampler->oversample; ++x){ for (int y=-sampler->oversample; y <= sampler->oversample; ++y){ if ((center_x + x < 0) || (center_y + y < 0)) continue; if ((center_x + x >= width) || (center_y + y >= height)) continue; get_pixel(data, stride, offset.x + center_x + x, offset.y + center_y + y, &sample); float f; if (sampler->oversample){ f = sampler->falloff_fnc(sqrt((double)(x * x + y * y)) * max_distance); }else{ f = 1; } color_multiply(&sample, f); color_add(&result, &sample); divider += f; } } if (divider > 0) color_multiply(&result, 1 / divider); color_copy(&result, color); return 0; } SamplerFalloff sampler_get_falloff(Sampler *sampler) { return sampler->falloff; } int sampler_get_oversample(Sampler *sampler) { return sampler->oversample; } void sampler_get_screen_rect(Sampler *sampler, math::Vec2& pointer, math::Rect2& screen_rect, math::Rect2 *rect) { int left, right, top, bottom; left = max_int(screen_rect.getLeft(), pointer.x - sampler->oversample); right = min_int(screen_rect.getRight(), pointer.x + sampler->oversample + 1); top = max_int(screen_rect.getTop(), pointer.y - sampler->oversample); bottom = min_int(screen_rect.getBottom(), pointer.y + sampler->oversample + 1); *rect = math::Rect2(left, top, right, bottom); } gpick-gpick-0.2.6/source/Sampler.h000066400000000000000000000045771377073231300170060ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_SAMPLER_H_ #define GPICK_SAMPLER_H_ #include "Color.h" #include "Rect2.h" #include "Vector2.h" struct Sampler; struct ScreenReader; enum class SamplerFalloff: int { none = 0, linear = 1, quadratic = 2, cubic = 3, exponential = 4, }; Sampler* sampler_new(ScreenReader* screen_reader); void sampler_set_falloff(Sampler *sampler, SamplerFalloff falloff); void sampler_set_oversample(Sampler *sampler, int oversample); SamplerFalloff sampler_get_falloff(Sampler *sampler); int sampler_get_oversample(Sampler *sampler); void sampler_destroy(Sampler *sampler); int sampler_get_color_sample(Sampler *sampler, math::Vec2& pointer, math::Rect2& screen_rect, math::Vec2& offset, Color* color); void sampler_get_screen_rect(Sampler *sampler, math::Vec2& pointer, math::Rect2& screen_rect, math::Rect2 *rect); #endif /* GPICK_SAMPLER_H_ */ gpick-gpick-0.2.6/source/ScreenReader.cpp000066400000000000000000000074741377073231300202770ustar00rootroot00000000000000/* * Copyright (c) 2009-2018, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ScreenReader.h" #include "Rect2.h" #include #include #include using namespace math; using namespace std; struct ScreenReader { cairo_surface_t *surface; int max_size; GdkScreen *screen; Rect2 read_area; }; struct ScreenReader* screen_reader_new() { ScreenReader* screen = new ScreenReader; screen->max_size = 0; screen->surface = 0; screen->screen = 0; return screen; } void screen_reader_destroy(ScreenReader *screen) { if (screen->surface) cairo_surface_destroy(screen->surface); delete screen; } void screen_reader_add_rect(ScreenReader *screen, GdkScreen *gdk_screen, Rect2& rect) { if (screen->screen && (screen->screen == gdk_screen)){ screen->read_area += rect; }else{ screen->read_area += rect; screen->screen = gdk_screen; } } void screen_reader_reset_rect(ScreenReader *screen) { screen->read_area = Rect2(); screen->screen = NULL; } void screen_reader_update_surface(ScreenReader *screen, Rect2* update_rect) { if (!screen->screen) return; int left = screen->read_area.getX(); int top = screen->read_area.getY(); int width = screen->read_area.getWidth(); int height = screen->read_area.getHeight(); if (width > screen->max_size || height > screen->max_size){ if (screen->surface) cairo_surface_destroy(screen->surface); screen->max_size = (std::max(width, height) / 150 + 1) * 150; screen->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, screen->max_size, screen->max_size); } GdkWindow* root_window = gdk_screen_get_root_window(screen->screen); cairo_t *root_cr = gdk_cairo_create(root_window); cairo_surface_t *root_surface = cairo_get_target(root_cr); if (cairo_surface_status(root_surface) != CAIRO_STATUS_SUCCESS){ cerr << "can not get root window surface" << endl; return; } cairo_surface_mark_dirty_rectangle(root_surface, left, top, width, height); cairo_t *cr = cairo_create(screen->surface); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_surface(cr, root_surface, -left, -top); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST); cairo_rectangle(cr, 0, 0, width, height); cairo_fill(cr); cairo_destroy(cr); cairo_destroy(root_cr); *update_rect = screen->read_area; } cairo_surface_t* screen_reader_get_surface(ScreenReader *screen) { return screen->surface; } gpick-gpick-0.2.6/source/ScreenReader.h000066400000000000000000000040741377073231300177350ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef SCREENREADER_H_ #define SCREENREADER_H_ #include #include #include "Rect2.h" struct ScreenReader; ScreenReader* screen_reader_new(); void screen_reader_reset_rect(ScreenReader *screen); void screen_reader_add_rect(ScreenReader *screen, GdkScreen *gdk_screen, math::Rect2& rect); void screen_reader_update_surface(ScreenReader *screen, math::Rect2* update_rect); cairo_surface_t* screen_reader_get_surface(ScreenReader *screen); void screen_reader_destroy(ScreenReader *screen); #endif /* SCREENREADER_H_ */ gpick-gpick-0.2.6/source/StandardEventHandler.cpp000066400000000000000000000136001377073231300217610ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "StandardEventHandler.h" #include "StandardMenu.h" #include "Clipboard.h" #include "uiColorInput.h" #include "GlobalState.h" #include "uiUtilities.h" #include "ColorObject.h" #include "common/CastToVariant.h" #include static gboolean onKeyPress(GtkWidget *widget, GdkEventKey *event, IReadonlyColorUI *readonlyColorUI) { auto *gs = reinterpret_cast(g_object_get_data(G_OBJECT(widget), "gs")); auto modifiers = gtk_accelerator_get_default_mod_mask(); switch (getKeyval(*event, gs->latinKeysGroup)) { case GDK_KEY_c: if ((event->state & modifiers) == GDK_CONTROL_MASK) { auto *editableColorsUI = dynamic_cast(readonlyColorUI); if (editableColorsUI) { auto colors = editableColorsUI->getColors(true); if (colors.size() > 0) clipboard::set(colors, gs, Converters::Type::copy); return true; } auto *readonlyColorsUI = dynamic_cast(readonlyColorUI); if (readonlyColorsUI) { auto colors = readonlyColorsUI->getColors(true); if (colors.size() > 0) clipboard::set(colors, gs, Converters::Type::copy); return true; } auto &colorObject = readonlyColorUI->getColor(); clipboard::set(colorObject, gs, Converters::Type::copy); return true; } return false; case GDK_KEY_v: if ((event->state & modifiers) == GDK_CONTROL_MASK) { auto *editableColorUI = dynamic_cast(readonlyColorUI); if (!editableColorUI || !editableColorUI->isEditable()) return false; auto colorObject = clipboard::getFirst(gs); if (colorObject) { editableColorUI->setColor(*colorObject); colorObject->release(); } return true; } return false; case GDK_KEY_a: if ((event->state & modifiers) == GDK_CONTROL_MASK) { auto *readonlyColorsUI = dynamic_cast(readonlyColorUI); if (!readonlyColorsUI) return false; readonlyColorsUI->addAllToPalette(); } else { auto &colorObject = readonlyColorUI->getColor(); readonlyColorUI->addToPalette(colorObject); } return true; case GDK_KEY_e: { auto *editableColorUI = dynamic_cast(readonlyColorUI); if (!editableColorUI || !editableColorUI->isEditable()) return false; auto *colorObject = readonlyColorUI->getColor().copy(); ColorObject *newColorObject; if (dialog_color_input_show(GTK_WINDOW(gtk_widget_get_toplevel(widget)), gs, colorObject, &newColorObject) == 0) { editableColorUI->setColor(*newColorObject); newColorObject->release(); } colorObject->release(); return true; } } return false; } static gboolean onButtonPress(GtkWidget *widget, GdkEventButton *event, IReadonlyColorUI *readonlyColorUI) { if (event->button == 3) { auto *gs = reinterpret_cast(g_object_get_data(G_OBJECT(widget), "gs")); auto interface = common::castToVariant(readonlyColorUI); StandardMenu::forInterface(gs, event, interface); return true; } return false; } static void onPopupMenu(GtkWidget *widget, IReadonlyColorUI *readonlyColorUI) { auto *gs = reinterpret_cast(g_object_get_data(G_OBJECT(widget), "gs")); auto interface = common::castToVariant(readonlyColorUI); StandardMenu::forInterface(gs, nullptr, interface); } StandardEventHandler::Options::Options(): m_afterEvents(true) { } StandardEventHandler::Options &StandardEventHandler::Options::afterEvents(bool enable) { m_afterEvents = enable; return *this; } void StandardEventHandler::forWidget(GtkWidget *widget, GlobalState *gs, Interface interface, Options options) { void *data = boost::apply_visitor([](auto *interface) -> void * { return interface; }, interface); if (options.m_afterEvents) { g_signal_connect_after(G_OBJECT(widget), "key_press_event", G_CALLBACK(onKeyPress), data); g_signal_connect_after(G_OBJECT(widget), "button-press-event", G_CALLBACK(onButtonPress), data); g_signal_connect_after(G_OBJECT(widget), "popup-menu", G_CALLBACK(onPopupMenu), data); } else { g_signal_connect(G_OBJECT(widget), "key_press_event", G_CALLBACK(onKeyPress), data); g_signal_connect(G_OBJECT(widget), "button-press-event", G_CALLBACK(onButtonPress), data); g_signal_connect(G_OBJECT(widget), "popup-menu", G_CALLBACK(onPopupMenu), data); } g_object_set_data(G_OBJECT(widget), "gs", gs); } gpick-gpick-0.2.6/source/StandardEventHandler.h000066400000000000000000000043021377073231300214250ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_STANDARD_EVENT_HANDLER_H_ #define GPICK_STANDARD_EVENT_HANDLER_H_ #include "IEditableColorUI.h" #include "IReadonlyColorUI.h" #include #include struct ColorObject; struct GlobalState; struct StandardEventHandler { using Interface = boost::variant; struct Options { Options(); Options &afterEvents(bool enable); private: bool m_afterEvents; friend StandardEventHandler; }; static void forWidget(GtkWidget *widget, GlobalState *gs, Interface interface, Options options = {}); private: GlobalState *gs; }; #endif /* GPICK_STANDARD_EVENT_HANDLER_H_ */ gpick-gpick-0.2.6/source/StandardMenu.cpp000066400000000000000000000405461377073231300203170ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "StandardMenu.h" #include "ColorObject.h" #include "Clipboard.h" #include "Converters.h" #include "Converter.h" #include "GlobalState.h" #include "ColorList.h" #include "uiUtilities.h" #include "uiColorInput.h" #include "I18N.h" #include "common/CastToVariant.h" #include "IMenuExtension.h" #include #include struct CopyMenuItemState: public boost::static_visitor<> { CopyMenuItemState(Converter *converter, const ColorObject &colorObject, GlobalState *gs): m_converter(converter), m_data(colorObject), m_gs(gs), m_recursion(false) { } CopyMenuItemState(Converter *converter, IReadonlyColorUI *interface, GlobalState *gs): m_converter(converter), m_data(interface), m_gs(gs), m_recursion(false) { } static void onReleaseState(CopyMenuItemState *state) { delete state; } static void onActivate(GtkWidget *widget, CopyMenuItemState *state) { boost::apply_visitor(*state, state->m_data); } void operator()(const ColorObject &colorObject) { clipboard::set(colorObject, m_gs, m_converter); } // this method will be called recursively if up-casting fails, so m_recursion is used to detect that void operator()(IReadonlyColorUI *interface) { if (m_recursion) { auto color = interface->getColor(); clipboard::set(color, m_gs, m_converter); return; } m_recursion = true; auto variant = common::castToVariant(interface); boost::apply_visitor(*this, variant); m_recursion = false; } void operator()(IEditableColorsUI *interface) { auto colors = interface->getColors(true); clipboard::set(colors, m_gs, m_converter); } void operator()(IReadonlyColorsUI *interface) { auto colors = interface->getColors(true); clipboard::set(colors, m_gs, m_converter); } private: Converter *m_converter; boost::variant m_data; GlobalState *m_gs; bool m_recursion; }; GtkWidget *StandardMenu::newItem(const ColorObject &colorObject, GlobalState *gs, bool includeName) { ConverterSerializePosition position; auto converter = gs->converters().firstCopyOrAny(); if (!converter) return nullptr; auto textLine = converter->serialize(colorObject, position); if (includeName) { textLine += " - "; textLine += colorObject.getName(); } auto item = newMenuItem(textLine.c_str(), GTK_STOCK_COPY); auto state = new CopyMenuItemState(converter, colorObject, gs); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(&CopyMenuItemState::onActivate), state); g_object_set_data_full(G_OBJECT(item), "item_data", state, (GDestroyNotify)&CopyMenuItemState::onReleaseState); return item; } GtkWidget *StandardMenu::newItem(const ColorObject &colorObject, Converter *converter, GlobalState *gs) { ConverterSerializePosition position; auto textLine = converter->serialize(colorObject, position); auto item = newMenuItem(textLine.c_str(), GTK_STOCK_COPY); auto state = new CopyMenuItemState(converter, colorObject, gs); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(&CopyMenuItemState::onActivate), state); g_object_set_data_full(G_OBJECT(item), "item_data", state, (GDestroyNotify)&CopyMenuItemState::onReleaseState); return item; } GtkWidget *StandardMenu::newItem(const ColorObject &colorObject, IReadonlyColorUI *interface, Converter *converter, GlobalState *gs) { ConverterSerializePosition position; auto textLine = converter->serialize(colorObject, position); auto item = newMenuItem(textLine.c_str(), GTK_STOCK_COPY); auto state = new CopyMenuItemState(converter, interface, gs); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(&CopyMenuItemState::onActivate), state); g_object_set_data_full(G_OBJECT(item), "item_data", state, (GDestroyNotify)&CopyMenuItemState::onReleaseState); return item; } GtkWidget *StandardMenu::newMenu(const ColorObject &colorObject, GlobalState *gs) { GtkWidget *menu = gtk_menu_new(); for (auto &converter: gs->converters().allCopy()) { GtkWidget *item = newItem(colorObject, converter, gs); if (item) gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); } return menu; } GtkWidget *StandardMenu::newMenu(const ColorObject &colorObject, IReadonlyColorUI *interface, GlobalState *gs) { GtkWidget *menu = gtk_menu_new(); for (auto &converter: gs->converters().allCopy()) { GtkWidget *item = newItem(colorObject, interface, converter, gs); if (item) gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); } return menu; } GtkWidget *StandardMenu::newNearestColorsMenu(const ColorObject &colorObject, GlobalState *gs) { GtkWidget *menu = gtk_menu_new(); std::multimap colorDistances; Color sourceColor = colorObject.getColor(); for (auto &colorObject: gs->getColorList()->colors) { Color targetColor = colorObject->getColor(); colorDistances.insert(std::pair(color_distance_lch(&sourceColor, &targetColor), colorObject)); } int count = 0; for (auto item: colorDistances) { gtk_menu_shell_append(GTK_MENU_SHELL(menu), newItem(*item.second, gs, true)); if (++count >= 3) break; } return menu; } static void buildMenu(GtkWidget *menu, GtkWidget **copyToClipboard, GtkWidget **nearestFromPalette) { GtkAccelGroup *accel_group = gtk_menu_get_accel_group(GTK_MENU(menu)); GtkWidget *item = *copyToClipboard = gtk_menu_item_new_with_mnemonic(_("_Copy to clipboard")); if (accel_group) gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_c, GdkModifierType(GDK_CONTROL_MASK), GTK_ACCEL_VISIBLE); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); item = *nearestFromPalette = gtk_menu_item_new_with_mnemonic(_("_Nearest from palette")); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); } void StandardMenu::appendMenu(GtkWidget *menu, const ColorObject &colorObject, GlobalState *gs) { GtkWidget *copyToClipboard, *nearestFromPalette; buildMenu(menu, ©ToClipboard, &nearestFromPalette); gtk_menu_item_set_submenu(GTK_MENU_ITEM(copyToClipboard), newMenu(colorObject, gs)); gtk_menu_item_set_submenu(GTK_MENU_ITEM(nearestFromPalette), newNearestColorsMenu(colorObject, gs)); } void StandardMenu::appendMenu(GtkWidget *menu, IReadonlyColorUI *interface, GlobalState *gs) { GtkWidget *copyToClipboard, *nearestFromPalette; buildMenu(menu, ©ToClipboard, &nearestFromPalette); if (interface->hasSelectedColor()) { auto colorObject = interface->getColor(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(copyToClipboard), newMenu(colorObject, interface, gs)); gtk_menu_item_set_submenu(GTK_MENU_ITEM(nearestFromPalette), newNearestColorsMenu(colorObject, gs)); } else { gtk_menu_item_set_submenu(GTK_MENU_ITEM(copyToClipboard), gtk_menu_new()); gtk_menu_item_set_submenu(GTK_MENU_ITEM(nearestFromPalette), gtk_menu_new()); gtk_widget_set_sensitive(copyToClipboard, false); gtk_widget_set_sensitive(nearestFromPalette, false); } } void StandardMenu::appendMenu(GtkWidget *menu, const Color &color, GlobalState *gs) { GtkWidget *copyToClipboard, *nearestFromPalette; buildMenu(menu, ©ToClipboard, &nearestFromPalette); ColorObject colorObject("", color); gtk_menu_item_set_submenu(GTK_MENU_ITEM(copyToClipboard), newMenu(colorObject, gs)); gtk_menu_item_set_submenu(GTK_MENU_ITEM(nearestFromPalette), newNearestColorsMenu(colorObject, gs)); } void StandardMenu::appendMenu(GtkWidget *menu) { GtkWidget *copyToClipboard, *nearestFromPalette; buildMenu(menu, ©ToClipboard, &nearestFromPalette); gtk_widget_set_sensitive(copyToClipboard, false); gtk_widget_set_sensitive(nearestFromPalette, false); } StandardMenu::Appender::Appender(GtkWidget *menu, GtkAccelGroup *acceleratorGroup, void *data): menu(menu), acceleratorGroup(acceleratorGroup), data(data) { } GtkWidget *StandardMenu::Appender::appendItem(const char *label, const char *icon, guint key, GdkModifierType modifiers, GCallback callback, bool enabled) { auto item = newMenuItem(label, icon); gtk_widget_add_accelerator(item, "activate", gtk_menu_get_accel_group(GTK_MENU(menu)), key, modifiers, GTK_ACCEL_VISIBLE); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(callback), data); gtk_widget_set_sensitive(item, enabled); return item; } GtkWidget *StandardMenu::Appender::appendSeparator() { GtkWidget *item; gtk_menu_shell_append(GTK_MENU_SHELL(menu), item = gtk_separator_menu_item_new()); return item; } static void onEditableColorAdd(GtkWidget *widget, IReadonlyColorUI *readonlyColorUI) { auto *colorObject = reinterpret_cast(g_object_get_data(G_OBJECT(gtk_widget_get_parent(widget)), "color")); if (colorObject) readonlyColorUI->addToPalette(*colorObject); else readonlyColorUI->addToPalette(ColorObject()); } static void onEditableColorAddAll(GtkWidget *widget, IReadonlyColorUI *readonlyColorUI) { dynamic_cast(readonlyColorUI)->addAllToPalette(); } static void onEditableColorEdit(GtkWidget *widget, IReadonlyColorUI *readonlyColorUI) { auto *colorObject = reinterpret_cast(g_object_get_data(G_OBJECT(gtk_widget_get_parent(widget)), "color")); auto *gs = reinterpret_cast(g_object_get_data(G_OBJECT(gtk_widget_get_parent(widget)), "gs")); ColorObject *newColorObject; if (colorObject) { if (dialog_color_input_show(GTK_WINDOW(gtk_widget_get_toplevel(widget)), gs, colorObject, &newColorObject) == 0) { dynamic_cast(readonlyColorUI)->setColor(*newColorObject); newColorObject->release(); } } else { auto colorObject = readonlyColorUI->getColor(); if (dialog_color_input_show(GTK_WINDOW(gtk_widget_get_toplevel(widget)), gs, &colorObject, &newColorObject) == 0) { dynamic_cast(readonlyColorUI)->setColor(*newColorObject); newColorObject->release(); } } } static void onEditableColorPaste(GtkWidget *widget, IReadonlyColorUI *readonlyColorUI) { auto *gs = reinterpret_cast(g_object_get_data(G_OBJECT(gtk_widget_get_parent(widget)), "gs")); auto colorObject = clipboard::getFirst(gs); if (colorObject) { dynamic_cast(readonlyColorUI)->setColor(*colorObject); colorObject->release(); } } static void releaseColorObject(ColorObject *colorObject) { colorObject->release(); } struct InterfaceInspector: public boost::static_visitor { InterfaceInspector(bool &editable, bool ¤tlyEditable, bool &multiple, bool &hasSelection, bool &hasColor): editable(editable), currentlyEditable(currentlyEditable), multiple(multiple), hasSelection(hasSelection), hasColor(hasColor) { } template void common(T interface) const { hasSelection = interface->hasSelectedColor(); hasColor = interface->hasColor(); } IReadonlyColorUI *operator()(IReadonlyColorUI *interface) const { editable = false; currentlyEditable = false; multiple = false; hasSelection = interface->hasSelectedColor(); hasColor = true; return interface; } IReadonlyColorUI *operator()(IReadonlyColorsUI *interface) const { editable = false; currentlyEditable = false; multiple = true; common(interface); return interface; } IReadonlyColorUI *operator()(IEditableColorUI *interface) const { editable = true; currentlyEditable = interface->isEditable(); multiple = false; hasSelection = interface->hasSelectedColor(); hasColor = true; return interface; } IReadonlyColorUI *operator()(IEditableColorsUI *interface) const { editable = true; currentlyEditable = interface->isEditable(); multiple = true; common(interface); return interface; } private: bool &editable, ¤tlyEditable, &multiple, &hasSelection, &hasColor; }; void StandardMenu::contextForColorObject(ColorObject *colorObject, GlobalState *gs, GdkEventButton *event, Interface interface) { auto menu = gtk_menu_new(); auto acceleratorGroup = gtk_accel_group_new(); gtk_menu_set_accel_group(GTK_MENU(menu), acceleratorGroup); bool editable = false, currentlyEditable = false, multiple = false, hasSelection = false, hasColor = false; IReadonlyColorUI *baseInterface; Appender appender(menu, acceleratorGroup, (baseInterface = boost::apply_visitor(InterfaceInspector(editable, currentlyEditable, multiple, hasSelection, hasColor), interface))); appender.appendItem(_("_Add to palette"), GTK_STOCK_ADD, GDK_KEY_A, GdkModifierType(0), G_CALLBACK(onEditableColorAdd), hasSelection); if (multiple) { appender.appendItem(_("A_dd all to palette"), GTK_STOCK_ADD, GDK_KEY_A, GdkModifierType(GDK_CONTROL_MASK), G_CALLBACK(onEditableColorAddAll), hasColor); } auto *menuExtension = dynamic_cast(baseInterface); if (menuExtension) menuExtension->extendMenu(menu, IMenuExtension::Position::middle); appender.appendSeparator(); StandardMenu::appendMenu(menu, baseInterface, gs); if (editable) { appender.appendSeparator(); appender.appendItem(_("_Edit..."), GTK_STOCK_EDIT, GDK_KEY_E, GdkModifierType(0), G_CALLBACK(onEditableColorEdit), hasSelection && currentlyEditable); appender.appendItem(_("_Paste"), GTK_STOCK_PASTE, GDK_KEY_V, GdkModifierType(GDK_CONTROL_MASK), G_CALLBACK(onEditableColorPaste), hasSelection && currentlyEditable && clipboard::colorObjectAvailable()); } if (menuExtension) menuExtension->extendMenu(menu, IMenuExtension::Position::end); g_object_set_data_full(G_OBJECT(menu), "color", colorObject->reference(), (GDestroyNotify)releaseColorObject); if (editable) g_object_set_data(G_OBJECT(menu), "gs", gs); showContextMenu(menu, event); } void StandardMenu::forInterface(GlobalState *gs, GdkEventButton *event, Interface interface) { auto menu = gtk_menu_new(); auto acceleratorGroup = gtk_accel_group_new(); gtk_menu_set_accel_group(GTK_MENU(menu), acceleratorGroup); bool editable = false, currentlyEditable = false, multiple = false, hasSelection = false, hasColor = false; IReadonlyColorUI *baseInterface; Appender appender(menu, acceleratorGroup, (baseInterface = boost::apply_visitor(InterfaceInspector(editable, currentlyEditable, multiple, hasSelection, hasColor), interface))); appender.appendItem(_("_Add to palette"), GTK_STOCK_ADD, GDK_KEY_A, GdkModifierType(0), G_CALLBACK(onEditableColorAdd), hasSelection); if (multiple) { appender.appendItem(_("A_dd all to palette"), GTK_STOCK_ADD, GDK_KEY_A, GdkModifierType(GDK_CONTROL_MASK), G_CALLBACK(onEditableColorAddAll), hasColor); } auto *menuExtension = dynamic_cast(baseInterface); if (menuExtension) menuExtension->extendMenu(menu, IMenuExtension::Position::middle); appender.appendSeparator(); StandardMenu::appendMenu(menu, baseInterface, gs); if (editable) { appender.appendSeparator(); appender.appendItem(_("_Edit..."), GTK_STOCK_EDIT, GDK_KEY_E, GdkModifierType(0), G_CALLBACK(onEditableColorEdit), hasSelection && currentlyEditable); appender.appendItem(_("_Paste"), GTK_STOCK_PASTE, GDK_KEY_V, GdkModifierType(GDK_CONTROL_MASK), G_CALLBACK(onEditableColorPaste), hasSelection && currentlyEditable && clipboard::colorObjectAvailable()); } if (menuExtension) menuExtension->extendMenu(menu, IMenuExtension::Position::end); if (editable) g_object_set_data(G_OBJECT(menu), "gs", gs); showContextMenu(menu, event); } gpick-gpick-0.2.6/source/StandardMenu.h000066400000000000000000000065441377073231300177640ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_STANDARD_MENU_H_ #define GPICK_STANDARD_MENU_H_ #include "IEditableColorUI.h" #include "IReadonlyColorUI.h" #include #include struct ColorObject; struct GlobalState; struct Color; struct Converter; struct StandardMenu { static void appendMenu(GtkWidget *menu, const ColorObject &colorObject, GlobalState *gs); static void appendMenu(GtkWidget *menu, const Color &color, GlobalState *gs); static void appendMenu(GtkWidget *menu, IReadonlyColorUI *interface, GlobalState *gs); static void appendMenu(GtkWidget *menu); static GtkWidget *newMenu(const ColorObject &colorObject, GlobalState *gs); static GtkWidget *newMenu(const ColorObject &colorObject, IReadonlyColorUI *interface, GlobalState *gs); static GtkWidget *newItem(const ColorObject &colorObject, GlobalState *gs, bool includeName); static GtkWidget *newItem(const ColorObject &colorObject, Converter *converter, GlobalState *gs); static GtkWidget *newItem(const ColorObject &colorObject, IReadonlyColorUI *interface, Converter *converter, GlobalState *gs); static GtkWidget *newNearestColorsMenu(const ColorObject &colorObject, GlobalState *gs); struct Appender { Appender(GtkWidget *menu, GtkAccelGroup *acceleratorGroup, void *data); GtkWidget *appendItem(const char *label, const char *icon, guint key, GdkModifierType modifiers, GCallback callback, bool enabled = true); GtkWidget *appendSeparator(); private: GtkWidget *menu; GtkAccelGroup *acceleratorGroup; void *data; }; using Interface = boost::variant; static void contextForColorObject(ColorObject *colorObject, GlobalState *gs, GdkEventButton *event, Interface interface); static void forInterface(GlobalState *gs, GdkEventButton *event, Interface interface); }; #endif /* GPICK_STANDARD_MENU_H_ */ gpick-gpick-0.2.6/source/StringUtils.cpp000066400000000000000000000051421377073231300202120ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "StringUtils.h" using namespace std; void split(const std::string &str, char separator, bool skip_empty, std::function function) { size_t start = 0; size_t separator_position = str.find(separator); if (separator_position == string::npos){ if (skip_empty && str.empty()) return; function(str); return; } do{ if (!skip_empty || separator_position - start > 0) function(str.substr(start, separator_position - start)); start = separator_position + 1; separator_position = str.find(separator, start); }while (separator_position != string::npos); if (start != str.length()){ function(str.substr(start, str.length() - start)); }else if (!skip_empty){ function(string()); } } void stripLeadingTrailingChars(std::string &str, const std::string &strip_chars) { if (str.empty()) return; if (strip_chars.empty()) return; size_t start = str.find_first_not_of(strip_chars); size_t end = str.find_last_not_of(strip_chars); if ((start == string::npos) || (end == string::npos)){ str.erase(); return; } str = str.substr(start, end - start + 1); } gpick-gpick-0.2.6/source/StringUtils.h000066400000000000000000000035441377073231300176630ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_STRING_UTILS_H_ #define GPICK_STRING_UTILS_H_ #include #include void split(const std::string &str, char separator, bool skip_empty, std::function function); void stripLeadingTrailingChars(std::string &str, const std::string &strip_chars); #endif /* GPICK_STRING_UTILS_H_ */ gpick-gpick-0.2.6/source/ToolColorNaming.cpp000066400000000000000000000064631377073231300210000ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ToolColorNaming.h" #include "GlobalState.h" #include "dynv/Map.h" #include "I18N.h" #include "color_names/ColorNames.h" #include "ColorObject.h" #include using namespace std; const ToolColorNamingOption options[] = { {TOOL_COLOR_NAMING_EMPTY, "empty", N_("_Empty")}, {TOOL_COLOR_NAMING_AUTOMATIC_NAME, "automatic_name", N_("_Automatic name")}, {TOOL_COLOR_NAMING_TOOL_SPECIFIC, "tool_specific", N_("_Tool specific")}, {TOOL_COLOR_NAMING_UNKNOWN, 0, 0}, }; const ToolColorNamingOption* tool_color_naming_get_options() { return options; } ToolColorNamingType tool_color_naming_name_to_type(const std::string &name) { string n = name; int i = 0; while (options[i].name){ if (n.compare(options[i].name) == 0){ return options[i].type; } i++; } return TOOL_COLOR_NAMING_UNKNOWN; } ToolColorNameAssigner::ToolColorNameAssigner(GlobalState *gs): m_gs(gs) { m_color_naming_type = tool_color_naming_name_to_type(m_gs->settings().getString("gpick.color_names.tool_color_naming", "automatic_name")); if (m_color_naming_type == TOOL_COLOR_NAMING_AUTOMATIC_NAME){ m_imprecision_postfix = m_gs->settings().getBool("gpick.color_names.imprecision_postfix", false); }else{ m_imprecision_postfix = false; } } ToolColorNameAssigner::~ToolColorNameAssigner() { } void ToolColorNameAssigner::assign(ColorObject *color_object, const Color *color) { string name; switch (m_color_naming_type){ case TOOL_COLOR_NAMING_UNKNOWN: case TOOL_COLOR_NAMING_EMPTY: color_object->setName(""); break; case TOOL_COLOR_NAMING_AUTOMATIC_NAME: name = color_names_get(m_gs->getColorNames(), color, m_imprecision_postfix); color_object->setName(name); break; case TOOL_COLOR_NAMING_TOOL_SPECIFIC: name = getToolSpecificName(color_object, color); color_object->setName(name); break; } } gpick-gpick-0.2.6/source/ToolColorNaming.h000066400000000000000000000047611377073231300204440ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_TOOL_COLOR_NAMING_H_ #define GPICK_TOOL_COLOR_NAMING_H_ #include struct GlobalState; struct Color; struct ColorObject; enum ToolColorNamingType { TOOL_COLOR_NAMING_UNKNOWN = 0, TOOL_COLOR_NAMING_EMPTY, TOOL_COLOR_NAMING_AUTOMATIC_NAME, TOOL_COLOR_NAMING_TOOL_SPECIFIC, }; typedef struct ToolColorNamingOption{ ToolColorNamingType type; const char *name; const char *label; }ToolColorNamingOption; const ToolColorNamingOption* tool_color_naming_get_options(); ToolColorNamingType tool_color_naming_name_to_type(const std::string &name); struct ToolColorNameAssigner { protected: ToolColorNamingType m_color_naming_type; GlobalState* m_gs; bool m_imprecision_postfix; public: ToolColorNameAssigner(GlobalState *gs); virtual ~ToolColorNameAssigner(); void assign(ColorObject *color_object, const Color *color); virtual std::string getToolSpecificName(ColorObject *color_object, const Color *color) = 0; }; #endif /* GPICK_TOOL_COLOR_NAMING_H_ */ gpick-gpick-0.2.6/source/Variations.cpp000066400000000000000000000456501377073231300200520ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Variations.h" #include "ColorObject.h" #include "ColorSource.h" #include "ColorSourceManager.h" #include "DragDrop.h" #include "GlobalState.h" #include "ToolColorNaming.h" #include "uiUtilities.h" #include "ColorList.h" #include "gtk/ColorWidget.h" #include "Converter.h" #include "dynv/Map.h" #include "I18N.h" #include "color_names/ColorNames.h" #include "StandardEventHandler.h" #include "IMenuExtension.h" #include "common/Format.h" #include #include const int Rows = 5; const int VariantWidgets = 8; enum class Component { hslHue = 1, hslSaturation, hslLightness, labLightness, rgbRed, rgbGreen, rgbBlue, }; struct Type { const char *id; const char *name; const char *symbol; Component component; float strengthMultiplier; }; const Type types[] = { { "rgb_red", N_("Red"), "RRGB", Component::rgbRed, 1 }, { "rgb_green", N_("Green"), "GRGB", Component::rgbGreen, 1 }, { "rgb_blue", N_("Blue"), "BRGB", Component::rgbBlue, 1 }, { "hsl_hue", N_("Hue"), "HHSL", Component::hslHue, 1 }, { "hsl_saturation", N_("Saturation"), "SHSL", Component::hslSaturation, 1 }, { "hsl_lightness", N_("Lightness"), "LHSL", Component::hslLightness, 1 }, { "lab_lightness", N_("Lightness (Lab)"), "LLab", Component::labLightness, 1 }, }; struct VariationsColorNameAssigner: public ToolColorNameAssigner { VariationsColorNameAssigner(GlobalState *gs): ToolColorNameAssigner(gs) { } void assign(ColorObject *colorObject, const Color *color, const std::string &ident) { m_ident = ident.c_str(); ToolColorNameAssigner::assign(colorObject, color); } virtual std::string getToolSpecificName(ColorObject *colorObject, const Color *color) { m_stream.str(""); m_stream << color_names_get(m_gs->getColorNames(), color, false) << " " << _("variations") << " " << m_ident; return m_stream.str(); } protected: std::stringstream m_stream; const char *m_ident; }; struct VariationsArgs { ColorSource source; GtkWidget *main, *statusBar, *strengthRange, *lastFocusedColor, *colorPreviews, *allColors; struct { GtkWidget *primary; GtkWidget *variants[VariantWidgets]; const Type *type; } rows[Rows]; dynv::Ref options; GlobalState *gs; void addToPalette() { color_list_add_color_object(gs->getColorList(), getColor(), true); } void addToPalette(VariationsColorNameAssigner &nameAssigner, Color &color, GtkWidget *widget) { gtk_color_get_color(GTK_COLOR(widget), &color); colorObject.setColor(color); nameAssigner.assign(&colorObject, &color, identifyColorWidget(widget)); color_list_add_color_object(gs->getColorList(), colorObject, true); } void addAllToPalette() { VariationsColorNameAssigner nameAssigner(gs); Color color; addToPalette(nameAssigner, color, allColors); for (int i = 0; i < Rows; ++i) { for (int j = 0; j < VariantWidgets; ++j) { if (j == VariantWidgets / 2) addToPalette(nameAssigner, color, rows[i].primary); addToPalette(nameAssigner, color, rows[i].variants[j]); } } } void setColor(const ColorObject &colorObject) { gtk_color_set_color(GTK_COLOR(lastFocusedColor), colorObject.getColor()); if (lastFocusedColor == allColors) { for (int i = 0; i < Rows; ++i) { gtk_color_set_color(GTK_COLOR(rows[i].primary), colorObject.getColor()); } } update(); } ColorObject colorObject; const ColorObject &getColor() { Color color; gtk_color_get_color(GTK_COLOR(lastFocusedColor), &color); colorObject.setColor(color); VariationsColorNameAssigner nameAssigner(gs); nameAssigner.assign(&colorObject, &color, identifyColorWidget(lastFocusedColor)); return colorObject; } std::string identifyColorWidget(GtkWidget *widget) { if (allColors == widget) { return _("all colors"); } else for (int i = 0; i < Rows; ++i) { if (rows[i].primary == widget) { return common::format(_("primary {}"), i + 1); } for (int j = 0; j < VariantWidgets; ++j) { if (rows[i].variants[j] == widget) { return common::format(_("result {} line {}"), j + 1, i + 1); } } } return "unknown"; } bool isEditable() { if (lastFocusedColor == allColors) return true; for (int i = 0; i < Rows; ++i) if (lastFocusedColor == rows[i].primary) return true; return false; } bool isPrimary() { for (int i = 0; i < Rows; ++i) { if (rows[i].primary == lastFocusedColor) return true; } return false; } static gboolean onFocusEvent(GtkWidget *widget, GdkEventFocus *, VariationsArgs *args) { args->setActiveWidget(widget); return false; } void setActiveWidget(GtkWidget *widget) { lastFocusedColor = widget; } int getActiveRow() { for (int i = 0; i < Rows; ++i) { if (rows[i].primary == lastFocusedColor) return i; for (int j = 0; j < VariantWidgets; ++j) { if (rows[i].variants[j] == lastFocusedColor) return i; } } return 0; } static void onModeChange(GtkWidget *widget, VariationsArgs *args) { if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) return; auto type = static_cast(g_object_get_data(G_OBJECT(widget), "variation_type")); args->rows[args->getActiveRow()].type = type; gtk_color_set_text(GTK_COLOR(args->rows[args->getActiveRow()].primary), type->symbol); args->update(); } static void onColorActivate(GtkWidget *, VariationsArgs *args) { args->addToPalette(); } static void onChange(GtkWidget *, VariationsArgs *args) { args->update(); } void update(bool saveSettings = false) { float strength = static_cast(gtk_range_get_value(GTK_RANGE(strengthRange))); if (saveSettings) { options->set("strength", strength); } Color color, rgb, hsl, lab, r, rgbModified, hslModified, labModified; for (int i = 0; i < Rows; ++i) { gtk_color_get_color(GTK_COLOR(rows[i].primary), &color); switch (rows[i].type->component) { case Component::rgbRed: case Component::rgbGreen: case Component::rgbBlue: color_rgb_get_linear(&color, &rgb); break; case Component::hslHue: case Component::hslSaturation: case Component::hslLightness: color_rgb_to_hsl(&color, &hsl); break; case Component::labLightness: color_rgb_to_lab_d50(&color, &lab); break; } for (int j = 0; j < VariantWidgets; ++j) { float position = rows[i].type->strengthMultiplier * strength * (j / static_cast(VariantWidgets - 1) - 0.5f); switch (rows[i].type->component) { case Component::rgbRed: rgbModified = rgb; rgbModified.rgb.red = clamp_float(rgbModified.rgb.red + position / 100.0f, 0, 1); color_linear_get_rgb(&rgbModified, &r); break; case Component::rgbGreen: rgbModified = rgb; rgbModified.rgb.green = clamp_float(rgbModified.rgb.green + position / 100.0f, 0, 1); color_linear_get_rgb(&rgbModified, &r); break; case Component::rgbBlue: rgbModified = rgb; rgbModified.rgb.blue = clamp_float(rgbModified.rgb.blue + position / 100.0f, 0, 1); color_linear_get_rgb(&rgbModified, &r); break; case Component::hslHue: color_copy(&hsl, &hslModified); hslModified.hsl.hue = wrap_float(hsl.hsl.hue + position / 100.0f); color_hsl_to_rgb(&hslModified, &r); break; case Component::hslSaturation: color_copy(&hsl, &hslModified); hslModified.hsl.saturation = clamp_float(hsl.hsl.saturation + position / 100.0f, 0, 1); color_hsl_to_rgb(&hslModified, &r); break; case Component::hslLightness: color_copy(&hsl, &hslModified); hslModified.hsl.lightness = clamp_float(hsl.hsl.lightness + position / 100.0f, 0, 1); color_hsl_to_rgb(&hslModified, &r); break; case Component::labLightness: color_copy(&lab, &labModified); labModified.lab.L = clamp_float(lab.lab.L + position, 0, 100); color_lab_to_rgb_d50(&labModified, &r); color_rgb_normalize(&r); break; } gtk_color_set_color(GTK_COLOR(rows[i].variants[j]), r); } } } struct Editable: IEditableColorsUI, IMenuExtension { Editable(VariationsArgs *args): args(args) { } virtual ~Editable() = default; virtual void addToPalette(const ColorObject &) override { args->addToPalette(); } virtual void addAllToPalette() override { args->addAllToPalette(); } virtual void setColor(const ColorObject &colorObject) override { args->setColor(colorObject.getColor()); } virtual const ColorObject &getColor() override { return args->getColor(); } virtual std::vector getColors(bool selected) override { std::vector colors; colors.push_back(getColor()); return colors; } virtual bool isEditable() override { return args->isEditable(); } virtual bool hasColor() override { return true; } virtual bool hasSelectedColor() override { return true; } virtual void extendMenu(GtkWidget *menu, Position position) { if (position != Position::end || !isEditable() || !args->isPrimary()) return; gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); GSList *group = nullptr; int row = args->getActiveRow(); gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); for (size_t i = 0; i < sizeof(types) / sizeof(Type); i++) { auto item = gtk_radio_menu_item_new_with_label(group, _(types[i].name)); group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item)); if (args->rows[row].type == &types[i]) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), true); g_object_set_data(G_OBJECT(item), "variation_type", const_cast(&types[i])); g_signal_connect(G_OBJECT(item), "toggled", G_CALLBACK(VariationsArgs::onModeChange), args); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); } } private: VariationsArgs *args; }; boost::optional editable; }; static int destroy(VariationsArgs *args) { Color color; char tmp[32]; for (int i = 0; i < Rows; ++i) { sprintf(tmp, "type%d", i); args->options->set(tmp, args->rows[i].type->id); sprintf(tmp, "color%d", i); gtk_color_get_color(GTK_COLOR(args->rows[i].primary), &color); args->options->set(tmp, color); } gtk_color_get_color(GTK_COLOR(args->allColors), &color); args->options->set("all_colors", color); gtk_widget_destroy(args->main); delete args; return 0; } static int getColor(VariationsArgs *args, ColorObject **color) { auto colorObject = args->getColor(); *color = colorObject.copy(); return 0; } static int setColor(VariationsArgs *args, ColorObject *colorObject) { args->setColor(*colorObject); return 0; } static int activate(VariationsArgs *args) { auto chain = args->gs->getTransformationChain(); gtk_color_set_transformation_chain(GTK_COLOR(args->allColors), chain); for (int i = 0; i < Rows; ++i) { gtk_color_set_transformation_chain(GTK_COLOR(args->rows[i].primary), chain); for (int j = 0; j < VariantWidgets; ++j) { gtk_color_set_transformation_chain(GTK_COLOR(args->rows[i].variants[j]), chain); } } gtk_statusbar_push(GTK_STATUSBAR(args->statusBar), gtk_statusbar_get_context_id(GTK_STATUSBAR(args->statusBar), "empty"), ""); return 0; } static int deactivate(VariationsArgs *args) { args->update(true); return 0; } static ColorObject *getColorObject(struct DragDrop *dd) { auto *args = static_cast(dd->userdata); return args->getColor().copy(); } static int setColorObjectAt(struct DragDrop *dd, ColorObject *colorObject, int x, int y, bool, bool) { auto *args = static_cast(dd->userdata); args->setActiveWidget(dd->widget); args->setColor(*colorObject); return 0; } static ColorSource *source_implement(ColorSource *source, GlobalState *gs, const dynv::Ref &options) { auto *args = new VariationsArgs; args->editable = VariationsArgs::Editable(args); args->options = options; args->statusBar = gs->getStatusBar(); args->gs = gs; color_source_init(&args->source, source->identificator, source->hr_name); args->source.destroy = (int (*)(ColorSource *))destroy; args->source.get_color = (int (*)(ColorSource *, ColorObject **))getColor; args->source.set_color = (int (*)(ColorSource *, ColorObject *))setColor; args->source.deactivate = (int (*)(ColorSource *))deactivate; args->source.activate = (int (*)(ColorSource * source)) activate; GtkWidget *table, *vbox, *hbox, *widget, *hbox2; hbox = gtk_hbox_new(false, 0); vbox = gtk_vbox_new(false, 0); gtk_box_pack_start(GTK_BOX(hbox), vbox, true, true, 5); args->colorPreviews = gtk_table_new(Rows, VariantWidgets + 1, false); gtk_box_pack_start(GTK_BOX(vbox), args->colorPreviews, true, true, 0); struct DragDrop dd; dragdrop_init(&dd, gs); dd.converterType = Converters::Type::display; dd.userdata = args; dd.get_color_object = getColorObject; dd.set_color_object_at = setColorObjectAt; widget = gtk_color_new(); gtk_color_set_rounded(GTK_COLOR(widget), true); gtk_color_set_hcenter(GTK_COLOR(widget), true); gtk_color_set_roundness(GTK_COLOR(widget), 5); gtk_table_attach(GTK_TABLE(args->colorPreviews), widget, VariantWidgets / 2, VariantWidgets / 2 + 1, 0, 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 0, 0); args->allColors = widget; g_signal_connect(G_OBJECT(widget), "activated", G_CALLBACK(VariationsArgs::onColorActivate), args); g_signal_connect(G_OBJECT(widget), "focus-in-event", G_CALLBACK(VariationsArgs::onFocusEvent), args); StandardEventHandler::forWidget(widget, args->gs, &*args->editable); //setup drag&drop gtk_widget_set_size_request(widget, 60, 30); gtk_drag_dest_set(widget, GtkDestDefaults(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT), 0, 0, GDK_ACTION_COPY); gtk_drag_source_set(widget, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY); dragdrop_widget_attach(widget, DragDropFlags(DRAGDROP_SOURCE | DRAGDROP_DESTINATION), &dd); for (int i = 0; i < Rows; ++i) { args->rows[i].type = &types[i]; args->rows[i].primary = widget = gtk_color_new(); gtk_color_set_rounded(GTK_COLOR(widget), true); gtk_color_set_hcenter(GTK_COLOR(widget), true); gtk_color_set_roundness(GTK_COLOR(widget), 5); gtk_table_attach(GTK_TABLE(args->colorPreviews), widget, VariantWidgets / 2, VariantWidgets / 2 + 1, i + 1, i + 2, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL | GTK_EXPAND), 0, 0); g_signal_connect(G_OBJECT(widget), "activated", G_CALLBACK(VariationsArgs::onColorActivate), args); g_signal_connect(G_OBJECT(widget), "focus-in-event", G_CALLBACK(VariationsArgs::onFocusEvent), args); StandardEventHandler::forWidget(widget, args->gs, &*args->editable); gtk_widget_set_size_request(widget, 60, 30); gtk_drag_dest_set(widget, GtkDestDefaults(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT), 0, 0, GDK_ACTION_COPY); gtk_drag_source_set(widget, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY); dragdrop_widget_attach(widget, DragDropFlags(DRAGDROP_SOURCE | DRAGDROP_DESTINATION), &dd); for (int j = 0; j < VariantWidgets; ++j) { int x = j + (j >= VariantWidgets / 2 ? 1 : 0); args->rows[i].variants[j] = widget = gtk_color_new(); gtk_color_set_rounded(GTK_COLOR(widget), true); gtk_color_set_hcenter(GTK_COLOR(widget), true); gtk_color_set_roundness(GTK_COLOR(widget), 5); gtk_table_attach(GTK_TABLE(args->colorPreviews), widget, x, x + 1, i + 1, i + 2, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL | GTK_EXPAND), 0, 0); g_signal_connect(G_OBJECT(widget), "activated", G_CALLBACK(VariationsArgs::onColorActivate), args); g_signal_connect(G_OBJECT(widget), "focus-in-event", G_CALLBACK(VariationsArgs::onFocusEvent), args); StandardEventHandler::forWidget(widget, args->gs, &*args->editable); gtk_widget_set_size_request(widget, 30, 30); gtk_drag_source_set(widget, GDK_BUTTON1_MASK, 0, 0, GDK_ACTION_COPY); dragdrop_widget_attach(widget, DragDropFlags(DRAGDROP_SOURCE), &dd); } } char tmp[32]; for (int i = 0; i < Rows; ++i) { sprintf(tmp, "type%d", i); auto typeName = options->getString(tmp, "lab_lightness"); for (uint32_t j = 0; j < sizeof(types) / sizeof(Type); j++) { if (types[j].id == typeName) { args->rows[i].type = &types[j]; break; } } sprintf(tmp, "color%d", i); gtk_color_set_color(GTK_COLOR(args->rows[i].primary), options->getColor(tmp, Color(0.5f)), args->rows[i].type->symbol); } gtk_color_set_color(GTK_COLOR(args->allColors), options->getColor("all_colors", Color(0.5f))); hbox2 = gtk_hbox_new(false, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox2, false, false, 0); gint table_y; table = gtk_table_new(5, 2, false); gtk_box_pack_start(GTK_BOX(hbox2), table, true, true, 0); table_y = 0; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Strength:"), 0, 0.5, 0, 0), 0, 1, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 0, 0); args->strengthRange = widget = gtk_hscale_new_with_range(1, 100, 1); gtk_range_set_value(GTK_RANGE(widget), options->getFloat("strength", 30)); g_signal_connect(G_OBJECT(widget), "value-changed", G_CALLBACK(VariationsArgs::onChange), args); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 0, 0); table_y++; gtk_widget_show_all(hbox); args->update(); args->main = hbox; args->source.widget = hbox; return (ColorSource *)args; } int variations_source_register(ColorSourceManager *csm) { ColorSource *color_source = new ColorSource; color_source_init(color_source, "variations", _("Variations")); color_source->implement = source_implement; color_source->default_accelerator = GDK_KEY_v; color_source_manager_add_source(csm, color_source); return 0; } gpick-gpick-0.2.6/source/Variations.h000066400000000000000000000032771377073231300175160ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_VARIATIONS_H_ #define GPICK_VARIATIONS_H_ struct ColorSourceManager; int variations_source_register(ColorSourceManager *csm); #endif /* GPICK_VARIATIONS_H_ */ gpick-gpick-0.2.6/source/Vector2.h000066400000000000000000000053521377073231300167170ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_VECTOR2_H_ #define GPICK_VECTOR2_H_ #include namespace math { /** \struct Vec2 * \brief Two dimensional vector */ template struct Vec2 { public: Vec2() { x = y = 0; }; Vec2(const T &x_, const T &y_) { x = x_; y = y_; }; Vec2(T &x_, T &y_) { x = x_; y = y_; }; Vec2 &operator=(const Vec2 &v) { x = v.x; y = v.y; return *this; }; Vec2 operator*(const Vec2 &v) { Vec2 r; r.x = x * v.x; r.y = y * v.y; return r; }; Vec2 operator*(const double &v) { Vec2 r; r.x = x * v; r.y = y * v; return r; }; Vec2 operator+(const Vec2 &v) { Vec2 r; r.x = x + v.x; r.y = y + v.y; return r; }; Vec2 operator-(const Vec2 &v) { Vec2 r; r.x = x - v.x; r.y = y - v.y; return r; }; const Vec2 operator-() const { Vec2 r; r.x = -x; r.y = -y; return r; }; friend bool operator!=(const Vec2 &lhs, const Vec2 &rhs) { if (lhs.x != rhs.x) return false; if (lhs.y != rhs.y) return false; return true; }; static T distance(const Vec2&a, const Vec2 &b) { return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); }; T x; T y; }; } #endif /* GPICK_VECTOR2_H_ */ gpick-gpick-0.2.6/source/color_names/000077500000000000000000000000001377073231300175165ustar00rootroot00000000000000gpick-gpick-0.2.6/source/color_names/ColorNames.cpp000066400000000000000000000227121377073231300222700ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ColorNames.h" #include "Color.h" #include "Paths.h" #include "dynv/Map.h" #include #include #include #include #include #include #include using namespace std; struct ColorNameEntry { std::string name; }; struct ColorEntry { Color color; Color original_color; ColorNameEntry* name; }; const int SpaceDivisions = 8; struct ColorNames { std::list names; std::vector colors[SpaceDivisions][SpaceDivisions][SpaceDivisions]; void (*color_space_convert)(const Color* a, Color* b); float (*color_space_distance)(const Color* a, const Color* b); }; ColorNames* color_names_new() { ColorNames* color_names = new ColorNames; color_names->color_space_convert = color_rgb_to_lab_d50; color_names->color_space_distance = color_distance_lch; return color_names; } void color_names_clear(ColorNames *color_names) { for (auto i = color_names->names.begin(); i != color_names->names.end(); i++){ delete *i; } color_names->names.clear(); for (int x = 0; x < SpaceDivisions; x++){ for (int y = 0; y < SpaceDivisions; y++){ for (int z = 0; z < SpaceDivisions; z++){ for (auto i = color_names->colors[x][y][z].begin(); i != color_names->colors[x][y][z].end(); ++i){ delete *i; } color_names->colors[x][y][z].clear(); } } } } static void color_names_strip_spaces(string& string_x, const string& strip_chars) { if (string_x.empty()) return; if (strip_chars.empty()) return; size_t start_index = string_x.find_first_not_of(strip_chars); size_t end_index = string_x.find_last_not_of(strip_chars); if ((start_index == string::npos) || (end_index == string::npos)){ string_x.erase(); return; } string_x = string_x.substr(start_index, (end_index - start_index) + 1); } void color_names_normalize(const Color &color, Color &out) { out.xyz.x = color.xyz.x / 100.0f; out.xyz.y = (color.xyz.y + 86.1825f) / (86.1825f + 98.2346f); out.xyz.z = (color.xyz.z + 107.86f) / (107.86f + 94.478f); } void color_names_get_color_xyz(ColorNames* color_names, Color* c, int* x1, int* y1, int* z1, int* x2, int* y2, int* z2) { *x1 = clamp_int(int(c->xyz.x / 100 * SpaceDivisions - 0.5), 0, SpaceDivisions - 1); *y1 = clamp_int(int((c->xyz.y + 100) / 200 * SpaceDivisions - 0.5), 0, SpaceDivisions - 1); *z1 = clamp_int(int((c->xyz.z + 100) / 200 * SpaceDivisions - 0.5), 0, SpaceDivisions - 1); *x2 = clamp_int(int(c->xyz.x / 100 * SpaceDivisions + 0.5), 0, SpaceDivisions - 1); *y2 = clamp_int(int((c->xyz.y + 100) / 200 * SpaceDivisions + 0.5), 0, SpaceDivisions - 1); *z2 = clamp_int(int((c->xyz.z + 100) / 200 * SpaceDivisions + 0.5), 0, SpaceDivisions - 1); } static vector* color_names_get_color_list(ColorNames* color_names, Color* c) { int x,y,z; x = clamp_int(int(c->xyz.x / 100 * SpaceDivisions), 0, SpaceDivisions - 1); y = clamp_int(int((c->xyz.y + 100) / 200 * SpaceDivisions), 0, SpaceDivisions - 1); z = clamp_int(int((c->xyz.z + 100) / 200 * SpaceDivisions), 0, SpaceDivisions - 1); return &color_names->colors[x][y][z]; } int color_names_load_from_file(ColorNames* color_names, const std::string &filename) { ifstream file(filename.c_str(), ifstream::in); if (file.is_open()){ string line; stringstream rline (ios::in | ios::out); Color color; string name; while (!(file.eof())){ getline(file, line); if (line.empty()) continue; if (line.at(0) == '!') continue; rline.clear(); rline.str(line); rline >> color.rgb.red >> color.rgb.green >> color.rgb.blue; getline(rline, name); const string strip_chars = " \t,.\n\r"; color_names_strip_spaces(name, strip_chars); string::iterator i(name.begin()); if (i != name.end()){ name[0] = toupper((unsigned char)name[0]); while(++i != name.end()){ *i = tolower((unsigned char)*i); } color_multiply(&color, 1 / 255.0f); ColorNameEntry* name_entry = new ColorNameEntry; name_entry->name = name; color_names->names.push_back(name_entry); ColorEntry* color_entry = new ColorEntry; color_entry->name = name_entry; color_names->color_space_convert(&color, &color_entry->color); color_copy(&color, &color_entry->original_color); color_names_get_color_list(color_names, &color_entry->color)->push_back(color_entry); } } file.close(); return 0; } return -1; } void color_names_destroy(ColorNames* color_names) { color_names_clear(color_names); delete color_names; } static void color_names_iterate(ColorNames* color_names, const Color* color, function on_color, function on_expansion) { Color c1; color_names->color_space_convert(color, &c1); int x1, y1, z1, x2, y2, z2; color_names_get_color_xyz(color_names, &c1, &x1, &y1, &z1, &x2, &y2, &z2); char skip_mask[SpaceDivisions][SpaceDivisions][SpaceDivisions]; memset(&skip_mask, 0, sizeof(skip_mask)); /* Search expansion should be from 0 to SpaceDivisions, but this would only increase search time and return * wrong color names when no closely matching color is found. Search expansion is only useful * when color name database is very small (16 colors) */ for (int expansion = 0; expansion < SpaceDivisions - 1; ++expansion){ int x_start = std::max(x1 - expansion, 0), x_end = std::min(x2 + expansion, SpaceDivisions - 1); int y_start = std::max(y1 - expansion, 0), y_end = std::min(y2 + expansion, SpaceDivisions - 1); int z_start = std::max(z1 - expansion, 0), z_end = std::min(z2 + expansion, SpaceDivisions - 1); for (int x_i = x_start; x_i <= x_end; ++x_i){ for (int y_i = y_start; y_i <= y_end; ++y_i){ for (int z_i = z_start; z_i <= z_end; ++z_i){ if (skip_mask[x_i][y_i][z_i]) continue; // skip checked items skip_mask[x_i][y_i][z_i] = 1; for (auto i = color_names->colors[x_i][y_i][z_i].begin(); i != color_names->colors[x_i][y_i][z_i].end(); ++i){ float delta = color_names->color_space_distance(&(*i)->color, &c1); if (!on_color(*i, delta)) return; } } } } if (on_expansion && !on_expansion()) return; } } string color_names_get(ColorNames* color_names, const Color* color, bool imprecision_postfix) { float result_delta = 1e5; ColorEntry* found_color_entry = nullptr; color_names_iterate(color_names, color, [&](ColorEntry *color_entry, float delta){ if (delta < result_delta){ result_delta = delta; found_color_entry = color_entry; } return true; }, [&](){ return found_color_entry == nullptr; // stop further expansion if we have found a match }); if (found_color_entry){ stringstream s; s << found_color_entry->name->name; if (imprecision_postfix) if (result_delta > 0.1) s << " ~"; return s.str(); } return string(""); } void color_names_load(ColorNames *color_names, const dynv::Map ¶ms) { if (!params.contains("color_dictionaries.items")) { color_names_load_from_file(color_names, buildFilename("color_dictionary_0.txt")); return; } const auto items = params.getMaps("color_dictionaries.items"); for (const auto &item: items) { if (!item->getBool("enable", false)) continue; auto builtIn = item->getBool("built_in", false); auto path = item->getString("path", ""); if (builtIn) { if (path == "built_in_0") { color_names_load_from_file(color_names, buildFilename("color_dictionary_0.txt")); } } else { color_names_load_from_file(color_names, path.c_str()); } } } void color_names_find_nearest(ColorNames *color_names, const Color &color, size_t count, std::vector> &colors) { multimap found_colors; color_names_iterate(color_names, &color, [&](ColorEntry *color_entry, float delta){ found_colors.insert(pair(delta, color_entry)); return true; }, [&](){ return found_colors.size() < count; }); if (found_colors.size() >= count) colors.resize(count); else colors.resize(found_colors.size()); size_t index = 0; for (auto &item: found_colors){ if (index >= count) break; colors[index++] = pair(item.second->name->name.c_str(), item.second->original_color); } } gpick-gpick-0.2.6/source/color_names/ColorNames.h000066400000000000000000000044071377073231300217360ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_COLOR_NAMES_COLOR_NAMES_H_ #define GPICK_COLOR_NAMES_COLOR_NAMES_H_ #include "Color.h" #include "dynv/MapFwd.h" #include #include struct ColorNames; ColorNames *color_names_new(); void color_names_clear(ColorNames *color_names); void color_names_load(ColorNames *color_names, const dynv::Map ¶ms); int color_names_load_from_file(ColorNames *color_names, const std::string &filename); void color_names_destroy(ColorNames *color_names); std::string color_names_get(ColorNames *color_names, const Color *color, bool imprecision_postfix); void color_names_find_nearest(ColorNames *color_names, const Color &color, size_t count, std::vector> &colors); #endif /* GPICK_COLOR_NAMES_COLOR_NAMES_H_ */ gpick-gpick-0.2.6/source/common/000077500000000000000000000000001377073231300165055ustar00rootroot00000000000000gpick-gpick-0.2.6/source/common/CastToVariant.h000066400000000000000000000044711377073231300214060ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_COMMON_CAST_TO_VARIANT_H_ #define GPICK_COMMON_CAST_TO_VARIANT_H_ #include namespace common { template TResult castToVariantInternal(TValue value) { return TResult(value); } template TResult castToVariantInternal(TValue value) { auto result = dynamic_cast(value); if (result) return TResult(result); else return castToVariantInternal(value); } template boost::variant castToVariant(TValue value) { return castToVariantInternal, TValue, Cast1, CastN...>(value); } } #endif /* GPICK_COMMON_CAST_TO_VARIANT_H_ */ gpick-gpick-0.2.6/source/common/Format.cpp000066400000000000000000000035051377073231300204440ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Format.h" namespace common { template<> std::string as_string(const std::string &value) { return value; } template<> std::string as_string(const char *value) { return value; } template<> std::string as_string(int value) { return std::to_string(value); } } gpick-gpick-0.2.6/source/common/Format.h000066400000000000000000000055341377073231300201150ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_COMMON_FORMAT_H_ #define GPICK_COMMON_FORMAT_H_ #include #include namespace common { template std::string as_string(T value) { return std::to_string(value); } template<> std::string as_string(const std::string &value); template<> std::string as_string(const char *value); template<> std::string as_string(int value); template std::string format(const char *format, const Args &... args) { std::vector values = { as_string(args)... }; size_t max_length = 0; for (auto &v: values) { max_length += v.length(); } char previous_char = 0; size_t i; for (i = 0; format[i]; ++i) { if (format[i] == '}' && previous_char == '{') { max_length -= 2; } previous_char = format[i]; } max_length += i; std::string result; result.reserve(max_length); previous_char = 0; size_t argument_index = 0; for (i = 0; format[i]; ++i) { if (format[i] == '}' && previous_char == '{') { result.pop_back(); if (argument_index < values.size()) { auto &value = values[argument_index]; for (size_t j = 0; j < value.length(); ++j) { result.push_back(value[j]); } } argument_index++; } else { result.push_back(format[i]); } previous_char = format[i]; } return result; } } #endif /* GPICK_COMMON_FORMAT_H_ */ gpick-gpick-0.2.6/source/common/Ref.h000066400000000000000000000064161377073231300174010ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_COMMON_REF_H_ #define GPICK_COMMON_REF_H_ #include #include namespace common { template struct Ref { struct Counter { Counter(): m_referenceCounter(1) { } virtual ~Counter() { if (m_referenceCounter > 1) { std::cerr << "Referenced value destroyed [address: " << this << ", reference count: " << m_referenceCounter << "]\n"; } } T *reference() { m_referenceCounter++; return reinterpret_cast(this); } bool release() { if (m_referenceCounter > 1) { m_referenceCounter--; return false; } else { delete this; return true; } } uint32_t references() const { return m_referenceCounter; } private: uint32_t m_referenceCounter; }; Ref(): m_value(nullptr) { } Ref(T *value): m_value(value) { } Ref(const Ref &reference): m_value(reference.m_value->reference()) { } Ref(Ref &&reference): m_value(reference.m_value) { reference.m_value = nullptr; } Ref &operator=(const Ref &reference) { if (m_value) m_value->release(); m_value = reference.m_value->reference(); return *this; } ~Ref() { if (m_value) m_value->release(); } bool release() { bool result = true; if (m_value) result = m_value->release(); m_value = nullptr; return result; } explicit operator bool() const { return m_value != nullptr; } bool operator==(const Ref &reference) const { return m_value == reference.m_value; } T &operator*() { return *m_value; } const T &operator*() const { return *m_value; } T *operator->() { return m_value; } const T *operator->() const { return m_value; } uint32_t references() const { return m_value ? m_value->references() : 0; } private: T *m_value; }; } #endif /* GPICK_COMMON_REF_H_ */ gpick-gpick-0.2.6/source/common/Result.h000066400000000000000000000117261377073231300201430ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_COMMON_RESULT_H_ #define GPICK_COMMON_RESULT_H_ #include namespace common { template struct Result { Result(): m_status(false) { } Result(const ErrorT &error): m_error(error), m_status(false) { } Result(const ValueT &value): m_value(value), m_status(true) { } Result(ErrorT &&error): m_error(std::move(error)), m_status(false) { } Result(ValueT &&value): m_value(std::move(value)), m_status(true) { } Result(const Result &) = delete; Result(Result &&result): m_value(std::move(result.m_value)), m_error(std::move(result.m_error)), m_status(result.m_status) { } Result &operator=(const Result &) = delete; Result &operator=(Result &&result) { m_status = result.m_status; m_value = std::move(result.m_value); m_error = std::move(result.m_error); return *this; } ~Result() { } operator bool() const { return m_status; } const ValueT &value() const { return m_value; } ValueT &value() { return m_value; } const ErrorT &error() const { return m_error; } ErrorT &error() { return m_error; } private: ValueT m_value; ErrorT m_error; bool m_status; }; template struct Result { Result(): m_status(false) { } Result(bool status, const BothT &value): m_value(value), m_status(status) { } Result(bool status, BothT &&value): m_value(std::move(value)), m_status(status) { } Result(const Result &) = delete; Result(Result &&result): m_value(std::move(result.m_value)), m_status(result.m_status) { } Result &operator=(const Result &) = delete; Result &operator=(Result &&result) { m_value = std::move(result.m_value); return *this; } ~Result() { } operator bool() const { return m_status; } const BothT &value() const { return m_value; } BothT &value() { return m_value; } const BothT &error() const { return m_value; } BothT &error() { return m_value; } private: BothT m_value; bool m_status; }; template struct Result { Result(): m_status(true) { } Result(const ErrorT &error): m_error(error), m_status(false) { } Result(ErrorT &&error): m_error(std::move(error)), m_status(false) { } Result(const Result &) = delete; Result(Result &&result): m_error(std::move(result.m_error)), m_status(result.m_status) { } Result &operator=(const Result &) = delete; Result &operator=(Result &&result) { m_error = std::move(result.m_error); return *this; } ~Result() { } operator bool() const { return m_status; } const ErrorT &error() const { return m_error; } ErrorT &error() { return m_error; } private: ErrorT m_error; bool m_status; }; template struct Result { Result(): m_status(false) { } Result(const ValueT &value): m_value(value), m_status(true) { } Result(ValueT &&value): m_value(std::move(value)), m_status(true) { } Result(const Result &) = delete; Result(Result &&result): m_value(std::move(result.m_value)), m_status(result.m_status) { } Result &operator=(const Result &) = delete; Result &operator=(Result &&result) { m_value = std::move(result.m_value); return *this; } ~Result() { } operator bool() const { return m_status; } const ValueT &value() const { return m_value; } ValueT &value() { return m_value; } private: ValueT m_value; bool m_status; }; template using ResultVoid = struct Result; } #endif /* GPICK_COMMON_RESULT_H_ */ gpick-gpick-0.2.6/source/common/Scoped.h000066400000000000000000000077051377073231300201040ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_COMMON_SCOPED_H_ #define GPICK_COMMON_SCOPED_H_ #include #include #include namespace common { namespace detail { template auto apply(Function f, Tuple t, std::index_sequence) { return f(std::get(t)...); } template auto apply(Function f, Tuple t) { static constexpr auto size = std::tuple_size::value; return apply(f, t, std::make_index_sequence {}); } } template struct Scoped; template struct Scoped { Scoped(void (*callable)(Args...), Args... params): m_callable(callable), m_arguments(std::forward_as_tuple(params...)), m_canceled(false) { } Scoped(Scoped &&scoped) { m_callable = scoped.m_callable; m_arguments = std::move(scoped.m_arguments); m_canceled = scoped.m_canceled; scoped.m_canceled = true; } Scoped(const Scoped &) = delete; Scoped &operator=(const Scoped &) = delete; ~Scoped() { if (!m_canceled && m_callable) detail::apply(m_callable, m_arguments); } void cancel() { m_canceled = true; } private: void (*m_callable)(Args...); std::tuple m_arguments; bool m_canceled; }; template struct Scoped> { Scoped(std::function callable, Args... params): m_callable(callable), m_arguments(std::forward_as_tuple(params...)), m_canceled(false) { } Scoped(Scoped &&scoped): m_callable(std::move(scoped.m_callable)), m_arguments(std::move(scoped.m_arguments)), m_canceled(scoped.m_canceled) { scoped.m_canceled = true; } Scoped(const Scoped &) = delete; Scoped &operator=(const Scoped &) = delete; ~Scoped() { if (!m_canceled && m_callable) detail::apply(m_callable, m_arguments); } void cancel() { m_canceled = true; } private: std::function m_callable; std::tuple m_arguments; bool m_canceled; }; template>::value, int> = 0> auto makeScoped(Callable callable, Args... args) { return Scoped(callable, args...); } template>::value, int> = 0> auto makeScoped(Callable callable, Args... args) { return Scoped(callable, args...); } } #endif /* GPICK_COMMON_SCOPED_H_ */ gpick-gpick-0.2.6/source/common/SetOnScopeEnd.h000066400000000000000000000041011377073231300213230ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_COMMON_SET_ON_SCOPE_END_H_ #define GPICK_COMMON_SET_ON_SCOPE_END_H_ namespace common { template struct SetOnScopeEnd { SetOnScopeEnd(T &target, T value): m_target(target), m_value(value), m_canceled(false) { } SetOnScopeEnd(const SetOnScopeEnd &) = delete; SetOnScopeEnd &operator=(const SetOnScopeEnd &) = delete; ~SetOnScopeEnd() { if (!m_canceled) m_target = m_value; } void cancel() { m_canceled = true; } private: T &m_target; T m_value; bool m_canceled; }; } #endif /* GPICK_COMMON_SET_ON_SCOPE_END_H_ */ gpick-gpick-0.2.6/source/common/Span.h000066400000000000000000000107071377073231300175640ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_COMMON_SPAN_H_ #define GPICK_COMMON_SPAN_H_ #include namespace common { template struct Span { struct Iterator { using iterator_category = std::forward_iterator_tag; using value_type = T; using difference_type = Size; using pointer = T*; using reference = T&; Iterator(Span &span, Size position): m_span(span), m_position(position) { } bool operator!=(const Iterator &iterator) const { return m_span != iterator.m_span || m_position != iterator.m_position; } bool operator==(const Iterator &iterator) const { return m_span == iterator.m_span && m_position == iterator.m_position; } Size operator-(const Iterator &iterator) const { return m_position - iterator.m_position; } Iterator &operator++() { m_position++; return *this; } const T &operator*() const { return m_span.m_data[m_position]; } T &operator*() { return m_span.m_data[m_position]; } private: Span &m_span; Size m_position; }; struct ConstIterator { using iterator_category = std::forward_iterator_tag; using value_type = T; using difference_type = Size; using pointer = T*; using reference = T&; ConstIterator(const Span &span, Size position): m_span(span), m_position(position) { } bool operator!=(const ConstIterator &iterator) const { return m_span != iterator.m_span || m_position != iterator.m_position; } bool operator==(const ConstIterator &iterator) const { return m_span == iterator.m_span && m_position == iterator.m_position; } Size operator-(const ConstIterator &iterator) const { return m_position - iterator.m_position; } ConstIterator &operator++() { m_position++; return *this; } const T &operator*() const { return m_span.m_data[m_position]; } T &operator*() { return m_span.m_data[m_position]; } private: const Span &m_span; Size m_position; }; Span(): m_data(nullptr) { } Span(T *data, Size size): m_data(data), m_size(size) { } Span(T *start, T *end): m_data(start), m_size(static_cast(end - start) / sizeof(T)) { } Span(const Span &span): m_data(span.m_data), m_size(span.m_size) { } Span &operator=(const Span &span) { m_data = span.m_data; m_size = span.m_size; return *this; } explicit operator bool() const { return m_data != nullptr && m_size > 0; } bool operator==(const Span &span) const { return m_data == span.m_data && m_size == span.m_size; } bool operator!=(const Span &span) const { return m_data != span.m_data || m_size != span.m_size; } Iterator begin() { return Iterator(*this, 0); } Iterator end() { return Iterator(*this, m_size); } ConstIterator begin() const { return ConstIterator(*this, 0); } ConstIterator end() const { return ConstIterator(*this, m_size); } Size size() const { return m_size; } private: T *m_data; Size m_size; friend Iterator; friend ConstIterator; }; }; #endif /* GPICK_COMMON_SPAN_H_ */ gpick-gpick-0.2.6/source/dbus/000077500000000000000000000000001377073231300161525ustar00rootroot00000000000000gpick-gpick-0.2.6/source/dbus/Control.cpp000066400000000000000000000175141377073231300203060ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Control.h" #ifndef WIN32 #include "DbusInterface.h" #include using namespace std; namespace dbus { struct Control::Impl { public: Control *m_decl; GDBusObjectManagerServer *m_manager; guint m_bus_id; Impl(Control *decl): m_decl(decl), m_manager(nullptr), m_bus_id(0) { } void ownName() { m_bus_id = g_bus_own_name(G_BUS_TYPE_SESSION, "org.gpick", GBusNameOwnerFlags(G_BUS_NAME_OWNER_FLAGS_REPLACE), (GBusAcquiredCallback)on_bus_acquired, (GBusNameAcquiredCallback)on_name_acquired, (GBusNameLostCallback)on_name_lost, this, nullptr); } void unownName() { g_bus_unown_name(m_bus_id); m_bus_id = 0; } GDBusObjectManager* getManager() { GDBusObjectManager *manager; GError *error = nullptr; manager = gpick_object_manager_client_new_for_bus_sync(G_BUS_TYPE_SESSION, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, "org.gpick", "/org/gpick", nullptr, &error); if (manager == nullptr) { cerr << "Error getting object manager client: " << error->message << endl; g_error_free (error); return 0; } return manager; } bool activateFloatingPicker(const std::string &converter_name) { GDBusObjectManager *manager = getManager(); if (!manager) return false; GError *error = nullptr; GDBusInterface *interface = g_dbus_object_manager_get_interface(manager, "/org/gpick/Control", "org.gpick.Control"); bool result = false; if (interface){ if (!gpick_control_call_activate_floating_picker_sync(GPICK_CONTROL(interface), converter_name.c_str(), nullptr, &error)){ cerr << "Error calling \"Control.ActivateFloatingPicker\": " << error->message << endl; g_error_free (error); }else result = true; g_object_unref(interface); } g_object_unref(manager); return result; } bool checkIfRunning() { GDBusObjectManager *manager = getManager(); if (!manager) return false; GError *error = nullptr; GDBusInterface *interface = g_dbus_object_manager_get_interface(manager, "/org/gpick/Control", "org.gpick.Control"); bool result = false; if (interface){ if (!gpick_control_call_check_if_running_sync(GPICK_CONTROL(interface), nullptr, &error)){ cerr << "Error calling \"Control.CheckIfRunning\": " << error->message << endl; g_error_free (error); }else result = true; g_object_unref(interface); } g_object_unref(manager); return result; } bool singleInstanceActivate() { GDBusObjectManager *manager = getManager(); if (!manager) return false; GError *error = nullptr; GDBusInterface *interface = g_dbus_object_manager_get_interface(manager, "/org/gpick/SingleInstance", "org.gpick.SingleInstance"); bool result = false; if (interface){ if (!gpick_single_instance_call_activate_sync(GPICK_SINGLE_INSTANCE(interface), nullptr, &error)){ cerr << "Error calling \"SingleInstance.Activate\": " << error->message << endl; g_error_free (error); }else result = true; g_object_unref(interface); } g_object_unref(manager); return result; } static gboolean on_control_activate_floating_picker(GpickControl *control, GDBusMethodInvocation *invocation, const char *converter_name, Impl *impl) { bool result = impl->m_decl->onActivateFloatingPicker ? impl->m_decl->onActivateFloatingPicker(converter_name) : false; gpick_control_complete_activate_floating_picker(control, invocation); return result; } static gboolean on_control_check_if_running(GpickControl *control, GDBusMethodInvocation *invocation, Impl*) { gpick_control_complete_check_if_running(control, invocation); return true; } static gboolean on_single_instance_activate(GpickSingleInstance *single_instance, GDBusMethodInvocation *invocation, Impl *impl) { bool result = impl->m_decl->onSingleInstanceActivate(); gpick_single_instance_complete_activate(single_instance, invocation); return result; } static void on_bus_acquired(GDBusConnection *connection, const gchar *name, Impl *impl) { auto manager = g_dbus_object_manager_server_new("/org/gpick"); impl->m_manager = manager; GpickObjectSkeleton *object; object = gpick_object_skeleton_new("/org/gpick/Control"); GpickControl *control; control = gpick_control_skeleton_new(); gpick_object_skeleton_set_control(object, control); g_object_unref(control); g_signal_connect(control, "handle-activate-floating-picker", G_CALLBACK(on_control_activate_floating_picker), impl); g_signal_connect(control, "handle-check-if-running", G_CALLBACK(on_control_check_if_running), impl); g_dbus_object_manager_server_export(manager, G_DBUS_OBJECT_SKELETON(object)); g_object_unref(object); GpickSingleInstance *single_instance; object = gpick_object_skeleton_new("/org/gpick/SingleInstance"); single_instance = gpick_single_instance_skeleton_new(); gpick_object_skeleton_set_single_instance(object, single_instance); g_object_unref(single_instance); g_signal_connect(single_instance, "handle-activate", G_CALLBACK(on_single_instance_activate), impl); g_dbus_object_manager_server_export(manager, G_DBUS_OBJECT_SKELETON(object)); g_object_unref(object); g_dbus_object_manager_server_set_connection(manager, connection); } static void on_name_acquired(GDBusConnection *connection, const gchar *name, Impl*) { } static void on_name_lost(GDBusConnection *connection, const gchar *name, Impl*) { }; }; Control::Control() { m_impl = make_unique(this); } Control::~Control() { } void Control::ownName() { m_impl->ownName(); } void Control::unownName() { m_impl->unownName(); } bool Control::singleInstanceActivate() { return m_impl->singleInstanceActivate(); } bool Control::activateFloatingPicker(const std::string &converter_name) { return m_impl->activateFloatingPicker(converter_name); } bool Control::checkIfRunning() { return m_impl->checkIfRunning(); } } #else namespace dbus { struct Control::Impl { }; Control::Control() { } Control::~Control() { } void Control::ownName() { } void Control::unownName() { } bool Control::singleInstanceActivate() { return false; } bool Control::activateFloatingPicker(const std::string &converter_name) { return false; } bool Control::checkIfRunning() { return false; } } #endif gpick-gpick-0.2.6/source/dbus/Control.h000066400000000000000000000041211377073231300177410ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_DBUS_CONTROL_H_ #define GPICK_DBUS_CONTROL_H_ #include #include #include namespace dbus { struct Control { public: Control(); ~Control(); void ownName(); void unownName(); bool singleInstanceActivate(); bool activateFloatingPicker(const std::string &converter_name); bool checkIfRunning(); std::function onActivateFloatingPicker; std::function onSingleInstanceActivate; private: struct Impl; std::unique_ptr m_impl; }; } #endif /* GPICK_DBUS_CONTROL_H_ */ gpick-gpick-0.2.6/source/dbus/DbusInterface.c000066400000000000000000002710721377073231300210450ustar00rootroot00000000000000/* * Generated by gdbus-codegen 2.48.0. DO NOT EDIT. * * The license of this code is the same as for the source it was derived from. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "DbusInterface.h" #include #ifdef G_OS_UNIX # include #endif typedef struct { GDBusArgInfo parent_struct; gboolean use_gvariant; } _ExtendedGDBusArgInfo; typedef struct { GDBusMethodInfo parent_struct; const gchar *signal_name; gboolean pass_fdlist; } _ExtendedGDBusMethodInfo; typedef struct { GDBusSignalInfo parent_struct; const gchar *signal_name; } _ExtendedGDBusSignalInfo; typedef struct { GDBusPropertyInfo parent_struct; const gchar *hyphen_name; gboolean use_gvariant; } _ExtendedGDBusPropertyInfo; typedef struct { GDBusInterfaceInfo parent_struct; const gchar *hyphen_name; } _ExtendedGDBusInterfaceInfo; typedef struct { const _ExtendedGDBusPropertyInfo *info; guint prop_id; GValue orig_value; /* the value before the change */ } ChangedProperty; static void _changed_property_free (ChangedProperty *data) { g_value_unset (&data->orig_value); g_free (data); } static gboolean _g_strv_equal0 (gchar **a, gchar **b) { gboolean ret = FALSE; guint n; if (a == NULL && b == NULL) { ret = TRUE; goto out; } if (a == NULL || b == NULL) goto out; if (g_strv_length (a) != g_strv_length (b)) goto out; for (n = 0; a[n] != NULL; n++) if (g_strcmp0 (a[n], b[n]) != 0) goto out; ret = TRUE; out: return ret; } static gboolean _g_variant_equal0 (GVariant *a, GVariant *b) { gboolean ret = FALSE; if (a == NULL && b == NULL) { ret = TRUE; goto out; } if (a == NULL || b == NULL) goto out; ret = g_variant_equal (a, b); out: return ret; } G_GNUC_UNUSED static gboolean _g_value_equal (const GValue *a, const GValue *b) { gboolean ret = FALSE; g_assert (G_VALUE_TYPE (a) == G_VALUE_TYPE (b)); switch (G_VALUE_TYPE (a)) { case G_TYPE_BOOLEAN: ret = (g_value_get_boolean (a) == g_value_get_boolean (b)); break; case G_TYPE_UCHAR: ret = (g_value_get_uchar (a) == g_value_get_uchar (b)); break; case G_TYPE_INT: ret = (g_value_get_int (a) == g_value_get_int (b)); break; case G_TYPE_UINT: ret = (g_value_get_uint (a) == g_value_get_uint (b)); break; case G_TYPE_INT64: ret = (g_value_get_int64 (a) == g_value_get_int64 (b)); break; case G_TYPE_UINT64: ret = (g_value_get_uint64 (a) == g_value_get_uint64 (b)); break; case G_TYPE_DOUBLE: { /* Avoid -Wfloat-equal warnings by doing a direct bit compare */ gdouble da = g_value_get_double (a); gdouble db = g_value_get_double (b); ret = memcmp (&da, &db, sizeof (gdouble)) == 0; } break; case G_TYPE_STRING: ret = (g_strcmp0 (g_value_get_string (a), g_value_get_string (b)) == 0); break; case G_TYPE_VARIANT: ret = _g_variant_equal0 (g_value_get_variant (a), g_value_get_variant (b)); break; default: if (G_VALUE_TYPE (a) == G_TYPE_STRV) ret = _g_strv_equal0 (g_value_get_boxed (a), g_value_get_boxed (b)); else g_critical ("_g_value_equal() does not handle type %s", g_type_name (G_VALUE_TYPE (a))); break; } return ret; } /* ------------------------------------------------------------------------ * Code for interface org.gpick.SingleInstance * ------------------------------------------------------------------------ */ /** * SECTION:GpickSingleInstance * @title: GpickSingleInstance * @short_description: Generated C code for the org.gpick.SingleInstance D-Bus interface * * This section contains code for working with the org.gpick.SingleInstance D-Bus interface in C. */ /* ---- Introspection data for org.gpick.SingleInstance ---- */ static const _ExtendedGDBusMethodInfo _gpick_single_instance_method_info_activate = { { -1, (gchar *) "Activate", NULL, NULL, NULL }, "handle-activate", FALSE }; static const _ExtendedGDBusMethodInfo * const _gpick_single_instance_method_info_pointers[] = { &_gpick_single_instance_method_info_activate, NULL }; static const _ExtendedGDBusInterfaceInfo _gpick_single_instance_interface_info = { { -1, (gchar *) "org.gpick.SingleInstance", (GDBusMethodInfo **) &_gpick_single_instance_method_info_pointers, NULL, NULL, NULL }, "single-instance", }; /** * gpick_single_instance_interface_info: * * Gets a machine-readable description of the org.gpick.SingleInstance D-Bus interface. * * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free. */ GDBusInterfaceInfo * gpick_single_instance_interface_info (void) { return (GDBusInterfaceInfo *) &_gpick_single_instance_interface_info.parent_struct; } /** * gpick_single_instance_override_properties: * @klass: The class structure for a #GObject-derived class. * @property_id_begin: The property id to assign to the first overridden property. * * Overrides all #GObject properties in the #GpickSingleInstance interface for a concrete class. * The properties are overridden in the order they are defined. * * Returns: The last property id. */ guint gpick_single_instance_override_properties (GObjectClass *klass, guint property_id_begin) { return property_id_begin - 1; } /** * GpickSingleInstance: * * Abstract interface type for the D-Bus interface org.gpick.SingleInstance. */ /** * GpickSingleInstanceIface: * @parent_iface: The parent interface. * @handle_activate: Handler for the #GpickSingleInstance::handle-activate signal. * * Virtual table for the D-Bus interface org.gpick.SingleInstance. */ typedef GpickSingleInstanceIface GpickSingleInstanceInterface; G_DEFINE_INTERFACE (GpickSingleInstance, gpick_single_instance, G_TYPE_OBJECT); static void gpick_single_instance_default_init (GpickSingleInstanceIface *iface) { /* GObject signals for incoming D-Bus method calls: */ /** * GpickSingleInstance::handle-activate: * @object: A #GpickSingleInstance. * @invocation: A #GDBusMethodInvocation. * * Signal emitted when a remote caller is invoking the Activate() D-Bus method. * * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gpick_single_instance_complete_activate() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. * * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run. */ g_signal_new ("handle-activate", G_TYPE_FROM_INTERFACE (iface), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GpickSingleInstanceIface, handle_activate), g_signal_accumulator_true_handled, NULL, g_cclosure_marshal_generic, G_TYPE_BOOLEAN, 1, G_TYPE_DBUS_METHOD_INVOCATION); } /** * gpick_single_instance_call_activate: * @proxy: A #GpickSingleInstanceProxy. * @cancellable: (allow-none): A #GCancellable or %NULL. * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL. * @user_data: User data to pass to @callback. * * Asynchronously invokes the Activate() D-Bus method on @proxy. * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from. * You can then call gpick_single_instance_call_activate_finish() to get the result of the operation. * * See gpick_single_instance_call_activate_sync() for the synchronous, blocking version of this method. */ void gpick_single_instance_call_activate ( GpickSingleInstance *proxy, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_dbus_proxy_call (G_DBUS_PROXY (proxy), "Activate", g_variant_new ("()"), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, callback, user_data); } /** * gpick_single_instance_call_activate_finish: * @proxy: A #GpickSingleInstanceProxy. * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gpick_single_instance_call_activate(). * @error: Return location for error or %NULL. * * Finishes an operation started with gpick_single_instance_call_activate(). * * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set. */ gboolean gpick_single_instance_call_activate_finish ( GpickSingleInstance *proxy, GAsyncResult *res, GError **error) { GVariant *_ret; _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error); if (_ret == NULL) goto _out; g_variant_get (_ret, "()"); g_variant_unref (_ret); _out: return _ret != NULL; } /** * gpick_single_instance_call_activate_sync: * @proxy: A #GpickSingleInstanceProxy. * @cancellable: (allow-none): A #GCancellable or %NULL. * @error: Return location for error or %NULL. * * Synchronously invokes the Activate() D-Bus method on @proxy. The calling thread is blocked until a reply is received. * * See gpick_single_instance_call_activate() for the asynchronous version of this method. * * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set. */ gboolean gpick_single_instance_call_activate_sync ( GpickSingleInstance *proxy, GCancellable *cancellable, GError **error) { GVariant *_ret; _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy), "Activate", g_variant_new ("()"), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error); if (_ret == NULL) goto _out; g_variant_get (_ret, "()"); g_variant_unref (_ret); _out: return _ret != NULL; } /** * gpick_single_instance_complete_activate: * @object: A #GpickSingleInstance. * @invocation: (transfer full): A #GDBusMethodInvocation. * * Helper function used in service implementations to finish handling invocations of the Activate() D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar. * * This method will free @invocation, you cannot use it afterwards. */ void gpick_single_instance_complete_activate ( GpickSingleInstance *object, GDBusMethodInvocation *invocation) { g_dbus_method_invocation_return_value (invocation, g_variant_new ("()")); } /* ------------------------------------------------------------------------ */ /** * GpickSingleInstanceProxy: * * The #GpickSingleInstanceProxy structure contains only private data and should only be accessed using the provided API. */ /** * GpickSingleInstanceProxyClass: * @parent_class: The parent class. * * Class structure for #GpickSingleInstanceProxy. */ struct _GpickSingleInstanceProxyPrivate { GData *qdata; }; static void gpick_single_instance_proxy_iface_init (GpickSingleInstanceIface *iface); #if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38 G_DEFINE_TYPE_WITH_CODE (GpickSingleInstanceProxy, gpick_single_instance_proxy, G_TYPE_DBUS_PROXY, G_ADD_PRIVATE (GpickSingleInstanceProxy) G_IMPLEMENT_INTERFACE (GPICK_TYPE_SINGLE_INSTANCE, gpick_single_instance_proxy_iface_init)); #else G_DEFINE_TYPE_WITH_CODE (GpickSingleInstanceProxy, gpick_single_instance_proxy, G_TYPE_DBUS_PROXY, G_IMPLEMENT_INTERFACE (GPICK_TYPE_SINGLE_INSTANCE, gpick_single_instance_proxy_iface_init)); #endif static void gpick_single_instance_proxy_finalize (GObject *object) { GpickSingleInstanceProxy *proxy = GPICK_SINGLE_INSTANCE_PROXY (object); g_datalist_clear (&proxy->priv->qdata); G_OBJECT_CLASS (gpick_single_instance_proxy_parent_class)->finalize (object); } static void gpick_single_instance_proxy_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec G_GNUC_UNUSED) { } static void gpick_single_instance_proxy_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec G_GNUC_UNUSED) { } static void gpick_single_instance_proxy_g_signal (GDBusProxy *proxy, const gchar *sender_name G_GNUC_UNUSED, const gchar *signal_name, GVariant *parameters) { _ExtendedGDBusSignalInfo *info; GVariantIter iter; GVariant *child; GValue *paramv; guint num_params; guint n; guint signal_id; info = (_ExtendedGDBusSignalInfo *) g_dbus_interface_info_lookup_signal ((GDBusInterfaceInfo *) &_gpick_single_instance_interface_info.parent_struct, signal_name); if (info == NULL) return; num_params = g_variant_n_children (parameters); paramv = g_new0 (GValue, num_params + 1); g_value_init (¶mv[0], GPICK_TYPE_SINGLE_INSTANCE); g_value_set_object (¶mv[0], proxy); g_variant_iter_init (&iter, parameters); n = 1; while ((child = g_variant_iter_next_value (&iter)) != NULL) { _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.args[n - 1]; if (arg_info->use_gvariant) { g_value_init (¶mv[n], G_TYPE_VARIANT); g_value_set_variant (¶mv[n], child); n++; } else g_dbus_gvariant_to_gvalue (child, ¶mv[n++]); g_variant_unref (child); } signal_id = g_signal_lookup (info->signal_name, GPICK_TYPE_SINGLE_INSTANCE); g_signal_emitv (paramv, signal_id, 0, NULL); for (n = 0; n < num_params + 1; n++) g_value_unset (¶mv[n]); g_free (paramv); } static void gpick_single_instance_proxy_g_properties_changed (GDBusProxy *_proxy, GVariant *changed_properties, const gchar *const *invalidated_properties) { GpickSingleInstanceProxy *proxy = GPICK_SINGLE_INSTANCE_PROXY (_proxy); guint n; const gchar *key; GVariantIter *iter; _ExtendedGDBusPropertyInfo *info; g_variant_get (changed_properties, "a{sv}", &iter); while (g_variant_iter_next (iter, "{&sv}", &key, NULL)) { info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gpick_single_instance_interface_info.parent_struct, key); g_datalist_remove_data (&proxy->priv->qdata, key); if (info != NULL) g_object_notify (G_OBJECT (proxy), info->hyphen_name); } g_variant_iter_free (iter); for (n = 0; invalidated_properties[n] != NULL; n++) { info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gpick_single_instance_interface_info.parent_struct, invalidated_properties[n]); g_datalist_remove_data (&proxy->priv->qdata, invalidated_properties[n]); if (info != NULL) g_object_notify (G_OBJECT (proxy), info->hyphen_name); } } static void gpick_single_instance_proxy_init (GpickSingleInstanceProxy *proxy) { #if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38 proxy->priv = gpick_single_instance_proxy_get_instance_private (proxy); #else proxy->priv = G_TYPE_INSTANCE_GET_PRIVATE (proxy, GPICK_TYPE_SINGLE_INSTANCE_PROXY, GpickSingleInstanceProxyPrivate); #endif g_dbus_proxy_set_interface_info (G_DBUS_PROXY (proxy), gpick_single_instance_interface_info ()); } static void gpick_single_instance_proxy_class_init (GpickSingleInstanceProxyClass *klass) { GObjectClass *gobject_class; GDBusProxyClass *proxy_class; gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = gpick_single_instance_proxy_finalize; gobject_class->get_property = gpick_single_instance_proxy_get_property; gobject_class->set_property = gpick_single_instance_proxy_set_property; proxy_class = G_DBUS_PROXY_CLASS (klass); proxy_class->g_signal = gpick_single_instance_proxy_g_signal; proxy_class->g_properties_changed = gpick_single_instance_proxy_g_properties_changed; #if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38 g_type_class_add_private (klass, sizeof (GpickSingleInstanceProxyPrivate)); #endif } static void gpick_single_instance_proxy_iface_init (GpickSingleInstanceIface *iface) { } /** * gpick_single_instance_proxy_new: * @connection: A #GDBusConnection. * @flags: Flags from the #GDBusProxyFlags enumeration. * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection. * @object_path: An object path. * @cancellable: (allow-none): A #GCancellable or %NULL. * @callback: A #GAsyncReadyCallback to call when the request is satisfied. * @user_data: User data to pass to @callback. * * Asynchronously creates a proxy for the D-Bus interface org.gpick.SingleInstance. See g_dbus_proxy_new() for more details. * * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from. * You can then call gpick_single_instance_proxy_new_finish() to get the result of the operation. * * See gpick_single_instance_proxy_new_sync() for the synchronous, blocking version of this constructor. */ void gpick_single_instance_proxy_new ( GDBusConnection *connection, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_async_initable_new_async (GPICK_TYPE_SINGLE_INSTANCE_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "org.gpick.SingleInstance", NULL); } /** * gpick_single_instance_proxy_new_finish: * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gpick_single_instance_proxy_new(). * @error: Return location for error or %NULL * * Finishes an operation started with gpick_single_instance_proxy_new(). * * Returns: (transfer full) (type GpickSingleInstanceProxy): The constructed proxy object or %NULL if @error is set. */ GpickSingleInstance * gpick_single_instance_proxy_new_finish ( GAsyncResult *res, GError **error) { GObject *ret; GObject *source_object; source_object = g_async_result_get_source_object (res); ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error); g_object_unref (source_object); if (ret != NULL) return GPICK_SINGLE_INSTANCE (ret); else return NULL; } /** * gpick_single_instance_proxy_new_sync: * @connection: A #GDBusConnection. * @flags: Flags from the #GDBusProxyFlags enumeration. * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection. * @object_path: An object path. * @cancellable: (allow-none): A #GCancellable or %NULL. * @error: Return location for error or %NULL * * Synchronously creates a proxy for the D-Bus interface org.gpick.SingleInstance. See g_dbus_proxy_new_sync() for more details. * * The calling thread is blocked until a reply is received. * * See gpick_single_instance_proxy_new() for the asynchronous version of this constructor. * * Returns: (transfer full) (type GpickSingleInstanceProxy): The constructed proxy object or %NULL if @error is set. */ GpickSingleInstance * gpick_single_instance_proxy_new_sync ( GDBusConnection *connection, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GError **error) { GInitable *ret; ret = g_initable_new (GPICK_TYPE_SINGLE_INSTANCE_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "org.gpick.SingleInstance", NULL); if (ret != NULL) return GPICK_SINGLE_INSTANCE (ret); else return NULL; } /** * gpick_single_instance_proxy_new_for_bus: * @bus_type: A #GBusType. * @flags: Flags from the #GDBusProxyFlags enumeration. * @name: A bus name (well-known or unique). * @object_path: An object path. * @cancellable: (allow-none): A #GCancellable or %NULL. * @callback: A #GAsyncReadyCallback to call when the request is satisfied. * @user_data: User data to pass to @callback. * * Like gpick_single_instance_proxy_new() but takes a #GBusType instead of a #GDBusConnection. * * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from. * You can then call gpick_single_instance_proxy_new_for_bus_finish() to get the result of the operation. * * See gpick_single_instance_proxy_new_for_bus_sync() for the synchronous, blocking version of this constructor. */ void gpick_single_instance_proxy_new_for_bus ( GBusType bus_type, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_async_initable_new_async (GPICK_TYPE_SINGLE_INSTANCE_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "org.gpick.SingleInstance", NULL); } /** * gpick_single_instance_proxy_new_for_bus_finish: * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gpick_single_instance_proxy_new_for_bus(). * @error: Return location for error or %NULL * * Finishes an operation started with gpick_single_instance_proxy_new_for_bus(). * * Returns: (transfer full) (type GpickSingleInstanceProxy): The constructed proxy object or %NULL if @error is set. */ GpickSingleInstance * gpick_single_instance_proxy_new_for_bus_finish ( GAsyncResult *res, GError **error) { GObject *ret; GObject *source_object; source_object = g_async_result_get_source_object (res); ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error); g_object_unref (source_object); if (ret != NULL) return GPICK_SINGLE_INSTANCE (ret); else return NULL; } /** * gpick_single_instance_proxy_new_for_bus_sync: * @bus_type: A #GBusType. * @flags: Flags from the #GDBusProxyFlags enumeration. * @name: A bus name (well-known or unique). * @object_path: An object path. * @cancellable: (allow-none): A #GCancellable or %NULL. * @error: Return location for error or %NULL * * Like gpick_single_instance_proxy_new_sync() but takes a #GBusType instead of a #GDBusConnection. * * The calling thread is blocked until a reply is received. * * See gpick_single_instance_proxy_new_for_bus() for the asynchronous version of this constructor. * * Returns: (transfer full) (type GpickSingleInstanceProxy): The constructed proxy object or %NULL if @error is set. */ GpickSingleInstance * gpick_single_instance_proxy_new_for_bus_sync ( GBusType bus_type, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GError **error) { GInitable *ret; ret = g_initable_new (GPICK_TYPE_SINGLE_INSTANCE_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "org.gpick.SingleInstance", NULL); if (ret != NULL) return GPICK_SINGLE_INSTANCE (ret); else return NULL; } /* ------------------------------------------------------------------------ */ /** * GpickSingleInstanceSkeleton: * * The #GpickSingleInstanceSkeleton structure contains only private data and should only be accessed using the provided API. */ /** * GpickSingleInstanceSkeletonClass: * @parent_class: The parent class. * * Class structure for #GpickSingleInstanceSkeleton. */ struct _GpickSingleInstanceSkeletonPrivate { GValue *properties; GList *changed_properties; GSource *changed_properties_idle_source; GMainContext *context; GMutex lock; }; static void _gpick_single_instance_skeleton_handle_method_call ( GDBusConnection *connection G_GNUC_UNUSED, const gchar *sender G_GNUC_UNUSED, const gchar *object_path G_GNUC_UNUSED, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { GpickSingleInstanceSkeleton *skeleton = GPICK_SINGLE_INSTANCE_SKELETON (user_data); _ExtendedGDBusMethodInfo *info; GVariantIter iter; GVariant *child; GValue *paramv; guint num_params; guint num_extra; guint n; guint signal_id; GValue return_value = G_VALUE_INIT; info = (_ExtendedGDBusMethodInfo *) g_dbus_method_invocation_get_method_info (invocation); g_assert (info != NULL); num_params = g_variant_n_children (parameters); num_extra = info->pass_fdlist ? 3 : 2; paramv = g_new0 (GValue, num_params + num_extra); n = 0; g_value_init (¶mv[n], GPICK_TYPE_SINGLE_INSTANCE); g_value_set_object (¶mv[n++], skeleton); g_value_init (¶mv[n], G_TYPE_DBUS_METHOD_INVOCATION); g_value_set_object (¶mv[n++], invocation); if (info->pass_fdlist) { #ifdef G_OS_UNIX g_value_init (¶mv[n], G_TYPE_UNIX_FD_LIST); g_value_set_object (¶mv[n++], g_dbus_message_get_unix_fd_list (g_dbus_method_invocation_get_message (invocation))); #else g_assert_not_reached (); #endif } g_variant_iter_init (&iter, parameters); while ((child = g_variant_iter_next_value (&iter)) != NULL) { _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.in_args[n - num_extra]; if (arg_info->use_gvariant) { g_value_init (¶mv[n], G_TYPE_VARIANT); g_value_set_variant (¶mv[n], child); n++; } else g_dbus_gvariant_to_gvalue (child, ¶mv[n++]); g_variant_unref (child); } signal_id = g_signal_lookup (info->signal_name, GPICK_TYPE_SINGLE_INSTANCE); g_value_init (&return_value, G_TYPE_BOOLEAN); g_signal_emitv (paramv, signal_id, 0, &return_value); if (!g_value_get_boolean (&return_value)) g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method %s is not implemented on interface %s", method_name, interface_name); g_value_unset (&return_value); for (n = 0; n < num_params + num_extra; n++) g_value_unset (¶mv[n]); g_free (paramv); } static GVariant * _gpick_single_instance_skeleton_handle_get_property ( GDBusConnection *connection G_GNUC_UNUSED, const gchar *sender G_GNUC_UNUSED, const gchar *object_path G_GNUC_UNUSED, const gchar *interface_name G_GNUC_UNUSED, const gchar *property_name, GError **error, gpointer user_data) { GpickSingleInstanceSkeleton *skeleton = GPICK_SINGLE_INSTANCE_SKELETON (user_data); GValue value = G_VALUE_INIT; GParamSpec *pspec; _ExtendedGDBusPropertyInfo *info; GVariant *ret; ret = NULL; info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gpick_single_instance_interface_info.parent_struct, property_name); g_assert (info != NULL); pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name); if (pspec == NULL) { g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name); } else { g_value_init (&value, pspec->value_type); g_object_get_property (G_OBJECT (skeleton), info->hyphen_name, &value); ret = g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (info->parent_struct.signature)); g_value_unset (&value); } return ret; } static gboolean _gpick_single_instance_skeleton_handle_set_property ( GDBusConnection *connection G_GNUC_UNUSED, const gchar *sender G_GNUC_UNUSED, const gchar *object_path G_GNUC_UNUSED, const gchar *interface_name G_GNUC_UNUSED, const gchar *property_name, GVariant *variant, GError **error, gpointer user_data) { GpickSingleInstanceSkeleton *skeleton = GPICK_SINGLE_INSTANCE_SKELETON (user_data); GValue value = G_VALUE_INIT; GParamSpec *pspec; _ExtendedGDBusPropertyInfo *info; gboolean ret; ret = FALSE; info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gpick_single_instance_interface_info.parent_struct, property_name); g_assert (info != NULL); pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name); if (pspec == NULL) { g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name); } else { if (info->use_gvariant) g_value_set_variant (&value, variant); else g_dbus_gvariant_to_gvalue (variant, &value); g_object_set_property (G_OBJECT (skeleton), info->hyphen_name, &value); g_value_unset (&value); ret = TRUE; } return ret; } static const GDBusInterfaceVTable _gpick_single_instance_skeleton_vtable = { _gpick_single_instance_skeleton_handle_method_call, _gpick_single_instance_skeleton_handle_get_property, _gpick_single_instance_skeleton_handle_set_property, {NULL} }; static GDBusInterfaceInfo * gpick_single_instance_skeleton_dbus_interface_get_info (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED) { return gpick_single_instance_interface_info (); } static GDBusInterfaceVTable * gpick_single_instance_skeleton_dbus_interface_get_vtable (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED) { return (GDBusInterfaceVTable *) &_gpick_single_instance_skeleton_vtable; } static GVariant * gpick_single_instance_skeleton_dbus_interface_get_properties (GDBusInterfaceSkeleton *_skeleton) { GpickSingleInstanceSkeleton *skeleton = GPICK_SINGLE_INSTANCE_SKELETON (_skeleton); GVariantBuilder builder; guint n; g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); if (_gpick_single_instance_interface_info.parent_struct.properties == NULL) goto out; for (n = 0; _gpick_single_instance_interface_info.parent_struct.properties[n] != NULL; n++) { GDBusPropertyInfo *info = _gpick_single_instance_interface_info.parent_struct.properties[n]; if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE) { GVariant *value; value = _gpick_single_instance_skeleton_handle_get_property (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)), NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "org.gpick.SingleInstance", info->name, NULL, skeleton); if (value != NULL) { g_variant_take_ref (value); g_variant_builder_add (&builder, "{sv}", info->name, value); g_variant_unref (value); } } } out: return g_variant_builder_end (&builder); } static void gpick_single_instance_skeleton_dbus_interface_flush (GDBusInterfaceSkeleton *_skeleton) { } static void gpick_single_instance_skeleton_iface_init (GpickSingleInstanceIface *iface); #if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38 G_DEFINE_TYPE_WITH_CODE (GpickSingleInstanceSkeleton, gpick_single_instance_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON, G_ADD_PRIVATE (GpickSingleInstanceSkeleton) G_IMPLEMENT_INTERFACE (GPICK_TYPE_SINGLE_INSTANCE, gpick_single_instance_skeleton_iface_init)); #else G_DEFINE_TYPE_WITH_CODE (GpickSingleInstanceSkeleton, gpick_single_instance_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON, G_IMPLEMENT_INTERFACE (GPICK_TYPE_SINGLE_INSTANCE, gpick_single_instance_skeleton_iface_init)); #endif static void gpick_single_instance_skeleton_finalize (GObject *object) { GpickSingleInstanceSkeleton *skeleton = GPICK_SINGLE_INSTANCE_SKELETON (object); g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free); if (skeleton->priv->changed_properties_idle_source != NULL) g_source_destroy (skeleton->priv->changed_properties_idle_source); g_main_context_unref (skeleton->priv->context); g_mutex_clear (&skeleton->priv->lock); G_OBJECT_CLASS (gpick_single_instance_skeleton_parent_class)->finalize (object); } static void gpick_single_instance_skeleton_init (GpickSingleInstanceSkeleton *skeleton) { #if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38 skeleton->priv = gpick_single_instance_skeleton_get_instance_private (skeleton); #else skeleton->priv = G_TYPE_INSTANCE_GET_PRIVATE (skeleton, GPICK_TYPE_SINGLE_INSTANCE_SKELETON, GpickSingleInstanceSkeletonPrivate); #endif g_mutex_init (&skeleton->priv->lock); skeleton->priv->context = g_main_context_ref_thread_default (); } static void gpick_single_instance_skeleton_class_init (GpickSingleInstanceSkeletonClass *klass) { GObjectClass *gobject_class; GDBusInterfaceSkeletonClass *skeleton_class; gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = gpick_single_instance_skeleton_finalize; skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass); skeleton_class->get_info = gpick_single_instance_skeleton_dbus_interface_get_info; skeleton_class->get_properties = gpick_single_instance_skeleton_dbus_interface_get_properties; skeleton_class->flush = gpick_single_instance_skeleton_dbus_interface_flush; skeleton_class->get_vtable = gpick_single_instance_skeleton_dbus_interface_get_vtable; #if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38 g_type_class_add_private (klass, sizeof (GpickSingleInstanceSkeletonPrivate)); #endif } static void gpick_single_instance_skeleton_iface_init (GpickSingleInstanceIface *iface) { } /** * gpick_single_instance_skeleton_new: * * Creates a skeleton object for the D-Bus interface org.gpick.SingleInstance. * * Returns: (transfer full) (type GpickSingleInstanceSkeleton): The skeleton object. */ GpickSingleInstance * gpick_single_instance_skeleton_new (void) { return GPICK_SINGLE_INSTANCE (g_object_new (GPICK_TYPE_SINGLE_INSTANCE_SKELETON, NULL)); } /* ------------------------------------------------------------------------ * Code for interface org.gpick.Control * ------------------------------------------------------------------------ */ /** * SECTION:GpickControl * @title: GpickControl * @short_description: Generated C code for the org.gpick.Control D-Bus interface * * This section contains code for working with the org.gpick.Control D-Bus interface in C. */ /* ---- Introspection data for org.gpick.Control ---- */ static const _ExtendedGDBusArgInfo _gpick_control_method_info_activate_floating_picker_IN_ARG_converter_name = { { -1, (gchar *) "converter_name", (gchar *) "s", NULL }, FALSE }; static const _ExtendedGDBusArgInfo * const _gpick_control_method_info_activate_floating_picker_IN_ARG_pointers[] = { &_gpick_control_method_info_activate_floating_picker_IN_ARG_converter_name, NULL }; static const _ExtendedGDBusMethodInfo _gpick_control_method_info_activate_floating_picker = { { -1, (gchar *) "ActivateFloatingPicker", (GDBusArgInfo **) &_gpick_control_method_info_activate_floating_picker_IN_ARG_pointers, NULL, NULL }, "handle-activate-floating-picker", FALSE }; static const _ExtendedGDBusMethodInfo _gpick_control_method_info_check_if_running = { { -1, (gchar *) "CheckIfRunning", NULL, NULL, NULL }, "handle-check-if-running", FALSE }; static const _ExtendedGDBusMethodInfo * const _gpick_control_method_info_pointers[] = { &_gpick_control_method_info_activate_floating_picker, &_gpick_control_method_info_check_if_running, NULL }; static const _ExtendedGDBusInterfaceInfo _gpick_control_interface_info = { { -1, (gchar *) "org.gpick.Control", (GDBusMethodInfo **) &_gpick_control_method_info_pointers, NULL, NULL, NULL }, "control", }; /** * gpick_control_interface_info: * * Gets a machine-readable description of the org.gpick.Control D-Bus interface. * * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free. */ GDBusInterfaceInfo * gpick_control_interface_info (void) { return (GDBusInterfaceInfo *) &_gpick_control_interface_info.parent_struct; } /** * gpick_control_override_properties: * @klass: The class structure for a #GObject-derived class. * @property_id_begin: The property id to assign to the first overridden property. * * Overrides all #GObject properties in the #GpickControl interface for a concrete class. * The properties are overridden in the order they are defined. * * Returns: The last property id. */ guint gpick_control_override_properties (GObjectClass *klass, guint property_id_begin) { return property_id_begin - 1; } /** * GpickControl: * * Abstract interface type for the D-Bus interface org.gpick.Control. */ /** * GpickControlIface: * @parent_iface: The parent interface. * @handle_activate_floating_picker: Handler for the #GpickControl::handle-activate-floating-picker signal. * @handle_check_if_running: Handler for the #GpickControl::handle-check-if-running signal. * * Virtual table for the D-Bus interface org.gpick.Control. */ typedef GpickControlIface GpickControlInterface; G_DEFINE_INTERFACE (GpickControl, gpick_control, G_TYPE_OBJECT); static void gpick_control_default_init (GpickControlIface *iface) { /* GObject signals for incoming D-Bus method calls: */ /** * GpickControl::handle-activate-floating-picker: * @object: A #GpickControl. * @invocation: A #GDBusMethodInvocation. * @arg_converter_name: Argument passed by remote caller. * * Signal emitted when a remote caller is invoking the ActivateFloatingPicker() D-Bus method. * * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gpick_control_complete_activate_floating_picker() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. * * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run. */ g_signal_new ("handle-activate-floating-picker", G_TYPE_FROM_INTERFACE (iface), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GpickControlIface, handle_activate_floating_picker), g_signal_accumulator_true_handled, NULL, g_cclosure_marshal_generic, G_TYPE_BOOLEAN, 2, G_TYPE_DBUS_METHOD_INVOCATION, G_TYPE_STRING); /** * GpickControl::handle-check-if-running: * @object: A #GpickControl. * @invocation: A #GDBusMethodInvocation. * * Signal emitted when a remote caller is invoking the CheckIfRunning() D-Bus method. * * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gpick_control_complete_check_if_running() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. * * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run. */ g_signal_new ("handle-check-if-running", G_TYPE_FROM_INTERFACE (iface), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GpickControlIface, handle_check_if_running), g_signal_accumulator_true_handled, NULL, g_cclosure_marshal_generic, G_TYPE_BOOLEAN, 1, G_TYPE_DBUS_METHOD_INVOCATION); } /** * gpick_control_call_activate_floating_picker: * @proxy: A #GpickControlProxy. * @arg_converter_name: Argument to pass with the method invocation. * @cancellable: (allow-none): A #GCancellable or %NULL. * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL. * @user_data: User data to pass to @callback. * * Asynchronously invokes the ActivateFloatingPicker() D-Bus method on @proxy. * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from. * You can then call gpick_control_call_activate_floating_picker_finish() to get the result of the operation. * * See gpick_control_call_activate_floating_picker_sync() for the synchronous, blocking version of this method. */ void gpick_control_call_activate_floating_picker ( GpickControl *proxy, const gchar *arg_converter_name, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_dbus_proxy_call (G_DBUS_PROXY (proxy), "ActivateFloatingPicker", g_variant_new ("(s)", arg_converter_name), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, callback, user_data); } /** * gpick_control_call_activate_floating_picker_finish: * @proxy: A #GpickControlProxy. * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gpick_control_call_activate_floating_picker(). * @error: Return location for error or %NULL. * * Finishes an operation started with gpick_control_call_activate_floating_picker(). * * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set. */ gboolean gpick_control_call_activate_floating_picker_finish ( GpickControl *proxy, GAsyncResult *res, GError **error) { GVariant *_ret; _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error); if (_ret == NULL) goto _out; g_variant_get (_ret, "()"); g_variant_unref (_ret); _out: return _ret != NULL; } /** * gpick_control_call_activate_floating_picker_sync: * @proxy: A #GpickControlProxy. * @arg_converter_name: Argument to pass with the method invocation. * @cancellable: (allow-none): A #GCancellable or %NULL. * @error: Return location for error or %NULL. * * Synchronously invokes the ActivateFloatingPicker() D-Bus method on @proxy. The calling thread is blocked until a reply is received. * * See gpick_control_call_activate_floating_picker() for the asynchronous version of this method. * * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set. */ gboolean gpick_control_call_activate_floating_picker_sync ( GpickControl *proxy, const gchar *arg_converter_name, GCancellable *cancellable, GError **error) { GVariant *_ret; _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy), "ActivateFloatingPicker", g_variant_new ("(s)", arg_converter_name), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error); if (_ret == NULL) goto _out; g_variant_get (_ret, "()"); g_variant_unref (_ret); _out: return _ret != NULL; } /** * gpick_control_call_check_if_running: * @proxy: A #GpickControlProxy. * @cancellable: (allow-none): A #GCancellable or %NULL. * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL. * @user_data: User data to pass to @callback. * * Asynchronously invokes the CheckIfRunning() D-Bus method on @proxy. * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from. * You can then call gpick_control_call_check_if_running_finish() to get the result of the operation. * * See gpick_control_call_check_if_running_sync() for the synchronous, blocking version of this method. */ void gpick_control_call_check_if_running ( GpickControl *proxy, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_dbus_proxy_call (G_DBUS_PROXY (proxy), "CheckIfRunning", g_variant_new ("()"), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, callback, user_data); } /** * gpick_control_call_check_if_running_finish: * @proxy: A #GpickControlProxy. * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gpick_control_call_check_if_running(). * @error: Return location for error or %NULL. * * Finishes an operation started with gpick_control_call_check_if_running(). * * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set. */ gboolean gpick_control_call_check_if_running_finish ( GpickControl *proxy, GAsyncResult *res, GError **error) { GVariant *_ret; _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error); if (_ret == NULL) goto _out; g_variant_get (_ret, "()"); g_variant_unref (_ret); _out: return _ret != NULL; } /** * gpick_control_call_check_if_running_sync: * @proxy: A #GpickControlProxy. * @cancellable: (allow-none): A #GCancellable or %NULL. * @error: Return location for error or %NULL. * * Synchronously invokes the CheckIfRunning() D-Bus method on @proxy. The calling thread is blocked until a reply is received. * * See gpick_control_call_check_if_running() for the asynchronous version of this method. * * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set. */ gboolean gpick_control_call_check_if_running_sync ( GpickControl *proxy, GCancellable *cancellable, GError **error) { GVariant *_ret; _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy), "CheckIfRunning", g_variant_new ("()"), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error); if (_ret == NULL) goto _out; g_variant_get (_ret, "()"); g_variant_unref (_ret); _out: return _ret != NULL; } /** * gpick_control_complete_activate_floating_picker: * @object: A #GpickControl. * @invocation: (transfer full): A #GDBusMethodInvocation. * * Helper function used in service implementations to finish handling invocations of the ActivateFloatingPicker() D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar. * * This method will free @invocation, you cannot use it afterwards. */ void gpick_control_complete_activate_floating_picker ( GpickControl *object, GDBusMethodInvocation *invocation) { g_dbus_method_invocation_return_value (invocation, g_variant_new ("()")); } /** * gpick_control_complete_check_if_running: * @object: A #GpickControl. * @invocation: (transfer full): A #GDBusMethodInvocation. * * Helper function used in service implementations to finish handling invocations of the CheckIfRunning() D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar. * * This method will free @invocation, you cannot use it afterwards. */ void gpick_control_complete_check_if_running ( GpickControl *object, GDBusMethodInvocation *invocation) { g_dbus_method_invocation_return_value (invocation, g_variant_new ("()")); } /* ------------------------------------------------------------------------ */ /** * GpickControlProxy: * * The #GpickControlProxy structure contains only private data and should only be accessed using the provided API. */ /** * GpickControlProxyClass: * @parent_class: The parent class. * * Class structure for #GpickControlProxy. */ struct _GpickControlProxyPrivate { GData *qdata; }; static void gpick_control_proxy_iface_init (GpickControlIface *iface); #if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38 G_DEFINE_TYPE_WITH_CODE (GpickControlProxy, gpick_control_proxy, G_TYPE_DBUS_PROXY, G_ADD_PRIVATE (GpickControlProxy) G_IMPLEMENT_INTERFACE (GPICK_TYPE_CONTROL, gpick_control_proxy_iface_init)); #else G_DEFINE_TYPE_WITH_CODE (GpickControlProxy, gpick_control_proxy, G_TYPE_DBUS_PROXY, G_IMPLEMENT_INTERFACE (GPICK_TYPE_CONTROL, gpick_control_proxy_iface_init)); #endif static void gpick_control_proxy_finalize (GObject *object) { GpickControlProxy *proxy = GPICK_CONTROL_PROXY (object); g_datalist_clear (&proxy->priv->qdata); G_OBJECT_CLASS (gpick_control_proxy_parent_class)->finalize (object); } static void gpick_control_proxy_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec G_GNUC_UNUSED) { } static void gpick_control_proxy_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec G_GNUC_UNUSED) { } static void gpick_control_proxy_g_signal (GDBusProxy *proxy, const gchar *sender_name G_GNUC_UNUSED, const gchar *signal_name, GVariant *parameters) { _ExtendedGDBusSignalInfo *info; GVariantIter iter; GVariant *child; GValue *paramv; guint num_params; guint n; guint signal_id; info = (_ExtendedGDBusSignalInfo *) g_dbus_interface_info_lookup_signal ((GDBusInterfaceInfo *) &_gpick_control_interface_info.parent_struct, signal_name); if (info == NULL) return; num_params = g_variant_n_children (parameters); paramv = g_new0 (GValue, num_params + 1); g_value_init (¶mv[0], GPICK_TYPE_CONTROL); g_value_set_object (¶mv[0], proxy); g_variant_iter_init (&iter, parameters); n = 1; while ((child = g_variant_iter_next_value (&iter)) != NULL) { _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.args[n - 1]; if (arg_info->use_gvariant) { g_value_init (¶mv[n], G_TYPE_VARIANT); g_value_set_variant (¶mv[n], child); n++; } else g_dbus_gvariant_to_gvalue (child, ¶mv[n++]); g_variant_unref (child); } signal_id = g_signal_lookup (info->signal_name, GPICK_TYPE_CONTROL); g_signal_emitv (paramv, signal_id, 0, NULL); for (n = 0; n < num_params + 1; n++) g_value_unset (¶mv[n]); g_free (paramv); } static void gpick_control_proxy_g_properties_changed (GDBusProxy *_proxy, GVariant *changed_properties, const gchar *const *invalidated_properties) { GpickControlProxy *proxy = GPICK_CONTROL_PROXY (_proxy); guint n; const gchar *key; GVariantIter *iter; _ExtendedGDBusPropertyInfo *info; g_variant_get (changed_properties, "a{sv}", &iter); while (g_variant_iter_next (iter, "{&sv}", &key, NULL)) { info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gpick_control_interface_info.parent_struct, key); g_datalist_remove_data (&proxy->priv->qdata, key); if (info != NULL) g_object_notify (G_OBJECT (proxy), info->hyphen_name); } g_variant_iter_free (iter); for (n = 0; invalidated_properties[n] != NULL; n++) { info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gpick_control_interface_info.parent_struct, invalidated_properties[n]); g_datalist_remove_data (&proxy->priv->qdata, invalidated_properties[n]); if (info != NULL) g_object_notify (G_OBJECT (proxy), info->hyphen_name); } } static void gpick_control_proxy_init (GpickControlProxy *proxy) { #if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38 proxy->priv = gpick_control_proxy_get_instance_private (proxy); #else proxy->priv = G_TYPE_INSTANCE_GET_PRIVATE (proxy, GPICK_TYPE_CONTROL_PROXY, GpickControlProxyPrivate); #endif g_dbus_proxy_set_interface_info (G_DBUS_PROXY (proxy), gpick_control_interface_info ()); } static void gpick_control_proxy_class_init (GpickControlProxyClass *klass) { GObjectClass *gobject_class; GDBusProxyClass *proxy_class; gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = gpick_control_proxy_finalize; gobject_class->get_property = gpick_control_proxy_get_property; gobject_class->set_property = gpick_control_proxy_set_property; proxy_class = G_DBUS_PROXY_CLASS (klass); proxy_class->g_signal = gpick_control_proxy_g_signal; proxy_class->g_properties_changed = gpick_control_proxy_g_properties_changed; #if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38 g_type_class_add_private (klass, sizeof (GpickControlProxyPrivate)); #endif } static void gpick_control_proxy_iface_init (GpickControlIface *iface) { } /** * gpick_control_proxy_new: * @connection: A #GDBusConnection. * @flags: Flags from the #GDBusProxyFlags enumeration. * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection. * @object_path: An object path. * @cancellable: (allow-none): A #GCancellable or %NULL. * @callback: A #GAsyncReadyCallback to call when the request is satisfied. * @user_data: User data to pass to @callback. * * Asynchronously creates a proxy for the D-Bus interface org.gpick.Control. See g_dbus_proxy_new() for more details. * * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from. * You can then call gpick_control_proxy_new_finish() to get the result of the operation. * * See gpick_control_proxy_new_sync() for the synchronous, blocking version of this constructor. */ void gpick_control_proxy_new ( GDBusConnection *connection, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_async_initable_new_async (GPICK_TYPE_CONTROL_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "org.gpick.Control", NULL); } /** * gpick_control_proxy_new_finish: * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gpick_control_proxy_new(). * @error: Return location for error or %NULL * * Finishes an operation started with gpick_control_proxy_new(). * * Returns: (transfer full) (type GpickControlProxy): The constructed proxy object or %NULL if @error is set. */ GpickControl * gpick_control_proxy_new_finish ( GAsyncResult *res, GError **error) { GObject *ret; GObject *source_object; source_object = g_async_result_get_source_object (res); ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error); g_object_unref (source_object); if (ret != NULL) return GPICK_CONTROL (ret); else return NULL; } /** * gpick_control_proxy_new_sync: * @connection: A #GDBusConnection. * @flags: Flags from the #GDBusProxyFlags enumeration. * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection. * @object_path: An object path. * @cancellable: (allow-none): A #GCancellable or %NULL. * @error: Return location for error or %NULL * * Synchronously creates a proxy for the D-Bus interface org.gpick.Control. See g_dbus_proxy_new_sync() for more details. * * The calling thread is blocked until a reply is received. * * See gpick_control_proxy_new() for the asynchronous version of this constructor. * * Returns: (transfer full) (type GpickControlProxy): The constructed proxy object or %NULL if @error is set. */ GpickControl * gpick_control_proxy_new_sync ( GDBusConnection *connection, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GError **error) { GInitable *ret; ret = g_initable_new (GPICK_TYPE_CONTROL_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "org.gpick.Control", NULL); if (ret != NULL) return GPICK_CONTROL (ret); else return NULL; } /** * gpick_control_proxy_new_for_bus: * @bus_type: A #GBusType. * @flags: Flags from the #GDBusProxyFlags enumeration. * @name: A bus name (well-known or unique). * @object_path: An object path. * @cancellable: (allow-none): A #GCancellable or %NULL. * @callback: A #GAsyncReadyCallback to call when the request is satisfied. * @user_data: User data to pass to @callback. * * Like gpick_control_proxy_new() but takes a #GBusType instead of a #GDBusConnection. * * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from. * You can then call gpick_control_proxy_new_for_bus_finish() to get the result of the operation. * * See gpick_control_proxy_new_for_bus_sync() for the synchronous, blocking version of this constructor. */ void gpick_control_proxy_new_for_bus ( GBusType bus_type, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_async_initable_new_async (GPICK_TYPE_CONTROL_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "org.gpick.Control", NULL); } /** * gpick_control_proxy_new_for_bus_finish: * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gpick_control_proxy_new_for_bus(). * @error: Return location for error or %NULL * * Finishes an operation started with gpick_control_proxy_new_for_bus(). * * Returns: (transfer full) (type GpickControlProxy): The constructed proxy object or %NULL if @error is set. */ GpickControl * gpick_control_proxy_new_for_bus_finish ( GAsyncResult *res, GError **error) { GObject *ret; GObject *source_object; source_object = g_async_result_get_source_object (res); ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error); g_object_unref (source_object); if (ret != NULL) return GPICK_CONTROL (ret); else return NULL; } /** * gpick_control_proxy_new_for_bus_sync: * @bus_type: A #GBusType. * @flags: Flags from the #GDBusProxyFlags enumeration. * @name: A bus name (well-known or unique). * @object_path: An object path. * @cancellable: (allow-none): A #GCancellable or %NULL. * @error: Return location for error or %NULL * * Like gpick_control_proxy_new_sync() but takes a #GBusType instead of a #GDBusConnection. * * The calling thread is blocked until a reply is received. * * See gpick_control_proxy_new_for_bus() for the asynchronous version of this constructor. * * Returns: (transfer full) (type GpickControlProxy): The constructed proxy object or %NULL if @error is set. */ GpickControl * gpick_control_proxy_new_for_bus_sync ( GBusType bus_type, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GError **error) { GInitable *ret; ret = g_initable_new (GPICK_TYPE_CONTROL_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "org.gpick.Control", NULL); if (ret != NULL) return GPICK_CONTROL (ret); else return NULL; } /* ------------------------------------------------------------------------ */ /** * GpickControlSkeleton: * * The #GpickControlSkeleton structure contains only private data and should only be accessed using the provided API. */ /** * GpickControlSkeletonClass: * @parent_class: The parent class. * * Class structure for #GpickControlSkeleton. */ struct _GpickControlSkeletonPrivate { GValue *properties; GList *changed_properties; GSource *changed_properties_idle_source; GMainContext *context; GMutex lock; }; static void _gpick_control_skeleton_handle_method_call ( GDBusConnection *connection G_GNUC_UNUSED, const gchar *sender G_GNUC_UNUSED, const gchar *object_path G_GNUC_UNUSED, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { GpickControlSkeleton *skeleton = GPICK_CONTROL_SKELETON (user_data); _ExtendedGDBusMethodInfo *info; GVariantIter iter; GVariant *child; GValue *paramv; guint num_params; guint num_extra; guint n; guint signal_id; GValue return_value = G_VALUE_INIT; info = (_ExtendedGDBusMethodInfo *) g_dbus_method_invocation_get_method_info (invocation); g_assert (info != NULL); num_params = g_variant_n_children (parameters); num_extra = info->pass_fdlist ? 3 : 2; paramv = g_new0 (GValue, num_params + num_extra); n = 0; g_value_init (¶mv[n], GPICK_TYPE_CONTROL); g_value_set_object (¶mv[n++], skeleton); g_value_init (¶mv[n], G_TYPE_DBUS_METHOD_INVOCATION); g_value_set_object (¶mv[n++], invocation); if (info->pass_fdlist) { #ifdef G_OS_UNIX g_value_init (¶mv[n], G_TYPE_UNIX_FD_LIST); g_value_set_object (¶mv[n++], g_dbus_message_get_unix_fd_list (g_dbus_method_invocation_get_message (invocation))); #else g_assert_not_reached (); #endif } g_variant_iter_init (&iter, parameters); while ((child = g_variant_iter_next_value (&iter)) != NULL) { _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.in_args[n - num_extra]; if (arg_info->use_gvariant) { g_value_init (¶mv[n], G_TYPE_VARIANT); g_value_set_variant (¶mv[n], child); n++; } else g_dbus_gvariant_to_gvalue (child, ¶mv[n++]); g_variant_unref (child); } signal_id = g_signal_lookup (info->signal_name, GPICK_TYPE_CONTROL); g_value_init (&return_value, G_TYPE_BOOLEAN); g_signal_emitv (paramv, signal_id, 0, &return_value); if (!g_value_get_boolean (&return_value)) g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method %s is not implemented on interface %s", method_name, interface_name); g_value_unset (&return_value); for (n = 0; n < num_params + num_extra; n++) g_value_unset (¶mv[n]); g_free (paramv); } static GVariant * _gpick_control_skeleton_handle_get_property ( GDBusConnection *connection G_GNUC_UNUSED, const gchar *sender G_GNUC_UNUSED, const gchar *object_path G_GNUC_UNUSED, const gchar *interface_name G_GNUC_UNUSED, const gchar *property_name, GError **error, gpointer user_data) { GpickControlSkeleton *skeleton = GPICK_CONTROL_SKELETON (user_data); GValue value = G_VALUE_INIT; GParamSpec *pspec; _ExtendedGDBusPropertyInfo *info; GVariant *ret; ret = NULL; info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gpick_control_interface_info.parent_struct, property_name); g_assert (info != NULL); pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name); if (pspec == NULL) { g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name); } else { g_value_init (&value, pspec->value_type); g_object_get_property (G_OBJECT (skeleton), info->hyphen_name, &value); ret = g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (info->parent_struct.signature)); g_value_unset (&value); } return ret; } static gboolean _gpick_control_skeleton_handle_set_property ( GDBusConnection *connection G_GNUC_UNUSED, const gchar *sender G_GNUC_UNUSED, const gchar *object_path G_GNUC_UNUSED, const gchar *interface_name G_GNUC_UNUSED, const gchar *property_name, GVariant *variant, GError **error, gpointer user_data) { GpickControlSkeleton *skeleton = GPICK_CONTROL_SKELETON (user_data); GValue value = G_VALUE_INIT; GParamSpec *pspec; _ExtendedGDBusPropertyInfo *info; gboolean ret; ret = FALSE; info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gpick_control_interface_info.parent_struct, property_name); g_assert (info != NULL); pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name); if (pspec == NULL) { g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name); } else { if (info->use_gvariant) g_value_set_variant (&value, variant); else g_dbus_gvariant_to_gvalue (variant, &value); g_object_set_property (G_OBJECT (skeleton), info->hyphen_name, &value); g_value_unset (&value); ret = TRUE; } return ret; } static const GDBusInterfaceVTable _gpick_control_skeleton_vtable = { _gpick_control_skeleton_handle_method_call, _gpick_control_skeleton_handle_get_property, _gpick_control_skeleton_handle_set_property, {NULL} }; static GDBusInterfaceInfo * gpick_control_skeleton_dbus_interface_get_info (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED) { return gpick_control_interface_info (); } static GDBusInterfaceVTable * gpick_control_skeleton_dbus_interface_get_vtable (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED) { return (GDBusInterfaceVTable *) &_gpick_control_skeleton_vtable; } static GVariant * gpick_control_skeleton_dbus_interface_get_properties (GDBusInterfaceSkeleton *_skeleton) { GpickControlSkeleton *skeleton = GPICK_CONTROL_SKELETON (_skeleton); GVariantBuilder builder; guint n; g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); if (_gpick_control_interface_info.parent_struct.properties == NULL) goto out; for (n = 0; _gpick_control_interface_info.parent_struct.properties[n] != NULL; n++) { GDBusPropertyInfo *info = _gpick_control_interface_info.parent_struct.properties[n]; if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE) { GVariant *value; value = _gpick_control_skeleton_handle_get_property (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)), NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "org.gpick.Control", info->name, NULL, skeleton); if (value != NULL) { g_variant_take_ref (value); g_variant_builder_add (&builder, "{sv}", info->name, value); g_variant_unref (value); } } } out: return g_variant_builder_end (&builder); } static void gpick_control_skeleton_dbus_interface_flush (GDBusInterfaceSkeleton *_skeleton) { } static void gpick_control_skeleton_iface_init (GpickControlIface *iface); #if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38 G_DEFINE_TYPE_WITH_CODE (GpickControlSkeleton, gpick_control_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON, G_ADD_PRIVATE (GpickControlSkeleton) G_IMPLEMENT_INTERFACE (GPICK_TYPE_CONTROL, gpick_control_skeleton_iface_init)); #else G_DEFINE_TYPE_WITH_CODE (GpickControlSkeleton, gpick_control_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON, G_IMPLEMENT_INTERFACE (GPICK_TYPE_CONTROL, gpick_control_skeleton_iface_init)); #endif static void gpick_control_skeleton_finalize (GObject *object) { GpickControlSkeleton *skeleton = GPICK_CONTROL_SKELETON (object); g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free); if (skeleton->priv->changed_properties_idle_source != NULL) g_source_destroy (skeleton->priv->changed_properties_idle_source); g_main_context_unref (skeleton->priv->context); g_mutex_clear (&skeleton->priv->lock); G_OBJECT_CLASS (gpick_control_skeleton_parent_class)->finalize (object); } static void gpick_control_skeleton_init (GpickControlSkeleton *skeleton) { #if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38 skeleton->priv = gpick_control_skeleton_get_instance_private (skeleton); #else skeleton->priv = G_TYPE_INSTANCE_GET_PRIVATE (skeleton, GPICK_TYPE_CONTROL_SKELETON, GpickControlSkeletonPrivate); #endif g_mutex_init (&skeleton->priv->lock); skeleton->priv->context = g_main_context_ref_thread_default (); } static void gpick_control_skeleton_class_init (GpickControlSkeletonClass *klass) { GObjectClass *gobject_class; GDBusInterfaceSkeletonClass *skeleton_class; gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = gpick_control_skeleton_finalize; skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass); skeleton_class->get_info = gpick_control_skeleton_dbus_interface_get_info; skeleton_class->get_properties = gpick_control_skeleton_dbus_interface_get_properties; skeleton_class->flush = gpick_control_skeleton_dbus_interface_flush; skeleton_class->get_vtable = gpick_control_skeleton_dbus_interface_get_vtable; #if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38 g_type_class_add_private (klass, sizeof (GpickControlSkeletonPrivate)); #endif } static void gpick_control_skeleton_iface_init (GpickControlIface *iface) { } /** * gpick_control_skeleton_new: * * Creates a skeleton object for the D-Bus interface org.gpick.Control. * * Returns: (transfer full) (type GpickControlSkeleton): The skeleton object. */ GpickControl * gpick_control_skeleton_new (void) { return GPICK_CONTROL (g_object_new (GPICK_TYPE_CONTROL_SKELETON, NULL)); } /* ------------------------------------------------------------------------ * Code for Object, ObjectProxy and ObjectSkeleton * ------------------------------------------------------------------------ */ /** * SECTION:GpickObject * @title: GpickObject * @short_description: Specialized GDBusObject types * * This section contains the #GpickObject, #GpickObjectProxy, and #GpickObjectSkeleton types which make it easier to work with objects implementing generated types for D-Bus interfaces. */ /** * GpickObject: * * The #GpickObject type is a specialized container of interfaces. */ /** * GpickObjectIface: * @parent_iface: The parent interface. * * Virtual table for the #GpickObject interface. */ typedef GpickObjectIface GpickObjectInterface; G_DEFINE_INTERFACE_WITH_CODE (GpickObject, gpick_object, G_TYPE_OBJECT, g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_DBUS_OBJECT)); static void gpick_object_default_init (GpickObjectIface *iface) { /** * GpickObject:single-instance: * * The #GpickSingleInstance instance corresponding to the D-Bus interface org.gpick.SingleInstance, if any. * * Connect to the #GObject::notify signal to get informed of property changes. */ g_object_interface_install_property (iface, g_param_spec_object ("single-instance", "single-instance", "single-instance", GPICK_TYPE_SINGLE_INSTANCE, G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS)); /** * GpickObject:control: * * The #GpickControl instance corresponding to the D-Bus interface org.gpick.Control, if any. * * Connect to the #GObject::notify signal to get informed of property changes. */ g_object_interface_install_property (iface, g_param_spec_object ("control", "control", "control", GPICK_TYPE_CONTROL, G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS)); } /** * gpick_object_get_single_instance: * @object: A #GpickObject. * * Gets the #GpickSingleInstance instance for the D-Bus interface org.gpick.SingleInstance on @object, if any. * * Returns: (transfer full): A #GpickSingleInstance that must be freed with g_object_unref() or %NULL if @object does not implement the interface. */ GpickSingleInstance *gpick_object_get_single_instance (GpickObject *object) { GDBusInterface *ret; ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "org.gpick.SingleInstance"); if (ret == NULL) return NULL; return GPICK_SINGLE_INSTANCE (ret); } /** * gpick_object_get_control: * @object: A #GpickObject. * * Gets the #GpickControl instance for the D-Bus interface org.gpick.Control on @object, if any. * * Returns: (transfer full): A #GpickControl that must be freed with g_object_unref() or %NULL if @object does not implement the interface. */ GpickControl *gpick_object_get_control (GpickObject *object) { GDBusInterface *ret; ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "org.gpick.Control"); if (ret == NULL) return NULL; return GPICK_CONTROL (ret); } /** * gpick_object_peek_single_instance: (skip) * @object: A #GpickObject. * * Like gpick_object_get_single_instance() but doesn't increase the reference count on the returned object. * * It is not safe to use the returned object if you are on another thread than the one where the #GDBusObjectManagerClient or #GDBusObjectManagerServer for @object is running. * * Returns: (transfer none): A #GpickSingleInstance or %NULL if @object does not implement the interface. Do not free the returned object, it is owned by @object. */ GpickSingleInstance *gpick_object_peek_single_instance (GpickObject *object) { GDBusInterface *ret; ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "org.gpick.SingleInstance"); if (ret == NULL) return NULL; g_object_unref (ret); return GPICK_SINGLE_INSTANCE (ret); } /** * gpick_object_peek_control: (skip) * @object: A #GpickObject. * * Like gpick_object_get_control() but doesn't increase the reference count on the returned object. * * It is not safe to use the returned object if you are on another thread than the one where the #GDBusObjectManagerClient or #GDBusObjectManagerServer for @object is running. * * Returns: (transfer none): A #GpickControl or %NULL if @object does not implement the interface. Do not free the returned object, it is owned by @object. */ GpickControl *gpick_object_peek_control (GpickObject *object) { GDBusInterface *ret; ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "org.gpick.Control"); if (ret == NULL) return NULL; g_object_unref (ret); return GPICK_CONTROL (ret); } static void gpick_object_notify (GDBusObject *object, GDBusInterface *interface) { _ExtendedGDBusInterfaceInfo *info = (_ExtendedGDBusInterfaceInfo *) g_dbus_interface_get_info (interface); /* info can be NULL if the other end is using a D-Bus interface we don't know * anything about, for example old generated code in this process talking to * newer generated code in the other process. */ if (info != NULL) g_object_notify (G_OBJECT (object), info->hyphen_name); } /** * GpickObjectProxy: * * The #GpickObjectProxy structure contains only private data and should only be accessed using the provided API. */ /** * GpickObjectProxyClass: * @parent_class: The parent class. * * Class structure for #GpickObjectProxy. */ static void gpick_object_proxy__gpick_object_iface_init (GpickObjectIface *iface G_GNUC_UNUSED) { } static void gpick_object_proxy__g_dbus_object_iface_init (GDBusObjectIface *iface) { iface->interface_added = gpick_object_notify; iface->interface_removed = gpick_object_notify; } G_DEFINE_TYPE_WITH_CODE (GpickObjectProxy, gpick_object_proxy, G_TYPE_DBUS_OBJECT_PROXY, G_IMPLEMENT_INTERFACE (GPICK_TYPE_OBJECT, gpick_object_proxy__gpick_object_iface_init) G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, gpick_object_proxy__g_dbus_object_iface_init)); static void gpick_object_proxy_init (GpickObjectProxy *object G_GNUC_UNUSED) { } static void gpick_object_proxy_set_property (GObject *gobject, guint prop_id, const GValue *value G_GNUC_UNUSED, GParamSpec *pspec) { G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); } static void gpick_object_proxy_get_property (GObject *gobject, guint prop_id, GValue *value, GParamSpec *pspec) { GpickObjectProxy *object = GPICK_OBJECT_PROXY (gobject); GDBusInterface *interface; switch (prop_id) { case 1: interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "org.gpick.SingleInstance"); g_value_take_object (value, interface); break; case 2: interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "org.gpick.Control"); g_value_take_object (value, interface); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); break; } } static void gpick_object_proxy_class_init (GpickObjectProxyClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->set_property = gpick_object_proxy_set_property; gobject_class->get_property = gpick_object_proxy_get_property; g_object_class_override_property (gobject_class, 1, "single-instance"); g_object_class_override_property (gobject_class, 2, "control"); } /** * gpick_object_proxy_new: * @connection: A #GDBusConnection. * @object_path: An object path. * * Creates a new proxy object. * * Returns: (transfer full): The proxy object. */ GpickObjectProxy * gpick_object_proxy_new (GDBusConnection *connection, const gchar *object_path) { g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); return GPICK_OBJECT_PROXY (g_object_new (GPICK_TYPE_OBJECT_PROXY, "g-connection", connection, "g-object-path", object_path, NULL)); } /** * GpickObjectSkeleton: * * The #GpickObjectSkeleton structure contains only private data and should only be accessed using the provided API. */ /** * GpickObjectSkeletonClass: * @parent_class: The parent class. * * Class structure for #GpickObjectSkeleton. */ static void gpick_object_skeleton__gpick_object_iface_init (GpickObjectIface *iface G_GNUC_UNUSED) { } static void gpick_object_skeleton__g_dbus_object_iface_init (GDBusObjectIface *iface) { iface->interface_added = gpick_object_notify; iface->interface_removed = gpick_object_notify; } G_DEFINE_TYPE_WITH_CODE (GpickObjectSkeleton, gpick_object_skeleton, G_TYPE_DBUS_OBJECT_SKELETON, G_IMPLEMENT_INTERFACE (GPICK_TYPE_OBJECT, gpick_object_skeleton__gpick_object_iface_init) G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, gpick_object_skeleton__g_dbus_object_iface_init)); static void gpick_object_skeleton_init (GpickObjectSkeleton *object G_GNUC_UNUSED) { } static void gpick_object_skeleton_set_property (GObject *gobject, guint prop_id, const GValue *value, GParamSpec *pspec) { GpickObjectSkeleton *object = GPICK_OBJECT_SKELETON (gobject); GDBusInterfaceSkeleton *interface; switch (prop_id) { case 1: interface = g_value_get_object (value); if (interface != NULL) { g_warn_if_fail (GPICK_IS_SINGLE_INSTANCE (interface)); g_dbus_object_skeleton_add_interface (G_DBUS_OBJECT_SKELETON (object), interface); } else { g_dbus_object_skeleton_remove_interface_by_name (G_DBUS_OBJECT_SKELETON (object), "org.gpick.SingleInstance"); } break; case 2: interface = g_value_get_object (value); if (interface != NULL) { g_warn_if_fail (GPICK_IS_CONTROL (interface)); g_dbus_object_skeleton_add_interface (G_DBUS_OBJECT_SKELETON (object), interface); } else { g_dbus_object_skeleton_remove_interface_by_name (G_DBUS_OBJECT_SKELETON (object), "org.gpick.Control"); } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); break; } } static void gpick_object_skeleton_get_property (GObject *gobject, guint prop_id, GValue *value, GParamSpec *pspec) { GpickObjectSkeleton *object = GPICK_OBJECT_SKELETON (gobject); GDBusInterface *interface; switch (prop_id) { case 1: interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "org.gpick.SingleInstance"); g_value_take_object (value, interface); break; case 2: interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "org.gpick.Control"); g_value_take_object (value, interface); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); break; } } static void gpick_object_skeleton_class_init (GpickObjectSkeletonClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->set_property = gpick_object_skeleton_set_property; gobject_class->get_property = gpick_object_skeleton_get_property; g_object_class_override_property (gobject_class, 1, "single-instance"); g_object_class_override_property (gobject_class, 2, "control"); } /** * gpick_object_skeleton_new: * @object_path: An object path. * * Creates a new skeleton object. * * Returns: (transfer full): The skeleton object. */ GpickObjectSkeleton * gpick_object_skeleton_new (const gchar *object_path) { g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); return GPICK_OBJECT_SKELETON (g_object_new (GPICK_TYPE_OBJECT_SKELETON, "g-object-path", object_path, NULL)); } /** * gpick_object_skeleton_set_single_instance: * @object: A #GpickObjectSkeleton. * @interface_: (allow-none): A #GpickSingleInstance or %NULL to clear the interface. * * Sets the #GpickSingleInstance instance for the D-Bus interface org.gpick.SingleInstance on @object. */ void gpick_object_skeleton_set_single_instance (GpickObjectSkeleton *object, GpickSingleInstance *interface_) { g_object_set (G_OBJECT (object), "single-instance", interface_, NULL); } /** * gpick_object_skeleton_set_control: * @object: A #GpickObjectSkeleton. * @interface_: (allow-none): A #GpickControl or %NULL to clear the interface. * * Sets the #GpickControl instance for the D-Bus interface org.gpick.Control on @object. */ void gpick_object_skeleton_set_control (GpickObjectSkeleton *object, GpickControl *interface_) { g_object_set (G_OBJECT (object), "control", interface_, NULL); } /* ------------------------------------------------------------------------ * Code for ObjectManager client * ------------------------------------------------------------------------ */ /** * SECTION:GpickObjectManagerClient * @title: GpickObjectManagerClient * @short_description: Generated GDBusObjectManagerClient type * * This section contains a #GDBusObjectManagerClient that uses gpick_object_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc. */ /** * GpickObjectManagerClient: * * The #GpickObjectManagerClient structure contains only private data and should only be accessed using the provided API. */ /** * GpickObjectManagerClientClass: * @parent_class: The parent class. * * Class structure for #GpickObjectManagerClient. */ G_DEFINE_TYPE (GpickObjectManagerClient, gpick_object_manager_client, G_TYPE_DBUS_OBJECT_MANAGER_CLIENT); static void gpick_object_manager_client_init (GpickObjectManagerClient *manager G_GNUC_UNUSED) { } static void gpick_object_manager_client_class_init (GpickObjectManagerClientClass *klass G_GNUC_UNUSED) { } /** * gpick_object_manager_client_get_proxy_type: * @manager: A #GDBusObjectManagerClient. * @object_path: The object path of the remote object (unused). * @interface_name: (allow-none): Interface name of the remote object or %NULL to get the object proxy #GType. * @user_data: User data (unused). * * A #GDBusProxyTypeFunc that maps @interface_name to the generated #GDBusObjectProxy- and #GDBusProxy-derived types. * * Returns: A #GDBusProxy-derived #GType if @interface_name is not %NULL, otherwise the #GType for #GpickObjectProxy. */ GType gpick_object_manager_client_get_proxy_type (GDBusObjectManagerClient *manager G_GNUC_UNUSED, const gchar *object_path G_GNUC_UNUSED, const gchar *interface_name, gpointer user_data G_GNUC_UNUSED) { static gsize once_init_value = 0; static GHashTable *lookup_hash; GType ret; if (interface_name == NULL) return GPICK_TYPE_OBJECT_PROXY; if (g_once_init_enter (&once_init_value)) { lookup_hash = g_hash_table_new (g_str_hash, g_str_equal); g_hash_table_insert (lookup_hash, (gpointer) "org.gpick.SingleInstance", GSIZE_TO_POINTER (GPICK_TYPE_SINGLE_INSTANCE_PROXY)); g_hash_table_insert (lookup_hash, (gpointer) "org.gpick.Control", GSIZE_TO_POINTER (GPICK_TYPE_CONTROL_PROXY)); g_once_init_leave (&once_init_value, 1); } ret = (GType) GPOINTER_TO_SIZE (g_hash_table_lookup (lookup_hash, interface_name)); if (ret == (GType) 0) ret = G_TYPE_DBUS_PROXY; return ret; } /** * gpick_object_manager_client_new: * @connection: A #GDBusConnection. * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration. * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection. * @object_path: An object path. * @cancellable: (allow-none): A #GCancellable or %NULL. * @callback: A #GAsyncReadyCallback to call when the request is satisfied. * @user_data: User data to pass to @callback. * * Asynchronously creates #GDBusObjectManagerClient using gpick_object_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc. See g_dbus_object_manager_client_new() for more details. * * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from. * You can then call gpick_object_manager_client_new_finish() to get the result of the operation. * * See gpick_object_manager_client_new_sync() for the synchronous, blocking version of this constructor. */ void gpick_object_manager_client_new ( GDBusConnection *connection, GDBusObjectManagerClientFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_async_initable_new_async (GPICK_TYPE_OBJECT_MANAGER_CLIENT, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "flags", flags, "name", name, "connection", connection, "object-path", object_path, "get-proxy-type-func", gpick_object_manager_client_get_proxy_type, NULL); } /** * gpick_object_manager_client_new_finish: * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gpick_object_manager_client_new(). * @error: Return location for error or %NULL * * Finishes an operation started with gpick_object_manager_client_new(). * * Returns: (transfer full) (type GpickObjectManagerClient): The constructed object manager client or %NULL if @error is set. */ GDBusObjectManager * gpick_object_manager_client_new_finish ( GAsyncResult *res, GError **error) { GObject *ret; GObject *source_object; source_object = g_async_result_get_source_object (res); ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error); g_object_unref (source_object); if (ret != NULL) return G_DBUS_OBJECT_MANAGER (ret); else return NULL; } /** * gpick_object_manager_client_new_sync: * @connection: A #GDBusConnection. * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration. * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection. * @object_path: An object path. * @cancellable: (allow-none): A #GCancellable or %NULL. * @error: Return location for error or %NULL * * Synchronously creates #GDBusObjectManagerClient using gpick_object_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc. See g_dbus_object_manager_client_new_sync() for more details. * * The calling thread is blocked until a reply is received. * * See gpick_object_manager_client_new() for the asynchronous version of this constructor. * * Returns: (transfer full) (type GpickObjectManagerClient): The constructed object manager client or %NULL if @error is set. */ GDBusObjectManager * gpick_object_manager_client_new_sync ( GDBusConnection *connection, GDBusObjectManagerClientFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GError **error) { GInitable *ret; ret = g_initable_new (GPICK_TYPE_OBJECT_MANAGER_CLIENT, cancellable, error, "flags", flags, "name", name, "connection", connection, "object-path", object_path, "get-proxy-type-func", gpick_object_manager_client_get_proxy_type, NULL); if (ret != NULL) return G_DBUS_OBJECT_MANAGER (ret); else return NULL; } /** * gpick_object_manager_client_new_for_bus: * @bus_type: A #GBusType. * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration. * @name: A bus name (well-known or unique). * @object_path: An object path. * @cancellable: (allow-none): A #GCancellable or %NULL. * @callback: A #GAsyncReadyCallback to call when the request is satisfied. * @user_data: User data to pass to @callback. * * Like gpick_object_manager_client_new() but takes a #GBusType instead of a #GDBusConnection. * * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from. * You can then call gpick_object_manager_client_new_for_bus_finish() to get the result of the operation. * * See gpick_object_manager_client_new_for_bus_sync() for the synchronous, blocking version of this constructor. */ void gpick_object_manager_client_new_for_bus ( GBusType bus_type, GDBusObjectManagerClientFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_async_initable_new_async (GPICK_TYPE_OBJECT_MANAGER_CLIENT, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "flags", flags, "name", name, "bus-type", bus_type, "object-path", object_path, "get-proxy-type-func", gpick_object_manager_client_get_proxy_type, NULL); } /** * gpick_object_manager_client_new_for_bus_finish: * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gpick_object_manager_client_new_for_bus(). * @error: Return location for error or %NULL * * Finishes an operation started with gpick_object_manager_client_new_for_bus(). * * Returns: (transfer full) (type GpickObjectManagerClient): The constructed object manager client or %NULL if @error is set. */ GDBusObjectManager * gpick_object_manager_client_new_for_bus_finish ( GAsyncResult *res, GError **error) { GObject *ret; GObject *source_object; source_object = g_async_result_get_source_object (res); ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error); g_object_unref (source_object); if (ret != NULL) return G_DBUS_OBJECT_MANAGER (ret); else return NULL; } /** * gpick_object_manager_client_new_for_bus_sync: * @bus_type: A #GBusType. * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration. * @name: A bus name (well-known or unique). * @object_path: An object path. * @cancellable: (allow-none): A #GCancellable or %NULL. * @error: Return location for error or %NULL * * Like gpick_object_manager_client_new_sync() but takes a #GBusType instead of a #GDBusConnection. * * The calling thread is blocked until a reply is received. * * See gpick_object_manager_client_new_for_bus() for the asynchronous version of this constructor. * * Returns: (transfer full) (type GpickObjectManagerClient): The constructed object manager client or %NULL if @error is set. */ GDBusObjectManager * gpick_object_manager_client_new_for_bus_sync ( GBusType bus_type, GDBusObjectManagerClientFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GError **error) { GInitable *ret; ret = g_initable_new (GPICK_TYPE_OBJECT_MANAGER_CLIENT, cancellable, error, "flags", flags, "name", name, "bus-type", bus_type, "object-path", object_path, "get-proxy-type-func", gpick_object_manager_client_get_proxy_type, NULL); if (ret != NULL) return G_DBUS_OBJECT_MANAGER (ret); else return NULL; } gpick-gpick-0.2.6/source/dbus/DbusInterface.h000066400000000000000000000451041377073231300210450ustar00rootroot00000000000000/* * Generated by gdbus-codegen 2.48.0. DO NOT EDIT. * * The license of this code is the same as for the source it was derived from. */ #ifndef __DBUSINTERFACE_H__ #define __DBUSINTERFACE_H__ #include G_BEGIN_DECLS /* ------------------------------------------------------------------------ */ /* Declarations for org.gpick.SingleInstance */ #define GPICK_TYPE_SINGLE_INSTANCE (gpick_single_instance_get_type ()) #define GPICK_SINGLE_INSTANCE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPICK_TYPE_SINGLE_INSTANCE, GpickSingleInstance)) #define GPICK_IS_SINGLE_INSTANCE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPICK_TYPE_SINGLE_INSTANCE)) #define GPICK_SINGLE_INSTANCE_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), GPICK_TYPE_SINGLE_INSTANCE, GpickSingleInstanceIface)) struct _GpickSingleInstance; typedef struct _GpickSingleInstance GpickSingleInstance; typedef struct _GpickSingleInstanceIface GpickSingleInstanceIface; struct _GpickSingleInstanceIface { GTypeInterface parent_iface; gboolean (*handle_activate) ( GpickSingleInstance *object, GDBusMethodInvocation *invocation); }; GType gpick_single_instance_get_type (void) G_GNUC_CONST; GDBusInterfaceInfo *gpick_single_instance_interface_info (void); guint gpick_single_instance_override_properties (GObjectClass *klass, guint property_id_begin); /* D-Bus method call completion functions: */ void gpick_single_instance_complete_activate ( GpickSingleInstance *object, GDBusMethodInvocation *invocation); /* D-Bus method calls: */ void gpick_single_instance_call_activate ( GpickSingleInstance *proxy, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); gboolean gpick_single_instance_call_activate_finish ( GpickSingleInstance *proxy, GAsyncResult *res, GError **error); gboolean gpick_single_instance_call_activate_sync ( GpickSingleInstance *proxy, GCancellable *cancellable, GError **error); /* ---- */ #define GPICK_TYPE_SINGLE_INSTANCE_PROXY (gpick_single_instance_proxy_get_type ()) #define GPICK_SINGLE_INSTANCE_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPICK_TYPE_SINGLE_INSTANCE_PROXY, GpickSingleInstanceProxy)) #define GPICK_SINGLE_INSTANCE_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GPICK_TYPE_SINGLE_INSTANCE_PROXY, GpickSingleInstanceProxyClass)) #define GPICK_SINGLE_INSTANCE_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPICK_TYPE_SINGLE_INSTANCE_PROXY, GpickSingleInstanceProxyClass)) #define GPICK_IS_SINGLE_INSTANCE_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPICK_TYPE_SINGLE_INSTANCE_PROXY)) #define GPICK_IS_SINGLE_INSTANCE_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPICK_TYPE_SINGLE_INSTANCE_PROXY)) typedef struct _GpickSingleInstanceProxy GpickSingleInstanceProxy; typedef struct _GpickSingleInstanceProxyClass GpickSingleInstanceProxyClass; typedef struct _GpickSingleInstanceProxyPrivate GpickSingleInstanceProxyPrivate; struct _GpickSingleInstanceProxy { /*< private >*/ GDBusProxy parent_instance; GpickSingleInstanceProxyPrivate *priv; }; struct _GpickSingleInstanceProxyClass { GDBusProxyClass parent_class; }; GType gpick_single_instance_proxy_get_type (void) G_GNUC_CONST; #if GLIB_CHECK_VERSION(2, 44, 0) G_DEFINE_AUTOPTR_CLEANUP_FUNC (GpickSingleInstanceProxy, g_object_unref) #endif void gpick_single_instance_proxy_new ( GDBusConnection *connection, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); GpickSingleInstance *gpick_single_instance_proxy_new_finish ( GAsyncResult *res, GError **error); GpickSingleInstance *gpick_single_instance_proxy_new_sync ( GDBusConnection *connection, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GError **error); void gpick_single_instance_proxy_new_for_bus ( GBusType bus_type, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); GpickSingleInstance *gpick_single_instance_proxy_new_for_bus_finish ( GAsyncResult *res, GError **error); GpickSingleInstance *gpick_single_instance_proxy_new_for_bus_sync ( GBusType bus_type, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GError **error); /* ---- */ #define GPICK_TYPE_SINGLE_INSTANCE_SKELETON (gpick_single_instance_skeleton_get_type ()) #define GPICK_SINGLE_INSTANCE_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPICK_TYPE_SINGLE_INSTANCE_SKELETON, GpickSingleInstanceSkeleton)) #define GPICK_SINGLE_INSTANCE_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GPICK_TYPE_SINGLE_INSTANCE_SKELETON, GpickSingleInstanceSkeletonClass)) #define GPICK_SINGLE_INSTANCE_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPICK_TYPE_SINGLE_INSTANCE_SKELETON, GpickSingleInstanceSkeletonClass)) #define GPICK_IS_SINGLE_INSTANCE_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPICK_TYPE_SINGLE_INSTANCE_SKELETON)) #define GPICK_IS_SINGLE_INSTANCE_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPICK_TYPE_SINGLE_INSTANCE_SKELETON)) typedef struct _GpickSingleInstanceSkeleton GpickSingleInstanceSkeleton; typedef struct _GpickSingleInstanceSkeletonClass GpickSingleInstanceSkeletonClass; typedef struct _GpickSingleInstanceSkeletonPrivate GpickSingleInstanceSkeletonPrivate; struct _GpickSingleInstanceSkeleton { /*< private >*/ GDBusInterfaceSkeleton parent_instance; GpickSingleInstanceSkeletonPrivate *priv; }; struct _GpickSingleInstanceSkeletonClass { GDBusInterfaceSkeletonClass parent_class; }; GType gpick_single_instance_skeleton_get_type (void) G_GNUC_CONST; #if GLIB_CHECK_VERSION(2, 44, 0) G_DEFINE_AUTOPTR_CLEANUP_FUNC (GpickSingleInstanceSkeleton, g_object_unref) #endif GpickSingleInstance *gpick_single_instance_skeleton_new (void); /* ------------------------------------------------------------------------ */ /* Declarations for org.gpick.Control */ #define GPICK_TYPE_CONTROL (gpick_control_get_type ()) #define GPICK_CONTROL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPICK_TYPE_CONTROL, GpickControl)) #define GPICK_IS_CONTROL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPICK_TYPE_CONTROL)) #define GPICK_CONTROL_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), GPICK_TYPE_CONTROL, GpickControlIface)) struct _GpickControl; typedef struct _GpickControl GpickControl; typedef struct _GpickControlIface GpickControlIface; struct _GpickControlIface { GTypeInterface parent_iface; gboolean (*handle_activate_floating_picker) ( GpickControl *object, GDBusMethodInvocation *invocation, const gchar *arg_converter_name); gboolean (*handle_check_if_running) ( GpickControl *object, GDBusMethodInvocation *invocation); }; GType gpick_control_get_type (void) G_GNUC_CONST; GDBusInterfaceInfo *gpick_control_interface_info (void); guint gpick_control_override_properties (GObjectClass *klass, guint property_id_begin); /* D-Bus method call completion functions: */ void gpick_control_complete_activate_floating_picker ( GpickControl *object, GDBusMethodInvocation *invocation); void gpick_control_complete_check_if_running ( GpickControl *object, GDBusMethodInvocation *invocation); /* D-Bus method calls: */ void gpick_control_call_activate_floating_picker ( GpickControl *proxy, const gchar *arg_converter_name, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); gboolean gpick_control_call_activate_floating_picker_finish ( GpickControl *proxy, GAsyncResult *res, GError **error); gboolean gpick_control_call_activate_floating_picker_sync ( GpickControl *proxy, const gchar *arg_converter_name, GCancellable *cancellable, GError **error); void gpick_control_call_check_if_running ( GpickControl *proxy, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); gboolean gpick_control_call_check_if_running_finish ( GpickControl *proxy, GAsyncResult *res, GError **error); gboolean gpick_control_call_check_if_running_sync ( GpickControl *proxy, GCancellable *cancellable, GError **error); /* ---- */ #define GPICK_TYPE_CONTROL_PROXY (gpick_control_proxy_get_type ()) #define GPICK_CONTROL_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPICK_TYPE_CONTROL_PROXY, GpickControlProxy)) #define GPICK_CONTROL_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GPICK_TYPE_CONTROL_PROXY, GpickControlProxyClass)) #define GPICK_CONTROL_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPICK_TYPE_CONTROL_PROXY, GpickControlProxyClass)) #define GPICK_IS_CONTROL_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPICK_TYPE_CONTROL_PROXY)) #define GPICK_IS_CONTROL_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPICK_TYPE_CONTROL_PROXY)) typedef struct _GpickControlProxy GpickControlProxy; typedef struct _GpickControlProxyClass GpickControlProxyClass; typedef struct _GpickControlProxyPrivate GpickControlProxyPrivate; struct _GpickControlProxy { /*< private >*/ GDBusProxy parent_instance; GpickControlProxyPrivate *priv; }; struct _GpickControlProxyClass { GDBusProxyClass parent_class; }; GType gpick_control_proxy_get_type (void) G_GNUC_CONST; #if GLIB_CHECK_VERSION(2, 44, 0) G_DEFINE_AUTOPTR_CLEANUP_FUNC (GpickControlProxy, g_object_unref) #endif void gpick_control_proxy_new ( GDBusConnection *connection, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); GpickControl *gpick_control_proxy_new_finish ( GAsyncResult *res, GError **error); GpickControl *gpick_control_proxy_new_sync ( GDBusConnection *connection, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GError **error); void gpick_control_proxy_new_for_bus ( GBusType bus_type, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); GpickControl *gpick_control_proxy_new_for_bus_finish ( GAsyncResult *res, GError **error); GpickControl *gpick_control_proxy_new_for_bus_sync ( GBusType bus_type, GDBusProxyFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GError **error); /* ---- */ #define GPICK_TYPE_CONTROL_SKELETON (gpick_control_skeleton_get_type ()) #define GPICK_CONTROL_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPICK_TYPE_CONTROL_SKELETON, GpickControlSkeleton)) #define GPICK_CONTROL_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GPICK_TYPE_CONTROL_SKELETON, GpickControlSkeletonClass)) #define GPICK_CONTROL_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPICK_TYPE_CONTROL_SKELETON, GpickControlSkeletonClass)) #define GPICK_IS_CONTROL_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPICK_TYPE_CONTROL_SKELETON)) #define GPICK_IS_CONTROL_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPICK_TYPE_CONTROL_SKELETON)) typedef struct _GpickControlSkeleton GpickControlSkeleton; typedef struct _GpickControlSkeletonClass GpickControlSkeletonClass; typedef struct _GpickControlSkeletonPrivate GpickControlSkeletonPrivate; struct _GpickControlSkeleton { /*< private >*/ GDBusInterfaceSkeleton parent_instance; GpickControlSkeletonPrivate *priv; }; struct _GpickControlSkeletonClass { GDBusInterfaceSkeletonClass parent_class; }; GType gpick_control_skeleton_get_type (void) G_GNUC_CONST; #if GLIB_CHECK_VERSION(2, 44, 0) G_DEFINE_AUTOPTR_CLEANUP_FUNC (GpickControlSkeleton, g_object_unref) #endif GpickControl *gpick_control_skeleton_new (void); /* ---- */ #define GPICK_TYPE_OBJECT (gpick_object_get_type ()) #define GPICK_OBJECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPICK_TYPE_OBJECT, GpickObject)) #define GPICK_IS_OBJECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPICK_TYPE_OBJECT)) #define GPICK_OBJECT_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), GPICK_TYPE_OBJECT, GpickObject)) struct _GpickObject; typedef struct _GpickObject GpickObject; typedef struct _GpickObjectIface GpickObjectIface; struct _GpickObjectIface { GTypeInterface parent_iface; }; GType gpick_object_get_type (void) G_GNUC_CONST; GpickSingleInstance *gpick_object_get_single_instance (GpickObject *object); GpickControl *gpick_object_get_control (GpickObject *object); GpickSingleInstance *gpick_object_peek_single_instance (GpickObject *object); GpickControl *gpick_object_peek_control (GpickObject *object); #define GPICK_TYPE_OBJECT_PROXY (gpick_object_proxy_get_type ()) #define GPICK_OBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPICK_TYPE_OBJECT_PROXY, GpickObjectProxy)) #define GPICK_OBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GPICK_TYPE_OBJECT_PROXY, GpickObjectProxyClass)) #define GPICK_OBJECT_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPICK_TYPE_OBJECT_PROXY, GpickObjectProxyClass)) #define GPICK_IS_OBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPICK_TYPE_OBJECT_PROXY)) #define GPICK_IS_OBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPICK_TYPE_OBJECT_PROXY)) typedef struct _GpickObjectProxy GpickObjectProxy; typedef struct _GpickObjectProxyClass GpickObjectProxyClass; typedef struct _GpickObjectProxyPrivate GpickObjectProxyPrivate; struct _GpickObjectProxy { /*< private >*/ GDBusObjectProxy parent_instance; GpickObjectProxyPrivate *priv; }; struct _GpickObjectProxyClass { GDBusObjectProxyClass parent_class; }; GType gpick_object_proxy_get_type (void) G_GNUC_CONST; #if GLIB_CHECK_VERSION(2, 44, 0) G_DEFINE_AUTOPTR_CLEANUP_FUNC (GpickObjectProxy, g_object_unref) #endif GpickObjectProxy *gpick_object_proxy_new (GDBusConnection *connection, const gchar *object_path); #define GPICK_TYPE_OBJECT_SKELETON (gpick_object_skeleton_get_type ()) #define GPICK_OBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPICK_TYPE_OBJECT_SKELETON, GpickObjectSkeleton)) #define GPICK_OBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GPICK_TYPE_OBJECT_SKELETON, GpickObjectSkeletonClass)) #define GPICK_OBJECT_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPICK_TYPE_OBJECT_SKELETON, GpickObjectSkeletonClass)) #define GPICK_IS_OBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPICK_TYPE_OBJECT_SKELETON)) #define GPICK_IS_OBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPICK_TYPE_OBJECT_SKELETON)) typedef struct _GpickObjectSkeleton GpickObjectSkeleton; typedef struct _GpickObjectSkeletonClass GpickObjectSkeletonClass; typedef struct _GpickObjectSkeletonPrivate GpickObjectSkeletonPrivate; struct _GpickObjectSkeleton { /*< private >*/ GDBusObjectSkeleton parent_instance; GpickObjectSkeletonPrivate *priv; }; struct _GpickObjectSkeletonClass { GDBusObjectSkeletonClass parent_class; }; GType gpick_object_skeleton_get_type (void) G_GNUC_CONST; #if GLIB_CHECK_VERSION(2, 44, 0) G_DEFINE_AUTOPTR_CLEANUP_FUNC (GpickObjectSkeleton, g_object_unref) #endif GpickObjectSkeleton *gpick_object_skeleton_new (const gchar *object_path); void gpick_object_skeleton_set_single_instance (GpickObjectSkeleton *object, GpickSingleInstance *interface_); void gpick_object_skeleton_set_control (GpickObjectSkeleton *object, GpickControl *interface_); /* ---- */ #define GPICK_TYPE_OBJECT_MANAGER_CLIENT (gpick_object_manager_client_get_type ()) #define GPICK_OBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPICK_TYPE_OBJECT_MANAGER_CLIENT, GpickObjectManagerClient)) #define GPICK_OBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GPICK_TYPE_OBJECT_MANAGER_CLIENT, GpickObjectManagerClientClass)) #define GPICK_OBJECT_MANAGER_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPICK_TYPE_OBJECT_MANAGER_CLIENT, GpickObjectManagerClientClass)) #define GPICK_IS_OBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPICK_TYPE_OBJECT_MANAGER_CLIENT)) #define GPICK_IS_OBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPICK_TYPE_OBJECT_MANAGER_CLIENT)) typedef struct _GpickObjectManagerClient GpickObjectManagerClient; typedef struct _GpickObjectManagerClientClass GpickObjectManagerClientClass; typedef struct _GpickObjectManagerClientPrivate GpickObjectManagerClientPrivate; struct _GpickObjectManagerClient { /*< private >*/ GDBusObjectManagerClient parent_instance; GpickObjectManagerClientPrivate *priv; }; struct _GpickObjectManagerClientClass { GDBusObjectManagerClientClass parent_class; }; #if GLIB_CHECK_VERSION(2, 44, 0) G_DEFINE_AUTOPTR_CLEANUP_FUNC (GpickObjectManagerClient, g_object_unref) #endif GType gpick_object_manager_client_get_type (void) G_GNUC_CONST; GType gpick_object_manager_client_get_proxy_type (GDBusObjectManagerClient *manager, const gchar *object_path, const gchar *interface_name, gpointer user_data); void gpick_object_manager_client_new ( GDBusConnection *connection, GDBusObjectManagerClientFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); GDBusObjectManager *gpick_object_manager_client_new_finish ( GAsyncResult *res, GError **error); GDBusObjectManager *gpick_object_manager_client_new_sync ( GDBusConnection *connection, GDBusObjectManagerClientFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GError **error); void gpick_object_manager_client_new_for_bus ( GBusType bus_type, GDBusObjectManagerClientFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); GDBusObjectManager *gpick_object_manager_client_new_for_bus_finish ( GAsyncResult *res, GError **error); GDBusObjectManager *gpick_object_manager_client_new_for_bus_sync ( GBusType bus_type, GDBusObjectManagerClientFlags flags, const gchar *name, const gchar *object_path, GCancellable *cancellable, GError **error); G_END_DECLS #endif /* __DBUSINTERFACE_H__ */ gpick-gpick-0.2.6/source/dbus/interface.xml000066400000000000000000000006021377073231300206320ustar00rootroot00000000000000 gpick-gpick-0.2.6/source/dynv/000077500000000000000000000000001377073231300161755ustar00rootroot00000000000000gpick-gpick-0.2.6/source/dynv/Binary.cpp000066400000000000000000000110771377073231300201330ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Binary.h" #include "Map.h" #include "Types.h" #include "Variable.h" namespace dynv { namespace binary { using ValueType = types::ValueType; struct SerializeVisitor: public boost::static_visitor { SerializeVisitor(std::ostream &stream, const std::string &name, const std::unordered_map &typeMap): stream(stream), name(name), typeMap(typeMap) { } template bool operator()(const T &value) const { using namespace types::binary; auto i = typeMap.find(dynv::types::typeHandler().type); if (i == typeMap.end()) return true; if (!write(stream, i->second)) return false; if (!write(stream, name)) return false; if (!write(stream, value)) return false; return true; } bool operator()(const Ref &value) const { return true; // skip unsupported value type for binary serialization } template bool operator()(const std::vector &values) const { return true; // skip unsupported value type for binary serialization } std::ostream &stream; const std::string &name; const std::unordered_map &typeMap; }; bool serialize(std::ostream &stream, const Map &map, const std::unordered_map &typeMap, bool firstLevel) { using namespace types::binary; if (!write(stream, static_cast(map.size()))) return false; auto visitor = [&stream, &typeMap](const Variable &value) -> bool { if (!boost::apply_visitor(SerializeVisitor(stream, value.name(), typeMap), value.data())) return false; return true; }; if (!map.visit(visitor)) return false; return true; } bool deserialize(std::istream &stream, Map &map, const std::unordered_map &typeMap) { using namespace types::binary; uint32_t count = read(stream); if (!stream.good()) return false; for (uint32_t i = 0; i < count; i++) { uint8_t handlerId = read(stream); if (!stream.good()) return false; std::string name = read(stream); if (!stream.good()) return false; auto type = typeMap.find(handlerId); if (type == typeMap.end()) { auto skip = read(stream); if (!stream.good()) return false; stream.seekg(skip, std::ios::cur); continue; } switch (type->second) { case ValueType::basicBool: { auto value = read(stream); if (!stream.good()) return false; map.set(name, value); } break; case ValueType::basicFloat: { auto value = read(stream); if (!stream.good()) return false; map.set(name, value); } break; case ValueType::basicInt32: { auto value = read(stream); if (!stream.good()) return false; map.set(name, value); } break; case ValueType::string: { auto value = read(stream); if (!stream.good()) return false; map.set(name, value); } break; case ValueType::color: { auto value = read(stream); if (!stream.good()) return false; map.set(name, value); } break; case ValueType::map: case ValueType::unknown: return false; } } return true; } } } gpick-gpick-0.2.6/source/dynv/Binary.h000066400000000000000000000037561377073231300176050ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_DYNV_BINARY_H_ #define GPICK_DYNV_BINARY_H_ #include "Types.h" #include #include #include namespace dynv { struct Map; namespace binary { bool serialize(std::ostream &stream, const Map &map, const std::unordered_map &typeMap, bool firstLevel = true); bool deserialize(std::istream &stream, Map &map, const std::unordered_map &typeMap); } } #endif /* GPICK_DYNV_BINARY_H_ */ gpick-gpick-0.2.6/source/dynv/Map.cpp000066400000000000000000000371131377073231300174230ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Map.h" #include "Variable.h" #include "Xml.h" #include "Binary.h" #include "Types.h" #include #include #include #include namespace dynv { template::value, int> = 0> auto get(const Map &map, const std::string &name, T defaultValue) { bool valid; std::string fieldName; auto &values = map.valuesForPath(name, valid, fieldName); if (!valid) return defaultValue; auto i = values.find(fieldName); if (i == values.end()) return defaultValue; auto &data = (*i)->data(); if (data.type() != typeid(T)) return defaultValue; return boost::get(data); } template::value, int> = 0> auto get(const Map &map, const std::string &name, const T &defaultValue) { bool valid; std::string fieldName; auto &values = map.valuesForPath(name, valid, fieldName); if (!valid) return defaultValue; auto i = values.find(fieldName); if (i == values.end()) return defaultValue; auto &data = (*i)->data(); if (data.type() != typeid(T)) return defaultValue; return boost::get(data); } template auto get(const Map &map, const std::string &name) { bool valid; std::string fieldName; auto &values = map.valuesForPath(name, valid, fieldName); if (!valid) return T(); auto i = values.find(fieldName); if (i == values.end()) return T(); auto &data = (*i)->data(); if (data.type() != typeid(T)) return T(); return boost::get(data); } template auto getVector(const Map &map, const std::string &name) { bool valid; std::string fieldName; auto &values = map.valuesForPath(name, valid, fieldName); if (!valid) return std::vector(); auto i = values.find(fieldName); if (i == values.end()) return std::vector(); auto &data = (*i)->data(); if (data.type() != typeid(std::vector)) { if (data.type() != typeid(T)) // try to fallback to non-vector type return std::vector(); return std::vector { boost::get(data) }; } return boost::get>(data); } bool Map::getBool(const std::string &name, bool defaultValue) const { return get(*this, name, defaultValue); } float Map::getFloat(const std::string &name, float defaultValue) const { return get(*this, name, defaultValue); } int32_t Map::getInt32(const std::string &name, int32_t defaultValue) const { return get(*this, name, defaultValue); } Color Map::getColor(const std::string &name, Color defaultValue) const { return get(*this, name, defaultValue); } std::string Map::getString(const std::string &name, const std::string &defaultValue) const { return get(*this, name, defaultValue); } std::vector Map::getBools(const std::string &name) const { return getVector(*this, name); } std::vector Map::getFloats(const std::string &name) const { return getVector(*this, name); } std::vector Map::getInt32s(const std::string &name) const { return getVector(*this, name); } std::vector Map::getColors(const std::string &name) const { return getVector(*this, name); } std::vector Map::getStrings(const std::string &name) const { return getVector(*this, name); } Ref Map::getMap(const std::string &name) { return get(*this, name); } Ref Map::getOrCreateMap(const std::string &name) { bool valid; std::string fieldName; auto &values = valuesForPath(name, valid, fieldName, true); if (!valid) return Ref(); auto i = values.find(fieldName); if (i == values.end()) { Ref result; values.emplace(new Variable(fieldName, (result = create()))); return result; } auto &data = (*i)->data(); if (data.type() != typeid(Ref)) { Ref result; (*i)->assign((result = create())); return result; } return boost::get(data); } const Ref Map::getMap(const std::string &name) const { return get(*this, name); } std::vector Map::getMaps(const std::string &name) { bool valid; std::string fieldName; auto &values = valuesForPath(name, valid, fieldName, true); if (!valid) return std::vector(); auto i = values.find(fieldName); if (i == values.end()) return std::vector(); auto &data = (*i)->data(); if (data.type() != typeid(std::vector)) { if (data.type() != typeid(Ref)) // try to fallback to non-vector type return std::vector(); auto result = std::vector(); result.emplace_back(boost::get(data)); return result; } return boost::get>(data); } std::vector Map::getMaps(const std::string &name) const { bool valid; std::string fieldName; auto &values = valuesForPath(name, valid, fieldName); if (!valid) return std::vector(); auto i = values.find(fieldName); if (i == values.end()) return std::vector(); auto &data = (*i)->data(); if (data.type() != typeid(std::vector)) { if (data.type() != typeid(Ref)) // try to fallback to non-vector type return std::vector(); auto result = std::vector(); result.emplace_back(boost::get(data)); return result; } return boost::get>(data); } struct IsMap: public boost::static_visitor { template bool operator()(const T &) const { return false; } bool operator()(const Ref &value) const { return true; } }; const Map::Set &Map::valuesForPath(const std::string &path, bool &valid, std::string &name) const { size_t position = path.find('.'); if (position == std::string::npos) { name = path; valid = true; return m_values; } size_t from = 0; auto pathPart = path.substr(from, position); Ref next; auto i = m_values.find(pathPart); if (i == m_values.end()) { valid = false; return m_values; } else { if (!boost::apply_visitor(IsMap(), (*i)->data())) { valid = false; return m_values; } next = boost::get((*i)->data()); if (!next) { valid = false; return m_values; } } for (;;) { from = position + 1; position = path.find('.', from); if (position == std::string::npos) { name = path.substr(from); valid = true; return next->m_values; } pathPart = path.substr(from, position - from); i = next->m_values.find(pathPart); if (i == next->m_values.end()) { valid = false; return m_values; } else { if (!boost::apply_visitor(IsMap(), (*i)->data())) { valid = false; return m_values; } next = boost::get((*i)->data()); if (!next) { valid = false; return m_values; } } } } Map::Set &Map::valuesForPath(const std::string &path, bool &valid, std::string &name, bool createMissing) { size_t position = path.find('.'); if (position == std::string::npos) { name = path; valid = true; return m_values; } size_t from = 0; auto pathPart = path.substr(from, position); Ref next; auto i = m_values.find(pathPart); if (i == m_values.end()) { if (!createMissing) { valid = false; return m_values; } m_values.emplace(new Variable(pathPart, (next = create()))); } else { if (!boost::apply_visitor(IsMap(), (*i)->data())) { valid = false; return m_values; } next = boost::get((*i)->data()); if (!next) { if (!createMissing) { valid = false; return m_values; } m_values.emplace(new Variable(pathPart, (next = create()))); } } for (;;) { from = position + 1; position = path.find('.', from); if (position == std::string::npos) { name = path.substr(from); valid = true; return next->m_values; } pathPart = path.substr(from, position - from); i = next->m_values.find(pathPart); if (i == next->m_values.end()) { if (!createMissing) { valid = false; return m_values; } next->m_values.emplace(new Variable(pathPart, (next = create()))); } else { if (!boost::apply_visitor(IsMap(), (*i)->data())) { valid = false; return m_values; } next = boost::get((*i)->data()); if (!next) { if (!createMissing) { valid = false; return m_values; } next->m_values.emplace(new Variable(pathPart, (next = create()))); } } } } template Map &setByPath(Map &map, const std::string &name, T value) { bool valid; std::string fieldName; auto &values = map.valuesForPath(name, valid, fieldName, true); if (valid) { auto i = values.find(fieldName); if (i == values.end()) values.emplace(new Variable(fieldName, value)); else { (*i)->assign(value); } } return map; } template Map &setByPath(Map &map, const std::string &name, common::Span value) { bool valid; std::string fieldName; auto &values = map.valuesForPath(name, valid, fieldName, true); if (valid) { auto i = values.find(fieldName); if (i == values.end()) values.emplace(new Variable(fieldName, std::vector(value.begin(), value.end()))); else { (*i)->assign(std::vector(value.begin(), value.end())); } } return map; } Map &Map::set(const std::string &name, bool value) { return setByPath(*this, name, value); } Map &Map::set(const std::string &name, float value) { return setByPath(*this, name, value); } Map &Map::set(const std::string &name, int32_t value) { return setByPath(*this, name, value); } Map &Map::set(const std::string &name, const Color &value) { return setByPath(*this, name, value); } Map &Map::set(const std::string &name, const std::string &value) { return setByPath(*this, name, value); } Map &Map::set(const std::string &name, const char *value) { return setByPath(*this, name, value); } Map &Map::set(const std::string &name, Ref value) { return setByPath(*this, name, value); } Map &Map::set(const std::string &name, const std::vector &values) { return setByPath(*this, name, values); } Map &Map::set(const std::string &name, const std::vector &values) { return setByPath(*this, name, values); } Map &Map::set(const std::string &name, const std::vector &values) { return setByPath(*this, name, values); } Map &Map::set(const std::string &name, const std::vector &values) { return setByPath(*this, name, values); } Map &Map::set(const std::string &name, const std::vector &values) { return setByPath(*this, name, values); } Map &Map::set(const std::string &name, const std::vector &values) { return setByPath(*this, name, values); } Map &Map::set(const std::string &name, const std::vector &values) { return setByPath(*this, name, values); } Map &Map::set(const std::string &name, const common::Span values) { return setByPath(*this, name, values); } Map &Map::set(const std::string &name, const common::Span values) { return setByPath(*this, name, values); } Map &Map::set(const std::string &name, const common::Span values) { return setByPath(*this, name, values); } Map &Map::set(const std::string &name, const common::Span values) { return setByPath(*this, name, values); } Map &Map::set(const std::string &name, const common::Span values) { return setByPath(*this, name, values); } Map &Map::set(const std::string &name, const common::Span values) { return setByPath(*this, name, values); } Map &Map::set(const std::string &name, const common::Span values) { return setByPath(*this, name, values); } Map &Map::set(std::unique_ptr &&value) { if (!value) return *this; auto i = m_values.find(value->name()); if (i == m_values.end()) m_values.emplace(std::move(value)); else (*i)->data() = std::move(value->data()); return *this; } bool Map::remove(const std::string &name) { bool valid; std::string fieldName; auto &values = valuesForPath(name, valid, fieldName, false); if (!valid) return false; auto i = values.find(fieldName); if (i == values.end()) return false; values.erase(i); return true; } bool Map::removeAll() { bool result = !m_values.empty(); m_values.clear(); return result; } size_t Map::size() const { return m_values.size(); } bool Map::contains(const std::string &name) const { bool valid; std::string fieldName; auto &values = valuesForPath(name, valid, fieldName); if (!valid) return false; return values.find(fieldName) != values.end(); } struct TypeNameVisitor: public boost::static_visitor { template std::string operator()(const T &) const { return dynv::types::typeHandler().name; } template std::string operator()(const std::vector &) const { return dynv::types::typeHandler().name; } }; std::string Map::type(const std::string &name) const { auto i = m_values.find(name); if (i == m_values.end()) return ""; return boost::apply_visitor(TypeNameVisitor(), (*i)->data()); } bool Map::serialize(std::ostream &stream, const std::unordered_map &typeMap) const { return binary::serialize(stream, *this, typeMap); } bool Map::deserialize(std::istream &stream, const std::unordered_map &typeMap) { return binary::deserialize(stream, *this, typeMap); } bool Map::serializeXml(std::ostream &stream) const { return xml::serialize(stream, *this); } bool Map::deserializeXml(std::istream &stream) { removeAll(); return xml::deserialize(stream, *this); } bool Map::visit(std::function visitor, bool recursive) const { if (!recursive) { for (const auto &value: m_values) if (!visitor(*value)) return false; return true; } std::queue systems; for (const auto &value: m_values) { if (!visitor(*value)) return false; if (boost::apply_visitor(IsMap(), value->data())) systems.push(&*boost::get(value->data())); } while (!systems.empty()) { auto &map = *systems.front(); systems.pop(); for (const auto &value: map.m_values) { if (!visitor(*value)) return false; if (boost::apply_visitor(IsMap(), value->data())) systems.push(&*boost::get(value->data())); } } return true; } Map::Map() { } Map::~Map() { } Ref Map::create() { return Ref(new Map()); } bool Map::Compare::operator()(const std::unique_ptr &a, const std::unique_ptr &b) const { return a->name() < b->name(); } bool Map::Compare::operator()(const std::string &name, const std::unique_ptr &b) const { return name < b->name(); } bool Map::Compare::operator()(const std::unique_ptr &a, const std::string &name) const { return a->name() < name; } } gpick-gpick-0.2.6/source/dynv/Map.h000066400000000000000000000134721377073231300170720ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_DYNV_MAP_H_ #define GPICK_DYNV_MAP_H_ #include "MapFwd.h" #include "Color.h" #include "Types.h" #include "common/Ref.h" #include "common/Span.h" #include #include #include #include #include #include #include #include namespace dynv { struct Variable; struct Map: public common::Ref::Counter { using Ref = common::Ref; struct Compare { using is_transparent = void; bool operator()(const std::unique_ptr &a, const std::unique_ptr &b) const; bool operator()(const std::string &name, const std::unique_ptr &b) const; bool operator()(const std::unique_ptr &a, const std::string &name) const; }; using Set = std::set, Compare>; Map(); virtual ~Map() override; bool getBool(const std::string &name, bool defaultValue = false) const; float getFloat(const std::string &name, float defaultValue = 0.0f) const; int32_t getInt32(const std::string &name, int32_t defaultValue = 0) const; Color getColor(const std::string &name, Color defaultValue = {}) const; std::string getString(const std::string &name, const std::string &defaultValue = m_defaultString) const; std::vector getBools(const std::string &name) const; std::vector getFloats(const std::string &name) const; std::vector getInt32s(const std::string &name) const; std::vector getColors(const std::string &name) const; std::vector getStrings(const std::string &name) const; Ref getMap(const std::string &name); std::vector getMaps(const std::string &name); const Ref getMap(const std::string &name) const; std::vector getMaps(const std::string &name) const; Ref getOrCreateMap(const std::string &name); std::vector getOrCreateMaps(const std::string &name); Map &set(const std::string &name, Ref value); Map &set(const std::string &name, bool value); Map &set(const std::string &name, float value); Map &set(const std::string &name, int32_t value); Map &set(const std::string &name, const Color &value); Map &set(const std::string &name, const std::string &value); Map &set(const std::string &name, const char *value); Map &set(const std::string &name, const std::vector &value); Map &set(const std::string &name, const std::vector &value); Map &set(const std::string &name, const std::vector &value); Map &set(const std::string &name, const std::vector &value); Map &set(const std::string &name, const std::vector &value); Map &set(const std::string &name, const std::vector &value); Map &set(const std::string &name, const std::vector &value); Map &set(const std::string &name, const common::Span value); Map &set(const std::string &name, const common::Span value); Map &set(const std::string &name, const common::Span value); Map &set(const std::string &name, const common::Span value); Map &set(const std::string &name, const common::Span value); Map &set(const std::string &name, const common::Span value); Map &set(const std::string &name, const common::Span value); template::value || std::is_same::value || std::is_same::value, int> = 0> Map &set(const std::string &name, T value) { return this->set(name, value); } Map &set(std::unique_ptr &&value); bool remove(const std::string &name); bool removeAll(); size_t size() const; bool contains(const std::string &name) const; std::string type(const std::string &name) const; bool serialize(std::ostream &stream, const std::unordered_map &typeMap) const; bool serializeXml(std::ostream &stream) const; bool deserialize(std::istream &stream, const std::unordered_map &typeMap); bool deserializeXml(std::istream &stream); bool visit(std::function visitor, bool recursive = false) const; static Ref create(); Set &valuesForPath(const std::string &path, bool &valid, std::string &name, bool createMissing); const Set &valuesForPath(const std::string &path, bool &valid, std::string &name) const; private: Set m_values; static const std::string m_defaultString; }; } #endif /* GPICK_DYNV_MAP_H_ */ gpick-gpick-0.2.6/source/dynv/MapFwd.h000066400000000000000000000033041377073231300175240ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_DYNV_MAP_FWD_H_ #define GPICK_DYNV_MAP_FWD_H_ #include "common/Ref.h" namespace dynv { struct Map; using Ref = common::Ref; } #endif /* GPICK_DYNV_MAP_FWD_H_ */ gpick-gpick-0.2.6/source/dynv/Types.cpp000066400000000000000000000201661377073231300200120ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Types.h" #include "Map.h" #include "Color.h" #include #include namespace dynv { namespace xml { bool serialize(std::ostream &stream, const Map &map, bool addRootElement = true); } namespace types { static const KnownHandler knownHandlers[] = { { "bool", ValueType::basicBool }, { "float", ValueType::basicFloat }, { "int32", ValueType::basicInt32 }, { "string", ValueType::string }, { "color", ValueType::color }, { "dynv", ValueType::map }, }; const size_t knownHandlerCount = sizeof(knownHandlers) / sizeof(KnownHandler); ValueType stringToType(const char *value) { if (value == nullptr || value[0] == 0) return ValueType::unknown; for (size_t i = 0; i < knownHandlerCount; i++) { if (knownHandlers[i].name == value) return knownHandlers[i].type; } return ValueType::unknown; } ValueType stringToType(const std::string &value) { if (value.empty()) return ValueType::unknown; for (size_t i = 0; i < knownHandlerCount; i++) { if (knownHandlers[i].name == value) return knownHandlers[i].type; } return ValueType::unknown; } template<> const KnownHandler &typeHandler() { return knownHandlers[0]; } template<> const KnownHandler &typeHandler() { return knownHandlers[1]; } template<> const KnownHandler &typeHandler() { return knownHandlers[2]; } template<> const KnownHandler &typeHandler() { return knownHandlers[3]; } template<> const KnownHandler &typeHandler() { return knownHandlers[4]; } template<> const KnownHandler &typeHandler() { return knownHandlers[5]; } namespace xml { static std::string escapeXmlString(const std::string &value) { std::string result; result.reserve(value.length() + 64); for (auto ch: value) { switch (ch) { case '&': result += "&"; break; case '<': result += "<"; break; case '>': result += ">"; break; default: result += ch; } } return result; } template<> bool write(std::ostream &stream, bool value) { stream << (value ? "true" : "false"); return stream.good(); } template<> bool write(std::ostream &stream, float value) { stream << value; return stream.good(); } template<> bool write(std::ostream &stream, int32_t value) { stream << value; return stream.good(); } template<> bool write(std::ostream &stream, const std::string &value) { stream << escapeXmlString(value); return stream.good(); } template<> bool write(std::ostream &stream, const Color &value) { stream << value.ma[0] << " " << value.ma[1] << " " << value.ma[2] << " " << value.ma[3]; return stream.good(); } template<> bool write(std::ostream &stream, const Ref &value) { if (value) dynv::xml::serialize(stream, *value, false); return stream.good(); } } namespace binary { template<> bool write(std::ostream &stream, uint8_t value) { stream.write(reinterpret_cast(&value), 1); return stream.good(); } template<> bool write(std::ostream &stream, bool value) { return write(stream, static_cast(value ? 1 : 0)); } template<> bool write(std::ostream &stream, float value) { static_assert(sizeof(float) == 4); #if BOOST_VERSION >= 107100 uint8_t buffer[sizeof(float)]; boost::endian::endian_store(buffer, value); stream.write(reinterpret_cast(buffer), sizeof(float)); #else value = boost::endian::native_to_little(value); stream.write(reinterpret_cast(&value), sizeof(float)); #endif return stream.good(); } template<> bool write(std::ostream &stream, int32_t value) { static_assert(sizeof(int32_t) == 4); value = boost::endian::native_to_little(value); stream.write(reinterpret_cast(&value), sizeof(int32_t)); return stream.good(); } template<> bool write(std::ostream &stream, uint32_t value) { static_assert(sizeof(uint32_t) == 4); value = boost::endian::native_to_little(value); stream.write(reinterpret_cast(&value), sizeof(uint32_t)); return stream.good(); } template<> bool write(std::ostream &stream, const std::string &value) { if (!write(stream, static_cast(value.length()))) return false; stream.write(value.c_str(), value.length()); return stream.good(); } template<> bool write(std::ostream &stream, const Color &value) { if (!write(stream, static_cast(sizeof(value.ma)))) return false; if (!write(stream, static_cast(value.ma[0]))) return false; if (!write(stream, static_cast(value.ma[1]))) return false; if (!write(stream, static_cast(value.ma[2]))) return false; if (!write(stream, static_cast(value.ma[3]))) return false; return true; } template<> uint8_t read(std::istream &stream) { static_assert(sizeof(uint8_t) == 1); uint8_t value; stream.read(reinterpret_cast(&value), sizeof(uint8_t)); return value; } template<> uint32_t read(std::istream &stream) { static_assert(sizeof(uint32_t) == 4); uint32_t value; stream.read(reinterpret_cast(&value), sizeof(uint32_t)); return boost::endian::little_to_native(value); } template<> int32_t read(std::istream &stream) { static_assert(sizeof(int32_t) == 4); int32_t value; stream.read(reinterpret_cast(&value), sizeof(int32_t)); return boost::endian::little_to_native(value); } template<> std::string read(std::istream &stream) { uint32_t length = read(stream); if (!stream.good()) return std::string(); std::string result; result.resize(length); stream.read(reinterpret_cast(&result.front()), length); return result; } template<> float read(std::istream &stream) { static_assert(sizeof(float) == 4); #if BOOST_VERSION >= 107100 uint8_t buffer[sizeof(float)]; stream.read(reinterpret_cast(buffer), sizeof(float)); return boost::endian::endian_load(buffer); #else float value; stream.read(reinterpret_cast(&value), sizeof(float)); return boost::endian::little_to_native(value); #endif } template<> Color read(std::istream &stream) { static_assert(sizeof(float) * 4 == 16); uint8_t buffer[sizeof(float) * 4]; auto storeLength = read(stream); auto length = std::min(storeLength, sizeof(float) * 4); if (length > 0) stream.read(reinterpret_cast(buffer), length); if (storeLength - length > 0) stream.seekg(storeLength - length, std::ios::cur); Color result; for (int i = 0; i < 4; i++) { #if BOOST_VERSION >= 107100 result.ma[i] = boost::endian::endian_load(buffer + i * sizeof(float)); #else float value; stream.read(reinterpret_cast(&value), sizeof(float)); result.ma[i] = boost::endian::little_to_native(value); #endif } return result; } } } } gpick-gpick-0.2.6/source/dynv/Types.h000066400000000000000000000052151377073231300174550ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_DYNV_TYPES_H_ #define GPICK_DYNV_TYPES_H_ #include "common/Ref.h" #include #include namespace dynv { struct Map; namespace types { enum class ValueType : uint8_t { unknown, map, basicBool, basicFloat, basicInt32, color, string, }; struct KnownHandler { std::string name; ValueType type; }; template const KnownHandler &typeHandler(); namespace xml { template::value, int> = 0> bool write(std::ostream &stream, T value); template::value, int> = 0> bool write(std::ostream &stream, const T &value); } namespace binary { template::value, int> = 0> bool write(std::ostream &stream, T value); template::value, int> = 0> bool write(std::ostream &stream, const T &value); template T read(std::istream &stream); } ValueType stringToType(const char *value); ValueType stringToType(const std::string &value); } } #endif /* GPICK_DYNV_TYPES_H_ */ gpick-gpick-0.2.6/source/dynv/Variable.cpp000066400000000000000000000106621377073231300204330ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Variable.h" #include "Map.h" namespace dynv { Variable::Variable(const std::string &name, bool value): m_name(name), m_data(value) { } Variable::Variable(const std::string &name, float value): m_name(name), m_data(value) { } Variable::Variable(const std::string &name, int32_t value): m_name(name), m_data(value) { } Variable::Variable(const std::string &name, const Color &value): m_name(name), m_data(value) { } Variable::Variable(const std::string &name, const std::string &value): m_name(name), m_data(value) { } Variable::Variable(const std::string &name, const char *value): m_name(name), m_data(std::string(value)) { } Variable::Variable(const std::string &name, const Ref &value): m_name(name), m_data(value) { } Variable::Variable(const std::string &name, const std::vector &value): m_name(name), m_data(value) { } Variable::Variable(const std::string &name, const std::vector &value): m_name(name), m_data(value) { } Variable::Variable(const std::string &name, const std::vector &value): m_name(name), m_data(value) { } Variable::Variable(const std::string &name, const std::vector &value): m_name(name), m_data(value) { } Variable::Variable(const std::string &name, const std::vector &value): m_name(name), m_data(value) { } Variable::Variable(const std::string &name, const std::vector &value): m_name(name), m_data(std::vector(value.begin(), value.end())) { } Variable::Variable(const std::string &name, const std::vector &value): m_name(name), m_data(value) { } void Variable::assign(bool value) { m_data = value; } void Variable::assign(float value) { m_data = value; } void Variable::assign(int32_t value) { m_data = value; } void Variable::assign(const Color &value) { m_data = value; } void Variable::assign(const std::string &value) { m_data = value; } void Variable::assign(const char *value) { m_data = std::string(value); } void Variable::assign(const Ref &value) { m_data = value; } template<> void Variable::assign(const std::vector &value) { m_data = std::move(value); } template<> void Variable::assign(const std::vector &value) { m_data = std::move(value); } template<> void Variable::assign(const std::vector &value) { m_data = std::move(value); } template<> void Variable::assign(const std::vector &value) { m_data = std::move(value); } template<> void Variable::assign(const std::vector &value) { m_data = std::move(std::vector(value.begin(), value.end())); } template<> void Variable::assign(const std::vector &value) { m_data = std::move(value); } template<> void Variable::assign(const std::vector &value) { m_data = std::move(value); } const std::string &Variable::name() const { return m_name; } const Variable::Data &Variable::data() const { return m_data; } Variable::Data &Variable::data() { return m_data; } Variable::~Variable() { } } gpick-gpick-0.2.6/source/dynv/Variable.h000066400000000000000000000064151377073231300201010ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_DYNV_VARIABLE_H_ #define GPICK_DYNV_VARIABLE_H_ #include "MapFwd.h" #include "Color.h" #include "common/Ref.h" #include #include #include #include namespace dynv { struct Map; struct Variable { using Data = boost::variant, std::vector, std::vector, std::vector, std::vector, std::vector>; Variable(const std::string &name, bool value); Variable(const std::string &name, float value); Variable(const std::string &name, int32_t value); Variable(const std::string &name, const Color &value); Variable(const std::string &name, const std::string &value); Variable(const std::string &name, const char *value); Variable(const std::string &name, const Ref &value); Variable(const std::string &name, const std::vector &value); Variable(const std::string &name, const std::vector &value); Variable(const std::string &name, const std::vector &value); Variable(const std::string &name, const std::vector &value); Variable(const std::string &name, const std::vector &value); Variable(const std::string &name, const std::vector &value); Variable(const std::string &name, const std::vector &value); void assign(bool value); void assign(float value); void assign(int32_t value); void assign(const Color &value); void assign(const std::string &value); void assign(const char *value); void assign(const Ref &value); template void assign(const std::vector &value); ~Variable(); const std::string &name() const; const Data &data() const; Data &data(); private: std::string m_name; Data m_data; }; } #endif /* GPICK_DYNV_VARIABLE_H_ */ gpick-gpick-0.2.6/source/dynv/Xml.cpp000066400000000000000000000307501377073231300174460ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Xml.h" #include "Map.h" #include "Variable.h" #include "Types.h" #include "common/Scoped.h" #include #include using namespace std::string_literals; namespace dynv { namespace xml { using ValueType = types::ValueType; bool writeStart(std::ostream &stream, const std::string &name) { stream << "<" << name << ">"; return stream.good(); } bool writeStart(std::ostream &stream, const std::string &name, const std::string &type) { stream << "<" << name << " type=\"" << type << "\">"; return stream.good(); } bool writeEnd(std::ostream &stream, const std::string &name) { stream << ""; return stream.good(); } bool writeListStart(std::ostream &stream, const std::string &name, const std::string &type) { stream << "<" << name << " type=\"" << type << "\" list=\"true\">"; return stream.good(); } struct SerializeVisitor: public boost::static_visitor { SerializeVisitor(std::ostream &stream, const std::string &name): stream(stream), name(name) { } template bool operator()(const T &value) const { if (!writeStart(stream, name, dynv::types::typeHandler().name)) return false; if (!types::xml::write(stream, value)) return false; if (!writeEnd(stream, name)) return false; return true; } bool operator()(const common::Ref &value) const { if (!writeStart(stream, name, dynv::types::typeHandler>().name)) return false; if (!types::xml::write(stream, value)) return false; if (!writeEnd(stream, name)) return false; return true; } template bool operator()(const std::vector &values) const { using namespace std::string_literals; if (!writeListStart(stream, name, dynv::types::typeHandler().name)) return false; for (const auto &i: values) { if (!writeStart(stream, "li"s)) return false; if (!types::xml::write(stream, i)) return false; if (!writeEnd(stream, "li"s)) return false; } return writeEnd(stream, name); } std::ostream &stream; const std::string &name; }; static bool isTrue(const char *value) { using namespace std::string_literals; if (value == nullptr) return false; return value == "true"s; } enum class EntityType { root, map, list, listItem, value, unknown, }; struct Entity { Entity(Entity &entity) = delete; Entity(Entity &&entity): m_system(entity.m_system), m_entityType(entity.m_entityType), m_valueType(entity.m_valueType), m_value(std::move(entity.m_value)) { } Entity(Map &map, EntityType entityType, ValueType valueType): m_system(map), m_entityType(entityType), m_valueType(valueType) { } Entity(Map &map, EntityType entityType, ValueType valueType, std::unique_ptr &&value): m_system(map), m_entityType(entityType), m_valueType(valueType), m_value(std::move(value)) { } void write(const XML_Char *data, int length) { m_data.write(reinterpret_cast(data), length); } std::string data() { return m_data.str(); } bool isList() const { return m_entityType == EntityType::list; } bool ignoreData() const { return m_entityType != EntityType::listItem && m_entityType != EntityType::value; } bool isIgnored() const { return m_entityType == EntityType::unknown; } bool hasValue() const { return static_cast(m_value); } std::unique_ptr &value() { return m_value; } Map &map() { return m_system; } ValueType valueType() const { return m_valueType; } EntityType entityType() const { return m_entityType; } private: Map &m_system; std::stringstream m_data; EntityType m_entityType; ValueType m_valueType; std::unique_ptr m_value; }; struct Context { Context(Map &map): m_rootFound(false), m_errors(0) { push(map, EntityType::root); } ~Context() { m_entities.clear(); } Entity &entity() { return m_entities.back(); } Entity &parentEntity() { return m_entities.at(m_entities.size() - 2); } bool rootFound() const { return m_rootFound; } void setRootFound() { m_rootFound = true; } void push(Map &map, EntityType entityType, ValueType valueType = ValueType::unknown) { m_entities.emplace_back(map, entityType, valueType); } void push(Map &map, EntityType entityType, ValueType valueType, std::unique_ptr &&value) { m_entities.emplace_back(map, entityType, valueType, std::move(value)); } void pop() { m_entities.pop_back(); } void error() { m_errors++; } operator bool() const { return m_errors == 0; } private: bool m_rootFound; std::vector m_entities; uint32_t m_errors; }; static const char *getAttribute(const XML_Char **attributes, const std::string &name) { for (auto i = attributes; *i; i += 2) { if (*i == name) return i[1]; } return nullptr; } static void onCharacterData(Context *context, const XML_Char *data, int length) { auto &entity = context->entity(); if (entity.ignoreData() || entity.isIgnored()) return; entity.write(data, length); } struct IsVector: public boost::static_visitor { IsVector(Entity &entity): entity(entity) { } template bool operator()(const T &) const { return false; } template bool operator()(const std::vector &) const { return true; } Entity &entity; }; static void onStartElement(Context *context, const XML_Char *name, const XML_Char **attributes) { using namespace std::string_literals; if (!context->rootFound()) { if (name == "root"s) context->setRootFound(); return; } auto &entity = context->entity(); if (entity.isIgnored()) { context->push(entity.map(), EntityType::unknown); return; } if (entity.isList()) { if (!(name && name == "li"s)) { context->push(entity.map(), EntityType::unknown); return; } if (!boost::apply_visitor(IsVector(entity), entity.value()->data())) { context->error(); context->push(entity.map(), EntityType::unknown); return; } if (entity.valueType() == ValueType::map) { auto map = common::Ref(new Map()); auto &data = entity.value()->data(); context->push(*map, EntityType::listItem); boost::get> &>(data).push_back(std::move(map)); } else { context->push(entity.map(), EntityType::listItem); } return; } auto type = types::stringToType(getAttribute(attributes, "type"s)); auto isList = isTrue(getAttribute(attributes, "list"s)); switch (type) { case ValueType::basicBool: case ValueType::basicFloat: case ValueType::basicInt32: case ValueType::color: case ValueType::string: if (isList) { std::unique_ptr variable; switch (type) { case ValueType::basicBool: variable = std::make_unique(name, std::vector()); break; case ValueType::basicFloat: variable = std::make_unique(name, std::vector()); break; case ValueType::basicInt32: variable = std::make_unique(name, std::vector()); break; case ValueType::color: variable = std::make_unique(name, std::vector()); break; case ValueType::string: variable = std::make_unique(name, std::vector()); break; case ValueType::map: case ValueType::unknown: break; } context->push(entity.map(), EntityType::list, type, std::move(variable)); } else { context->push(entity.map(), EntityType::value, type); } break; case ValueType::map: if (isList) { auto systems = std::vector>(); auto variable = std::make_unique(name, systems); context->push(entity.map(), EntityType::list, type, std::move(variable)); } else { auto map = common::Ref(new Map()); entity.map().set(name, map); context->push(*map, EntityType::map, type); } break; case ValueType::unknown: context->push(entity.map(), EntityType::unknown); break; } } static void onEndElement(Context *context, const XML_Char *name) { if (!context->rootFound()) return; auto &entity = context->entity(); if (entity.isIgnored()) { context->pop(); return; } if (entity.isList()) { entity.map().set(std::move(entity.value())); context->pop(); return; } if (entity.entityType() == EntityType::listItem) { auto &listEntity = context->parentEntity(); auto &data = listEntity.value()->data(); switch (listEntity.valueType()) { case ValueType::string: boost::get &>(data).push_back(entity.data()); break; case ValueType::basicBool: boost::get &>(data).push_back(entity.data() == "true"); break; case ValueType::basicInt32: boost::get &>(data).push_back(std::stoi(entity.data())); break; case ValueType::basicFloat: boost::get &>(data).push_back(std::stof(entity.data())); break; case ValueType::color: { std::stringstream in(entity.data()); Color color; in >> color.ma[0] >> color.ma[1] >> color.ma[2] >> color.ma[3]; boost::get &>(data).push_back(color); } break; case ValueType::map: break; case ValueType::unknown: break; } context->pop(); return; } if (entity.entityType() == EntityType::value) { auto &map = entity.map(); switch (entity.valueType()) { case ValueType::string: map.set(name, entity.data()); break; case ValueType::basicBool: map.set(name, entity.data() == "true"); break; case ValueType::basicInt32: map.set(name, std::stoi(entity.data())); break; case ValueType::basicFloat: map.set(name, std::stof(entity.data())); break; case ValueType::color: { std::stringstream in(entity.data()); Color color; in >> color.ma[0] >> color.ma[1] >> color.ma[2] >> color.ma[3]; map.set(name, color); } break; case ValueType::map: break; case ValueType::unknown: break; } context->pop(); return; } if (entity.entityType() == EntityType::map) { context->pop(); return; } } bool serialize(std::ostream &stream, const Map &map, bool addRootElement) { if (addRootElement) { stream << ""; if (!stream.good()) return false; } auto visitor = [&stream](const Variable &value) -> bool { if (!boost::apply_visitor(SerializeVisitor(stream, value.name()), value.data())) return false; return true; }; if (!map.visit(visitor)) return false; if (addRootElement) { stream << ""; if (!stream.good()) return false; } return true; } bool deserialize(std::istream &stream, Map &map) { auto parser = XML_ParserCreate("UTF-8"); auto freeParser = common::makeScoped(XML_ParserFree, parser); XML_SetElementHandler(parser, reinterpret_cast(onStartElement), reinterpret_cast(onEndElement)); XML_SetCharacterDataHandler(parser, reinterpret_cast(onCharacterData)); xml::Context context(map); XML_SetUserData(parser, &context); for (;;) { auto buffer = XML_GetBuffer(parser, 4096); stream.read(reinterpret_cast(buffer), 4096); size_t length = stream.gcount(); if (!XML_ParseBuffer(parser, length, length == 0)) { std::cerr << "XML parse error\n"; return false; } if (length == 0) break; } return context; } } } gpick-gpick-0.2.6/source/dynv/Xml.h000066400000000000000000000034761377073231300171200ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_DYNV_XML_H_ #define GPICK_DYNV_XML_H_ #include #include namespace dynv { struct Map; namespace xml { bool serialize(std::ostream &stream, const Map &map, bool addRootElement = true); bool deserialize(std::istream &stream, Map &map); } } #endif /* GPICK_DYNV_XML_H_ */ gpick-gpick-0.2.6/source/gtk/000077500000000000000000000000001377073231300160025ustar00rootroot00000000000000gpick-gpick-0.2.6/source/gtk/ColorCell.cpp000066400000000000000000000201671377073231300203720ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ColorCell.h" #include "../ColorObject.h" #include static void init(CustomCellRendererColor *cellcolor); static void class_init(CustomCellRendererColorClass *klass); static void get_property(GObject *object, guint param_id, GValue *value, GParamSpec *pspec); static void set_property(GObject *object, guint param_id, const GValue *value, GParamSpec *pspec); static void finalize(GObject *gobject); #if GTK_MAJOR_VERSION >= 3 static void get_preferred_width(GtkCellRenderer *cell, GtkWidget *widget, gint *minimum_size, gint *natural_size); static void get_preferred_height(GtkCellRenderer *cell, GtkWidget *widget, gint *minimum_size, gint *natural_size); static void render(GtkCellRenderer *cell, cairo_t *cr, GtkWidget *widget, const GdkRectangle *background_area, const GdkRectangle *cell_area, GtkCellRendererState flags); #else static void get_size(GtkCellRenderer *cell, GtkWidget *widget, GdkRectangle *cell_area, gint *x_offset, gint *y_offset, gint *width, gint *height); static void render(GtkCellRenderer *cell, GdkDrawable *window, GtkWidget *widget, GdkRectangle *background_area, GdkRectangle *cell_area, GdkRectangle *expose_area, GtkCellRendererState flags); #endif enum { PROP_COLOR = 1, }; static gpointer parent_class; GType custom_cell_renderer_color_get_type() { static GType cell_color_type = 0; if (cell_color_type == 0){ static const GTypeInfo cell_color_info = { sizeof(CustomCellRendererColorClass), nullptr, /* base_init */ nullptr, /* base_finalize */ (GClassInitFunc) class_init, nullptr, /* class_finalize */ nullptr, /* class_data */ sizeof(CustomCellRendererColor), 0, /* n_preallocs */ (GInstanceInitFunc) init, }; cell_color_type = g_type_register_static(GTK_TYPE_CELL_RENDERER, "CustomCellRendererColor", &cell_color_info, (GTypeFlags) 0); } return cell_color_type; } static void init(CustomCellRendererColor *cellrenderercolor) { #if GTK_MAJOR_VERSION >= 3 #else GTK_CELL_RENDERER(cellrenderercolor)->mode = GTK_CELL_RENDERER_MODE_INERT; GTK_CELL_RENDERER(cellrenderercolor)->xpad = 2; GTK_CELL_RENDERER(cellrenderercolor)->ypad = 2; #endif cellrenderercolor->width = 32; cellrenderercolor->height = 16; cellrenderercolor->color = nullptr; } static void class_init(CustomCellRendererColorClass *klass) { GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(klass); GObjectClass *object_class = G_OBJECT_CLASS(klass); parent_class = g_type_class_peek_parent(klass); object_class->finalize = finalize; object_class->get_property = get_property; object_class->set_property = set_property; #if GTK_MAJOR_VERSION >= 3 cell_class->get_preferred_width = get_preferred_width; cell_class->get_preferred_height = get_preferred_height; #else cell_class->get_size = get_size; #endif cell_class->render = render; g_object_class_install_property(object_class, PROP_COLOR, g_param_spec_pointer("color", "Color", "ColorObject pointer", (GParamFlags) G_PARAM_READWRITE)); } static void finalize(GObject *object) { (*G_OBJECT_CLASS(parent_class)->finalize)(object); } static void get_property(GObject *object, guint param_id, GValue *value, GParamSpec *psec) { CustomCellRendererColor *cellcolor = CUSTOM_CELL_RENDERER_COLOR(object); switch (param_id){ case PROP_COLOR: g_value_set_pointer(value, cellcolor->color); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, psec); break; } } static void set_property(GObject *object, guint param_id, const GValue *value, GParamSpec *pspec) { CustomCellRendererColor *cellcolor = CUSTOM_CELL_RENDERER_COLOR(object); switch (param_id){ case PROP_COLOR: cellcolor->color = (ColorObject*)g_value_get_pointer(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); break; } } GtkCellRenderer *custom_cell_renderer_color_new() { return (GtkCellRenderer*)g_object_new(CUSTOM_TYPE_CELL_RENDERER_COLOR, nullptr); } void custom_cell_renderer_color_set_size(GtkCellRenderer *cell, gint width, gint height) { CustomCellRendererColor *cellcolor = CUSTOM_CELL_RENDERER_COLOR(cell); cellcolor->width = width; cellcolor->height = height; } #if GTK_MAJOR_VERSION >= 3 static void get_preferred_width(GtkCellRenderer *cell, GtkWidget *widget, gint *minimum_size, gint *natural_size) { CustomCellRendererColor *cellcolor = CUSTOM_CELL_RENDERER_COLOR(cell); if (minimum_size) *minimum_size = 1; *natural_size = cellcolor->width; } static void get_preferred_height(GtkCellRenderer *cell, GtkWidget *widget, gint *minimum_size, gint *natural_size) { CustomCellRendererColor *cellcolor = CUSTOM_CELL_RENDERER_COLOR(cell); if (minimum_size) *minimum_size = 1; *natural_size = cellcolor->height; } static void render(GtkCellRenderer *cell, cairo_t *cr, GtkWidget *widget, const GdkRectangle *background_area, const GdkRectangle *cell_area, GtkCellRendererState flags) { CustomCellRendererColor *cellcolor = CUSTOM_CELL_RENDERER_COLOR(cell); cairo_rectangle(cr, cell_area->x, cell_area->y, cell_area->width, cell_area->height); Color color = cellcolor->color->getColor(); cairo_set_source_rgb(cr, round(color.rgb.red * 255.0) / 255.0, round(color.rgb.green * 255.0) / 255.0, round(color.rgb.blue * 255.0) / 255.0); cairo_fill(cr); } #else static void get_size(GtkCellRenderer *cell, GtkWidget *widget, GdkRectangle *cell_area, gint *x_offset, gint *y_offset, gint *width, gint *height) { CustomCellRendererColor *cellcolor = CUSTOM_CELL_RENDERER_COLOR(cell); gint calc_width; gint calc_height; calc_width = (gint) cell->xpad * 2 + cellcolor->width; calc_height = (gint) cell->ypad * 2 + cellcolor->height; if (width) *width = calc_width; if (height) *height = calc_height; if (cell_area){ if (x_offset){ *x_offset = gint(cell->xalign * (cell_area->width - calc_width)); *x_offset = MAX(*x_offset, 0); } if (y_offset){ *y_offset = gint(cell->yalign * (cell_area->height - calc_height)); *y_offset = MAX(*y_offset, 0); } } } static void render(GtkCellRenderer *cell, GdkDrawable *window, GtkWidget *widget, GdkRectangle *background_area, GdkRectangle *cell_area, GdkRectangle *expose_area, GtkCellRendererState flags) { using boost::math::round; CustomCellRendererColor *cellcolor = CUSTOM_CELL_RENDERER_COLOR(cell); cairo_t *cr; cr = gdk_cairo_create(window); cairo_rectangle(cr, expose_area->x, expose_area->y, expose_area->width, expose_area->height); cairo_clip(cr); cairo_rectangle(cr, expose_area->x, expose_area->y, expose_area->width, expose_area->height); Color color = cellcolor->color->getColor(); cairo_set_source_rgb(cr, round(color.rgb.red * 255.0) / 255.0, round(color.rgb.green * 255.0) / 255.0, round(color.rgb.blue * 255.0) / 255.0); cairo_fill(cr); cairo_destroy(cr); } #endif gpick-gpick-0.2.6/source/gtk/ColorCell.h000066400000000000000000000053511377073231300200350ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_GTK_COLOR_CELL_H_ #define GPICK_GTK_COLOR_CELL_H_ #include struct ColorObject; #define CUSTOM_TYPE_CELL_RENDERER_COLOR (custom_cell_renderer_color_get_type()) #define CUSTOM_CELL_RENDERER_COLOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), CUSTOM_TYPE_CELL_RENDERER_COLOR, CustomCellRendererColor)) #define CUSTOM_CELL_RENDERER_COLOR_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST((obj), CUSTOM_TYPE_CELL_RENDERER_COLOR, CustomCellRendererColorClass)) #define CUSTOM_IS_CELL_COLOR_COLOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CUSTOM_TYPE_CELL_RENDERER_COLOR)) #define CUSTOM_IS_CELL_COLOR_COLOR_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((obj), CUSTOM_TYPE_CELL_RENDERER_COLOR)) #define CUSTOM_CELL_RENDERER_COLOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), CUSTOM_TYPE_CELL_RENDERER_COLOR, CustomCellRendererColorClass)) struct CustomCellRendererColor { GtkCellRenderer parent; ColorObject *color; int width; int height; }; struct CustomCellRendererColorClass { GtkCellRendererClass parent_class; }; GType custom_cell_renderer_color_get_type(); GtkCellRenderer *custom_cell_renderer_color_new(); void custom_cell_renderer_color_set_size(GtkCellRenderer *cell, gint width, gint height); #endif /* GPICK_GTK_COLOR_CELL_H_ */ gpick-gpick-0.2.6/source/gtk/ColorComponent.cpp000066400000000000000000000744411377073231300214610ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ColorComponent.h" #include "../uiUtilities.h" #include "../Color.h" #include "../MathUtil.h" #include "../Paths.h" #include #include #include using namespace std; #define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), GTK_TYPE_COLOR_COMPONENT, GtkColorComponentPrivate)) G_DEFINE_TYPE(GtkColorComponent, gtk_color_component, GTK_TYPE_DRAWING_AREA); struct GtkColorComponentPrivate; static gboolean button_release(GtkWidget *widget, GdkEventButton *event); static gboolean button_press(GtkWidget *node_system, GdkEventButton *event); static gboolean motion_notify(GtkWidget *node_system, GdkEventMotion *event); static void update_rgb_color(GtkColorComponentPrivate *ns, Color *c); static void finalize(GObject *color_obj); #if GTK_MAJOR_VERSION >= 3 static gboolean draw(GtkWidget *widget, cairo_t *cr); #else static gboolean expose(GtkWidget *widget, GdkEventExpose *event); static void size_request(GtkWidget *widget, GtkRequisition *requisition); #endif enum { COLOR_CHANGED, INPUT_CLICKED, LAST_SIGNAL }; static const int MaxNumberOfComponents = 4; static guint signals[LAST_SIGNAL] = {}; struct GtkColorComponentPrivate { Color orig_color; Color color; GtkColorComponentComp component; int n_components; int capture_on; gint last_event_position; bool changing_color; bool out_of_gamut_mask; ReferenceIlluminant lab_illuminant; ReferenceObserver lab_observer; cairo_surface_t *pattern_surface; cairo_pattern_t *pattern; const char *label[MaxNumberOfComponents][2]; gchar *text[MaxNumberOfComponents]; double range[MaxNumberOfComponents]; double offset[MaxNumberOfComponents]; #if GTK_MAJOR_VERSION >= 3 GdkDevice *pointer_grab; #endif }; static void gtk_color_component_class_init(GtkColorComponentClass *color_component_class) { GObjectClass *obj_class = G_OBJECT_CLASS (color_component_class); obj_class->finalize = finalize; g_type_class_add_private(obj_class, sizeof(GtkColorComponentPrivate)); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (color_component_class); widget_class->button_release_event = button_release; widget_class->button_press_event = button_press; widget_class->motion_notify_event = motion_notify; #if GTK_MAJOR_VERSION >= 3 widget_class->draw = draw; #else widget_class->expose_event = expose; widget_class->size_request = size_request; #endif signals[COLOR_CHANGED] = g_signal_new( "color-changed", G_OBJECT_CLASS_TYPE(obj_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkColorComponentClass, color_changed), nullptr, nullptr, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); signals[INPUT_CLICKED] = g_signal_new( "input-clicked", G_OBJECT_CLASS_TYPE(obj_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkColorComponentClass, input_clicked), nullptr, nullptr, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); } static void gtk_color_component_init(GtkColorComponent *color_component) { gtk_widget_add_events(GTK_WIDGET(color_component), GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_MOTION_MASK); } static void finalize(GObject *color_obj) { GtkColorComponentPrivate *ns = GET_PRIVATE(color_obj); for (int i = 0; i != sizeof(ns->text) / sizeof(gchar*); i++){ if (ns->text[i]){ g_free(ns->text[i]); ns->text[i] = 0; } } if (ns->pattern_surface) cairo_surface_destroy(ns->pattern_surface); if (ns->pattern) cairo_pattern_destroy(ns->pattern); gpointer parent_class = g_type_class_peek_parent(G_OBJECT_CLASS(GTK_COLOR_COMPONENT_GET_CLASS(color_obj))); G_OBJECT_CLASS(parent_class)->finalize(color_obj); } GtkWidget *gtk_color_component_new(GtkColorComponentComp component) { GtkWidget* widget = (GtkWidget*)g_object_new(GTK_TYPE_COLOR_COMPONENT, nullptr); GtkColorComponentPrivate *ns = GET_PRIVATE(widget); auto patternFilename = buildFilename("gpick-gray-pattern.png"); ns->pattern_surface = cairo_image_surface_create_from_png(patternFilename.c_str()); ns->pattern = cairo_pattern_create_for_surface(ns->pattern_surface); cairo_pattern_set_extend(ns->pattern, CAIRO_EXTEND_REPEAT); ns->component = component; ns->last_event_position = -1; ns->changing_color = false; ns->lab_illuminant = REFERENCE_ILLUMINANT_D50; ns->lab_observer= REFERENCE_OBSERVER_2; ns->out_of_gamut_mask = false; #if GTK_MAJOR_VERSION >= 3 ns->pointer_grab = nullptr; #endif for (int i = 0; i != sizeof(ns->text) / sizeof(gchar*); i++){ ns->text[i] = 0; } for (int i = 0; i != sizeof(ns->label) / sizeof(const char*[2]); i++){ ns->label[i][0] = 0; ns->label[i][1] = 0; } switch (component){ case GtkColorComponentComp::lab: ns->n_components = 3; ns->range[0] = 100; ns->offset[0] = 0; ns->range[1] = ns->range[2] = 290; ns->offset[1] = ns->offset[2] = -145; break; case GtkColorComponentComp::lch: ns->n_components = 3; ns->range[0] = 100; ns->offset[0] = 0; ns->range[1] = 136; ns->range[2] = 360; ns->offset[1] = ns->offset[2] = 0; break; case GtkColorComponentComp::xyz: //TODO: implement break; case GtkColorComponentComp::cmyk: ns->n_components = 4; ns->range[0] = ns->range[1] = ns->range[2] = ns->range[3] = 1; ns->offset[0] = ns->offset[1] = ns->offset[2] = ns->offset[3] = 0; break; default: ns->n_components = 3; ns->range[0] = ns->range[1] = ns->range[2] = ns->range[3] = 1; ns->offset[0] = ns->offset[1] = ns->offset[2] = ns->offset[3] = 0; } gtk_widget_set_size_request(GTK_WIDGET(widget), 242, 16 * ns->n_components); return widget; } void gtk_color_component_get_color(GtkColorComponent* color_component, Color* color) { GtkColorComponentPrivate *ns = GET_PRIVATE(color_component); color_copy(&ns->orig_color, color); } void gtk_color_component_get_transformed_color(GtkColorComponent* color_component, Color* color) { GtkColorComponentPrivate *ns = GET_PRIVATE(color_component); color_copy(&ns->color, color); } void gtk_color_component_set_transformed_color(GtkColorComponent* color_component, Color* color) { GtkColorComponentPrivate *ns = GET_PRIVATE(color_component); color_copy(color, &ns->color); update_rgb_color(ns, &ns->orig_color); gtk_widget_queue_draw(GTK_WIDGET(color_component)); } int gtk_color_component_get_component_id_at(GtkColorComponent* color_component, gint x, gint y) { GtkColorComponentPrivate *ns = GET_PRIVATE(color_component); int component = y / 16; if (component < 0) component = 0; else if (component >= ns->n_components) component = ns->n_components - 1; return component; } const char* gtk_color_component_get_text(GtkColorComponent* color_component, gint component_id) { GtkColorComponentPrivate *ns = GET_PRIVATE(color_component); return ns->text[component_id]; } void gtk_color_component_set_text(GtkColorComponent* color_component, const char **text) { GtkColorComponentPrivate *ns = GET_PRIVATE(color_component); for (int i = 0; i != sizeof(ns->text) / sizeof(gchar*); i++){ if (!text[i]) break; if (ns->text[i]){ g_free(ns->text[i]); } ns->text[i] = g_strdup(text[i]); } gtk_widget_queue_draw(GTK_WIDGET(color_component)); } void gtk_color_component_set_label(GtkColorComponent* color_component, const char **label) { GtkColorComponentPrivate *ns = GET_PRIVATE(color_component); for (int i = 0; i != MaxNumberOfComponents * 2; i++){ if (!label[i]) break; ns->label[i >> 1][i & 1] = label[i]; } gtk_widget_queue_draw(GTK_WIDGET(color_component)); } void gtk_color_component_set_color(GtkColorComponent* color_component, Color* color) { GtkColorComponentPrivate *ns = GET_PRIVATE(color_component); color_copy(color, &ns->orig_color); switch (ns->component){ case GtkColorComponentComp::rgb: color_copy(&ns->orig_color, &ns->color); break; case GtkColorComponentComp::hsl: color_rgb_to_hsl(&ns->orig_color, &ns->color); break; case GtkColorComponentComp::hsv: color_rgb_to_hsv(&ns->orig_color, &ns->color); break; case GtkColorComponentComp::cmyk: color_rgb_to_cmyk(&ns->orig_color, &ns->color); break; case GtkColorComponentComp::lab: { matrix3x3 adaptation_matrix; color_get_chromatic_adaptation_matrix(color_get_reference(REFERENCE_ILLUMINANT_D65, REFERENCE_OBSERVER_2), color_get_reference(ns->lab_illuminant, ns->lab_observer), &adaptation_matrix); color_rgb_to_lab(&ns->orig_color, &ns->color, color_get_reference(ns->lab_illuminant, ns->lab_observer), color_get_sRGB_transformation_matrix(), &adaptation_matrix); } break; case GtkColorComponentComp::xyz: //TODO: implement break; case GtkColorComponentComp::lch: { matrix3x3 adaptation_matrix; color_get_chromatic_adaptation_matrix(color_get_reference(REFERENCE_ILLUMINANT_D65, REFERENCE_OBSERVER_2), color_get_reference(ns->lab_illuminant, ns->lab_observer), &adaptation_matrix); color_rgb_to_lch(&ns->orig_color, &ns->color, color_get_reference(ns->lab_illuminant, ns->lab_observer), color_get_sRGB_transformation_matrix(), &adaptation_matrix); } break; } gtk_widget_queue_draw(GTK_WIDGET(color_component)); } static void interpolate_colors(Color *color1, Color *color2, float position, Color *result) { result->rgb.red = color1->rgb.red * (1 - position) + color2->rgb.red * position; result->rgb.green= color1->rgb.green * (1 - position) + color2->rgb.green * position; result->rgb.blue = color1->rgb.blue * (1 - position) + color2->rgb.blue * position; } #if GTK_MAJOR_VERSION >= 3 #else static void size_request(GtkWidget *widget, GtkRequisition *requisition) { GtkColorComponentPrivate *ns = GET_PRIVATE(widget); gint width = 240 + widget->style->xthickness * 2; gint height = ns->n_components * 16 + widget->style->ythickness * 2; requisition->width = width; requisition->height = height; } #endif static int get_x_offset(GtkWidget *widget) { #if GTK_MAJOR_VERSION >= 3 return 0; #else return widget->allocation.width - widget->style->xthickness * 2 - 240; #endif } static gboolean draw(GtkWidget *widget, cairo_t *cr) { GtkColorComponentPrivate *ns = GET_PRIVATE(widget); Color c[MaxNumberOfComponents]; double pointer_pos[MaxNumberOfComponents]; float steps; int i, j; for (int i = 0; i < ns->n_components; ++i){ pointer_pos[i] = (ns->color.ma[i] - ns->offset[i]) / ns->range[i]; } cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 200, ns->n_components * 16); unsigned char *data = cairo_image_surface_get_data(surface); int stride = cairo_image_surface_get_stride(surface); int surface_width = cairo_image_surface_get_width(surface); unsigned char *col_ptr; Color *rgb_points = new Color[ns->n_components * 200]; double int_part; matrix3x3 adaptation_matrix; vector > out_of_gamut(MaxNumberOfComponents, vector(false, 1)); switch (ns->component) { case GtkColorComponentComp::rgb: steps = 1; for (i = 0; i < 3; ++i){ color_copy(&ns->color, &c[i]); } for (i = 0; i < surface_width; ++i){ c[0].rgb.red = c[1].rgb.green = c[2].rgb.blue = (float)i / (float)(surface_width - 1); col_ptr = data + i * 4; for (int y = 0; y < ns->n_components * 16; ++y){ if ((y & 0x0f) != 0x0f){ col_ptr[2] = (unsigned char)(c[y / 16].rgb.red * 255); col_ptr[1] = (unsigned char)(c[y / 16].rgb.green * 255); col_ptr[0] = (unsigned char)(c[y / 16].rgb.blue * 255); col_ptr[3] = 0xff; }else{ col_ptr[0] = 0x00; col_ptr[1] = 0x00; col_ptr[2] = 0x00; col_ptr[3] = 0x00; } col_ptr += stride; } } break; case GtkColorComponentComp::hsv: steps = 100; for (i = 0; i < 3; ++i){ color_copy(&ns->color, &c[i]); } for (i = 0; i <= steps; ++i){ c[0].hsv.hue = c[1].hsv.saturation = c[2].hsv.value = i / steps; for (j = 0; j < 3; ++j){ color_hsv_to_rgb(&c[j], &rgb_points[j * (int(steps) + 1) + i]); } } for (i = 0; i < surface_width; ++i){ float position = modf(i * steps / surface_width, &int_part); int index = i * int(steps) / surface_width; interpolate_colors(&rgb_points[0 * (int(steps) + 1) + index], &rgb_points[0 * (int(steps) + 1) + index + 1], position, &c[0]); interpolate_colors(&rgb_points[1 * (int(steps) + 1) + index], &rgb_points[1 * (int(steps) + 1) + index + 1], position, &c[1]); interpolate_colors(&rgb_points[2 * (int(steps) + 1) + index], &rgb_points[2 * (int(steps) + 1) + index + 1], position, &c[2]); col_ptr = data + i * 4; for (int y = 0; y < ns->n_components * 16; ++y){ if ((y & 0x0f) != 0x0f){ col_ptr[2] = (unsigned char)(c[y / 16].rgb.red * 255); col_ptr[1] = (unsigned char)(c[y / 16].rgb.green * 255); col_ptr[0] = (unsigned char)(c[y / 16].rgb.blue * 255); col_ptr[3] = 0xff; }else{ col_ptr[0] = 0x00; col_ptr[1] = 0x00; col_ptr[2] = 0x00; col_ptr[3] = 0x00; } col_ptr += stride; } } break; case GtkColorComponentComp::hsl: steps = 100; for (i = 0; i < 3; ++i){ color_copy(&ns->color, &c[i]); } for (i = 0; i <= steps; ++i){ c[0].hsl.hue = c[1].hsl.saturation = c[2].hsl.lightness = i / steps; for (j = 0; j < 3; ++j){ color_hsl_to_rgb(&c[j], &rgb_points[j * (int(steps) + 1) + i]); } } for (i = 0; i < surface_width; ++i){ float position = modf(i * steps / surface_width, &int_part); int index = i * int(steps) / surface_width; interpolate_colors(&rgb_points[0 * (int(steps) + 1) + index], &rgb_points[0 * (int(steps) + 1) + index + 1], position, &c[0]); interpolate_colors(&rgb_points[1 * (int(steps) + 1) + index], &rgb_points[1 * (int(steps) + 1) + index + 1], position, &c[1]); interpolate_colors(&rgb_points[2 * (int(steps) + 1) + index], &rgb_points[2 * (int(steps) + 1) + index + 1], position, &c[2]); col_ptr = data + i * 4; for (int y = 0; y < ns->n_components * 16; ++y){ if ((y & 0x0f) != 0x0f){ col_ptr[2] = (unsigned char)(c[y / 16].rgb.red * 255); col_ptr[1] = (unsigned char)(c[y / 16].rgb.green * 255); col_ptr[0] = (unsigned char)(c[y / 16].rgb.blue * 255); col_ptr[3] = 0xff; }else{ col_ptr[0] = 0x00; col_ptr[1] = 0x00; col_ptr[2] = 0x00; col_ptr[3] = 0x00; } col_ptr += stride; } } break; case GtkColorComponentComp::cmyk: steps = 100; for (i = 0; i < 4; ++i){ color_copy(&ns->color, &c[i]); } for (i = 0; i <= steps; ++i){ c[0].cmyk.c = c[1].cmyk.m = c[2].cmyk.y = c[3].cmyk.k = i / steps; for (j = 0; j < 4; ++j){ color_cmyk_to_rgb(&c[j], &rgb_points[j * (int(steps) + 1) + i]); } } for (i = 0; i < surface_width; ++i){ float position = modf(i * steps / surface_width, &int_part); int index = i * int(steps) / surface_width; interpolate_colors(&rgb_points[0 * (int(steps) + 1) + index], &rgb_points[0 * (int(steps) + 1) + index + 1], position, &c[0]); interpolate_colors(&rgb_points[1 * (int(steps) + 1) + index], &rgb_points[1 * (int(steps) + 1) + index + 1], position, &c[1]); interpolate_colors(&rgb_points[2 * (int(steps) + 1) + index], &rgb_points[2 * (int(steps) + 1) + index + 1], position, &c[2]); interpolate_colors(&rgb_points[3 * (int(steps) + 1) + index], &rgb_points[3 * (int(steps) + 1) + index + 1], position, &c[3]); col_ptr = data + i * 4; for (int y = 0; y < ns->n_components * 16; ++y){ if ((y & 0x0f) != 0x0f){ col_ptr[2] = (unsigned char)(c[y / 16].rgb.red * 255); col_ptr[1] = (unsigned char)(c[y / 16].rgb.green * 255); col_ptr[0] = (unsigned char)(c[y / 16].rgb.blue * 255); col_ptr[3] = 0xff; }else{ col_ptr[0] = 0x00; col_ptr[1] = 0x00; col_ptr[2] = 0x00; col_ptr[3] = 0x00; } col_ptr += stride; } } break; case GtkColorComponentComp::lab: steps = 100; color_get_chromatic_adaptation_matrix(color_get_reference(ns->lab_illuminant, ns->lab_observer), color_get_reference(REFERENCE_ILLUMINANT_D65, REFERENCE_OBSERVER_2), &adaptation_matrix); for (j = 0; j < 3; ++j){ color_copy(&ns->color, &c[j]); out_of_gamut[j] = vector(steps + 1, false); for (i = 0; i <= steps; ++i){ c[j].ma[j] = (i / steps) * ns->range[j] + ns->offset[j]; color_lab_to_rgb(&c[j], &rgb_points[j * (int(steps) + 1) + i], color_get_reference(ns->lab_illuminant, ns->lab_observer), color_get_inverted_sRGB_transformation_matrix(), &adaptation_matrix); if (color_is_rgb_out_of_gamut(&rgb_points[j * (int(steps) + 1) + i])){ out_of_gamut[j][i] = true; } color_rgb_normalize(&rgb_points[j * (int(steps) + 1) + i]); } } for (i = 0; i < surface_width; ++i){ float position = modf(i * steps / surface_width, &int_part); int index = i * int(steps) / surface_width; interpolate_colors(&rgb_points[0 * (int(steps) + 1) + index], &rgb_points[0 * (int(steps) + 1) + index + 1], position, &c[0]); interpolate_colors(&rgb_points[1 * (int(steps) + 1) + index], &rgb_points[1 * (int(steps) + 1) + index + 1], position, &c[1]); interpolate_colors(&rgb_points[2 * (int(steps) + 1) + index], &rgb_points[2 * (int(steps) + 1) + index + 1], position, &c[2]); col_ptr = data + i * 4; for (int y = 0; y < ns->n_components * 16; ++y){ if ((y & 0x0f) != 0x0f){ col_ptr[2] = (unsigned char)(c[y / 16].rgb.red * 255); col_ptr[1] = (unsigned char)(c[y / 16].rgb.green * 255); col_ptr[0] = (unsigned char)(c[y / 16].rgb.blue * 255); col_ptr[3] = 0xff; }else{ col_ptr[0] = 0x00; col_ptr[1] = 0x00; col_ptr[2] = 0x00; col_ptr[3] = 0x00; } col_ptr += stride; } } break; case GtkColorComponentComp::lch: steps = 100; color_get_chromatic_adaptation_matrix(color_get_reference(ns->lab_illuminant, ns->lab_observer), color_get_reference(REFERENCE_ILLUMINANT_D65, REFERENCE_OBSERVER_2), &adaptation_matrix); for (j = 0; j < 3; ++j){ color_copy(&ns->color, &c[j]); out_of_gamut[j] = vector(steps + 1, false); for (i = 0; i <= steps; ++i){ c[j].ma[j] = (i / steps) * ns->range[j] + ns->offset[j]; color_lch_to_rgb(&c[j], &rgb_points[j * (int(steps) + 1) + i], color_get_reference(ns->lab_illuminant, ns->lab_observer), color_get_inverted_sRGB_transformation_matrix(), &adaptation_matrix); if (color_is_rgb_out_of_gamut(&rgb_points[j * (int(steps) + 1) + i])){ out_of_gamut[j][i] = true; } color_rgb_normalize(&rgb_points[j * (int(steps) + 1) + i]); } } for (i = 0; i < surface_width; ++i){ float position = modf(i * steps / surface_width, &int_part); int index = i * int(steps) / surface_width; interpolate_colors(&rgb_points[0 * (int(steps) + 1) + index], &rgb_points[0 * (int(steps) + 1) + index + 1], position, &c[0]); interpolate_colors(&rgb_points[1 * (int(steps) + 1) + index], &rgb_points[1 * (int(steps) + 1) + index + 1], position, &c[1]); interpolate_colors(&rgb_points[2 * (int(steps) + 1) + index], &rgb_points[2 * (int(steps) + 1) + index + 1], position, &c[2]); col_ptr = data + i * 4; for (int y = 0; y < ns->n_components * 16; ++y){ if ((y & 0x0f) != 0x0f){ col_ptr[2] = (unsigned char)(c[y / 16].rgb.red * 255); col_ptr[1] = (unsigned char)(c[y / 16].rgb.green * 255); col_ptr[0] = (unsigned char)(c[y / 16].rgb.blue * 255); col_ptr[3] = 0xff; }else{ col_ptr[0] = 0x00; col_ptr[1] = 0x00; col_ptr[2] = 0x00; col_ptr[3] = 0x00; } col_ptr += stride; } } break; default: break; } delete [] rgb_points; cairo_surface_mark_dirty(surface); cairo_save(cr); int offset_x = get_x_offset(widget); cairo_set_source_surface(cr, surface, offset_x, 0); cairo_surface_destroy(surface); for (i = 0; i < ns->n_components; ++i){ cairo_rectangle(cr, offset_x, 16 * i, 200, 15); cairo_fill(cr); } cairo_restore(cr); for (i = 0; i < ns->n_components; ++i){ cairo_matrix_t matrix; cairo_matrix_init_translate(&matrix, -offset_x - 64, -64 + 5 * i); cairo_pattern_set_matrix(ns->pattern, &matrix); if (ns->out_of_gamut_mask){ int first_out_of_gamut = 0; bool out_of_gamut_found = false; cairo_set_source(cr, ns->pattern); for (size_t j = 0; j < out_of_gamut[i].size(); j++){ if (out_of_gamut[i][j]){ if (!out_of_gamut_found){ out_of_gamut_found = true; first_out_of_gamut = j; } }else{ if (out_of_gamut_found){ cairo_rectangle(cr, offset_x + (first_out_of_gamut * 200.0 / out_of_gamut[i].size()), 16 * i, (j - first_out_of_gamut) * 200.0 / out_of_gamut[i].size(), 15); cairo_fill(cr); out_of_gamut_found = false; } } } if (out_of_gamut_found){ cairo_rectangle(cr, offset_x + (first_out_of_gamut * 200.0 / out_of_gamut[i].size()), 16 * i, (out_of_gamut[i].size() - first_out_of_gamut) * 200.0 / out_of_gamut[i].size(), 15); cairo_fill(cr); } } cairo_move_to(cr, offset_x + 200 * pointer_pos[i], 16 * i + 9); cairo_line_to(cr, offset_x + 200 * pointer_pos[i] + 3, 16 * i + 16); cairo_line_to(cr, offset_x + 200 * pointer_pos[i] - 3, 16 * i + 16); cairo_set_source_rgb(cr, 1, 1, 1); cairo_fill_preserve(cr); cairo_set_source_rgb(cr, 0, 0, 0); cairo_set_line_width(cr, 1); cairo_stroke(cr); if (ns->text[i] || ns->label[i]){ PangoLayout *layout; PangoFontDescription *font_description; font_description = pango_font_description_new(); layout = pango_cairo_create_layout(cr); pango_font_description_set_family(font_description, "sans"); pango_font_description_set_weight(font_description, PANGO_WEIGHT_NORMAL); pango_font_description_set_absolute_size(font_description, 12 * PANGO_SCALE); pango_layout_set_font_description(layout, font_description); pango_layout_set_wrap(layout, PANGO_WRAP_WORD); pango_layout_set_single_paragraph_mode(layout, true); #if GTK_MAJOR_VERSION >= 3 //TODO: GTK3 font color #else gdk_cairo_set_source_color(cr, &widget->style->text[0]); #endif int width, height; if (ns->text[i]){ pango_layout_set_text(layout, ns->text[i], -1); pango_layout_set_width(layout, 40 * PANGO_SCALE); pango_layout_set_height(layout, 16 * PANGO_SCALE); pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT); pango_cairo_update_layout(cr, layout); pango_layout_get_pixel_size(layout, &width, &height); cairo_move_to(cr, 200 + offset_x, i * 16); pango_cairo_show_layout(cr, layout); } if (ns->label[i] && offset_x > 10){ if (offset_x > 50){ pango_layout_set_text(layout, ns->label[i][1], -1); }else{ pango_layout_set_text(layout, ns->label[i][0], -1); } pango_layout_set_width(layout, (offset_x - 10) * PANGO_SCALE); pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END); pango_layout_set_height(layout, 16 * PANGO_SCALE); pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); pango_cairo_update_layout(cr, layout); pango_layout_get_pixel_size(layout, &width, &height); cairo_move_to(cr, 5, i * 16); pango_cairo_show_layout(cr, layout); } g_object_unref(layout); pango_font_description_free(font_description); } } return TRUE; } #if GTK_MAJOR_VERSION < 3 static gboolean expose(GtkWidget *widget, GdkEventExpose *event) { cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_rectangle(cr, event->area.x, event->area.y, event->area.width, event->area.height); cairo_clip(cr); cairo_translate(cr, widget->style->xthickness, widget->style->ythickness); gboolean result = draw(widget, cr); cairo_destroy(cr); return result; } #endif GtkColorComponentComp gtk_color_component_get_component(GtkColorComponent* color_component) { return GET_PRIVATE(color_component)->component; } static void update_rgb_color(GtkColorComponentPrivate *ns, Color *c) { switch (ns->component){ case GtkColorComponentComp::rgb: color_copy(&ns->color, c); color_rgb_normalize(c); break; case GtkColorComponentComp::hsv: color_hsv_to_rgb(&ns->color, c); color_rgb_normalize(c); break; case GtkColorComponentComp::hsl: color_hsl_to_rgb(&ns->color, c); color_rgb_normalize(c); break; case GtkColorComponentComp::cmyk: color_cmyk_to_rgb(&ns->color, c); color_rgb_normalize(c); break; case GtkColorComponentComp::lab: { matrix3x3 adaptation_matrix; color_get_chromatic_adaptation_matrix(color_get_reference(ns->lab_illuminant, ns->lab_observer), color_get_reference(REFERENCE_ILLUMINANT_D65, REFERENCE_OBSERVER_2), &adaptation_matrix); color_lab_to_rgb(&ns->color, c, color_get_reference(ns->lab_illuminant, ns->lab_observer), color_get_inverted_sRGB_transformation_matrix(), &adaptation_matrix); color_rgb_normalize(c); } break; case GtkColorComponentComp::xyz: //TODO: implement break; case GtkColorComponentComp::lch: { matrix3x3 adaptation_matrix; color_get_chromatic_adaptation_matrix(color_get_reference(ns->lab_illuminant, ns->lab_observer), color_get_reference(REFERENCE_ILLUMINANT_D65, REFERENCE_OBSERVER_2), &adaptation_matrix); color_lch_to_rgb(&ns->color, c, color_get_reference(ns->lab_illuminant, ns->lab_observer), color_get_inverted_sRGB_transformation_matrix(), &adaptation_matrix); color_rgb_normalize(c); } break; } } void gtk_color_component_get_raw_color(GtkColorComponent* color_component, Color* color) { GtkColorComponentPrivate *ns = GET_PRIVATE(color_component); color_copy(&ns->color, color); } void gtk_color_component_set_raw_color(GtkColorComponent* color_component, Color* color) { GtkColorComponentPrivate *ns = GET_PRIVATE(color_component); color_copy(color, &ns->color); Color c; update_rgb_color(ns, &c); color_copy(&c, &ns->orig_color); gtk_widget_queue_draw(GTK_WIDGET(color_component)); g_signal_emit(GTK_WIDGET(color_component), signals[COLOR_CHANGED], 0, &c); } static void emit_color_change(GtkWidget *widget, int component, double value) { GtkColorComponentPrivate *ns = GET_PRIVATE(widget); Color c; ns->color.ma[component] = value * ns->range[component] + ns->offset[component]; update_rgb_color(ns, &c); g_signal_emit(widget, signals[COLOR_CHANGED], 0, &c); } static gboolean button_release(GtkWidget *widget, GdkEventButton *event) { GtkColorComponentPrivate *ns = GET_PRIVATE(widget); #if GTK_MAJOR_VERSION >= 3 if (ns->pointer_grab){ gdk_seat_ungrab(gdk_device_get_seat(ns->pointer_grab)); ns->pointer_grab = nullptr; } #else gdk_pointer_ungrab(GDK_CURRENT_TIME); #endif ns->changing_color = false; return false; } static gboolean button_press(GtkWidget *widget, GdkEventButton *event) { GtkColorComponentPrivate *ns = GET_PRIVATE(widget); if ((event->type == GDK_BUTTON_PRESS) && (event->button == 1)){ int component = event->y / 16; if (component < 0) component = 0; else if (component >= ns->n_components) component = ns->n_components - 1; int offset_x = get_x_offset(widget); if (event->x < offset_x || event->x > 200 + offset_x) { g_signal_emit(widget, signals[INPUT_CLICKED], 0, component); return FALSE; } ns->changing_color = true; ns->last_event_position = event->x; double value; value = (event->x - offset_x) / 200.0; if (value < 0) value = 0; else if (value > 1) value = 1; ns->capture_on = component; #if GTK_MAJOR_VERSION >= 3 ns->pointer_grab = event->device; gdk_seat_grab(gdk_device_get_seat(event->device), gtk_widget_get_window(widget), GDK_SEAT_CAPABILITY_ALL, false, nullptr, nullptr, nullptr, nullptr); #else gdk_pointer_grab(gtk_widget_get_window(widget), false, GdkEventMask(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK), nullptr, nullptr, GDK_CURRENT_TIME); #endif emit_color_change(widget, component, value); gtk_widget_queue_draw(widget); return TRUE; } return FALSE; } static gboolean motion_notify(GtkWidget *widget, GdkEventMotion *event) { GtkColorComponentPrivate *ns = GET_PRIVATE(widget); if (ns->changing_color && (event->state & GDK_BUTTON1_MASK)){ int offset_x = get_x_offset(widget); if ((event->x < offset_x && ns->last_event_position < offset_x) || ((event->x > 200 + offset_x) && (ns->last_event_position > 200 + offset_x))) return FALSE; ns->last_event_position = event->x; double value; value = (event->x - offset_x) / 200.0; if (value < 0) value = 0; else if (value > 1) value = 1; emit_color_change(widget, ns->capture_on, value); gtk_widget_queue_draw(widget); return TRUE; } return FALSE; } void gtk_color_component_set_lab_illuminant(GtkColorComponent* color_component, ReferenceIlluminant illuminant) { GtkColorComponentPrivate *ns = GET_PRIVATE(color_component); ns->lab_illuminant = illuminant; gtk_color_component_set_color(color_component, &ns->orig_color); gtk_widget_queue_draw(GTK_WIDGET(color_component)); } void gtk_color_component_set_lab_observer(GtkColorComponent* color_component, ReferenceObserver observer) { GtkColorComponentPrivate *ns = GET_PRIVATE(color_component); ns->lab_observer = observer; gtk_color_component_set_color(color_component, &ns->orig_color); gtk_widget_queue_draw(GTK_WIDGET(color_component)); } void gtk_color_component_set_out_of_gamut_mask(GtkColorComponent* color_component, bool mask_enabled) { GtkColorComponentPrivate *ns = GET_PRIVATE(color_component); ns->out_of_gamut_mask = mask_enabled; gtk_widget_queue_draw(GTK_WIDGET(color_component)); } bool gtk_color_component_get_out_of_gamut_mask(GtkColorComponent* color_component) { GtkColorComponentPrivate *ns = GET_PRIVATE(color_component); return ns->out_of_gamut_mask; } gpick-gpick-0.2.6/source/gtk/ColorComponent.h000066400000000000000000000102101377073231300211060ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_GTK_COLOR_COMPONENT_H_ #define GPICK_GTK_COLOR_COMPONENT_H_ #include #include "../Color.h" #define GTK_TYPE_COLOR_COMPONENT (gtk_color_component_get_type()) #define GTK_COLOR_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_COLOR_COMPONENT, GtkColorComponent)) #define GTK_COLOR_COMPONENT_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST((obj), GTK_COLOR_COMPONENT, GtkColorComponentClass)) #define GTK_IS_COLOR_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_COLOR_COMPONENT)) #define GTK_IS_COLOR_COMPONENT_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((obj), GTK_TYPE_COLOR_COMPONENT)) #define GTK_COLOR_COMPONENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_COLOR_COMPONENT, GtkColorComponentClass)) struct GtkColorComponent { GtkDrawingArea parent; }; struct GtkColorComponentClass { GtkDrawingAreaClass parent_class; void (*color_changed)(GtkWidget* widget, Color* c, gpointer userdata); void (*input_clicked)(GtkWidget* widget, int component_id, gpointer userdata); }; enum class GtkColorComponentComp: int { rgb, hsv, hsl, cmyk, xyz, lab, lch, }; GtkWidget* gtk_color_component_new(GtkColorComponentComp component); void gtk_color_component_set_color(GtkColorComponent* color_component, Color* color); void gtk_color_component_set_text(GtkColorComponent* color_component, const char **text); const char* gtk_color_component_get_text(GtkColorComponent* color_component, gint component_id); void gtk_color_component_set_label(GtkColorComponent* color_component, const char **label); void gtk_color_component_get_color(GtkColorComponent* color_component, Color* color); void gtk_color_component_get_raw_color(GtkColorComponent* color_component, Color* color); void gtk_color_component_set_raw_color(GtkColorComponent* color_component, Color* color); void gtk_color_component_get_transformed_color(GtkColorComponent* color_component, Color* color); void gtk_color_component_set_transformed_color(GtkColorComponent* color_component, Color* color); void gtk_color_component_set_out_of_gamut_mask(GtkColorComponent* color_component, bool mask_enabled); bool gtk_color_component_get_out_of_gamut_mask(GtkColorComponent* color_component); void gtk_color_component_set_lab_illuminant(GtkColorComponent* color_component, ReferenceIlluminant illuminant); void gtk_color_component_set_lab_observer(GtkColorComponent* color_component, ReferenceObserver observer); GtkColorComponentComp gtk_color_component_get_component(GtkColorComponent* color_component); int gtk_color_component_get_component_id_at(GtkColorComponent* color_component, gint x, gint y); GType gtk_color_component_get_type(); #endif /* GPICK_GTK_COLOR_COMPONENT_H_ */ gpick-gpick-0.2.6/source/gtk/ColorWheel.cpp000066400000000000000000000422731377073231300205610ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ColorWheel.h" #include "../Color.h" #include "../ColorWheelType.h" #include "../MathUtil.h" #include #ifdef _MSC_VER #define M_PI 3.14159265359 #endif #include #include #include using namespace std; #define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), GTK_TYPE_COLOR_WHEEL, GtkColorWheelPrivate)) G_DEFINE_TYPE (GtkColorWheel, gtk_color_wheel, GTK_TYPE_DRAWING_AREA); struct GtkColorWheelPrivate; struct ColorPoint; static GtkWindowClass *parent_class = nullptr; static gboolean button_release(GtkWidget *color_wheel, GdkEventButton *event); static gboolean button_press(GtkWidget *color_wheel, GdkEventButton *event); static gboolean motion_notify(GtkWidget *widget, GdkEventMotion *event); static uint32_t get_color_index(GtkColorWheelPrivate *ns, ColorPoint *cp); #if GTK_MAJOR_VERSION >= 3 static gboolean draw(GtkWidget *widget, cairo_t *cr); #else static gboolean expose(GtkWidget *color_wheel, GdkEventExpose *event); #endif enum { HUE_CHANGED, SATURATION_VALUE_CHANGED, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = {0}; struct ColorPoint { double hue; double lightness; double saturation; }; struct GtkColorWheelPrivate { ColorPoint cpoint[10]; uint32_t n_cpoint; ColorPoint *grab_active; bool grab_block; ColorPoint *selected; int active_color; double radius; double circle_width; double block_size; bool block_editable; const ColorWheelType *color_wheel_type; cairo_surface_t *cache_color_wheel; #if GTK_MAJOR_VERSION >= 3 GdkDevice *pointer_grab; #endif }; static void finalize(GObject *color_wheel_obj) { GtkColorWheelPrivate *ns = GET_PRIVATE(color_wheel_obj); if (ns->cache_color_wheel){ cairo_surface_destroy(ns->cache_color_wheel); ns->cache_color_wheel = 0; } G_OBJECT_CLASS(parent_class)->finalize(color_wheel_obj); } static void gtk_color_wheel_class_init(GtkColorWheelClass *color_wheel_class) { GObjectClass *obj_class = G_OBJECT_CLASS(color_wheel_class); obj_class->finalize = finalize; GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(color_wheel_class); widget_class->button_release_event = button_release; widget_class->button_press_event = button_press; widget_class->motion_notify_event = motion_notify; #if GTK_MAJOR_VERSION >= 3 widget_class->draw = draw; #else widget_class->expose_event = expose; #endif parent_class = (GtkWindowClass*)g_type_class_peek_parent(G_OBJECT_CLASS(color_wheel_class)); g_type_class_add_private(obj_class, sizeof(GtkColorWheelPrivate)); signals[HUE_CHANGED] = g_signal_new("hue_changed", G_OBJECT_CLASS_TYPE(obj_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkColorWheelClass, hue_changed), nullptr, nullptr, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); signals[SATURATION_VALUE_CHANGED] = g_signal_new("saturation_value_changed", G_OBJECT_CLASS_TYPE(obj_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkColorWheelClass, saturation_value_changed), nullptr, nullptr, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); } static void gtk_color_wheel_init(GtkColorWheel *color_wheel) { gtk_widget_add_events(GTK_WIDGET(color_wheel), GDK_2BUTTON_PRESS | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); } GtkWidget* gtk_color_wheel_new() { GtkWidget* widget = (GtkWidget*) g_object_new(GTK_TYPE_COLOR_WHEEL, nullptr); GtkColorWheelPrivate *ns = GET_PRIVATE(widget); ns->active_color = 1; ns->radius = 80; ns->circle_width = 14; ns->block_size = 2 * (ns->radius - ns->circle_width) * sin(M_PI / 4) - 8; #if GTK_MAJOR_VERSION >= 3 gtk_widget_set_size_request(GTK_WIDGET(widget), ns->radius * 2, ns->radius * 2); #else gtk_widget_set_size_request(GTK_WIDGET(widget), ns->radius * 2 + widget->style->xthickness * 2, ns->radius * 2 + widget->style->ythickness * 2); #endif ns->n_cpoint = 0; ns->grab_active = 0; ns->grab_block = false; ns->selected = &ns->cpoint[0]; ns->block_editable = true; ns->color_wheel_type = &color_wheel_types_get()[0]; ns->cache_color_wheel = 0; #if GTK_MAJOR_VERSION >= 3 ns->pointer_grab = nullptr; #endif gtk_widget_set_can_focus(widget, true); return widget; } void gtk_color_wheel_set_color_wheel_type(GtkColorWheel *color_wheel, const ColorWheelType *color_wheel_type) { GtkColorWheelPrivate *ns = GET_PRIVATE(color_wheel); if (ns->color_wheel_type != color_wheel_type){ ns->color_wheel_type = color_wheel_type; if (ns->cache_color_wheel){ cairo_surface_destroy(ns->cache_color_wheel); ns->cache_color_wheel = 0; } gtk_widget_queue_draw(GTK_WIDGET(color_wheel)); } } void gtk_color_wheel_set_block_editable(GtkColorWheel* color_wheel, bool editable) { GtkColorWheelPrivate *ns = GET_PRIVATE(color_wheel); ns->block_editable = editable; } bool gtk_color_wheel_get_block_editable(GtkColorWheel* color_wheel) { GtkColorWheelPrivate *ns = GET_PRIVATE(color_wheel); return ns->block_editable; } void gtk_color_wheel_set_selected(GtkColorWheel* color_wheel, guint32 index) { GtkColorWheelPrivate *ns = GET_PRIVATE(color_wheel); if (index < 10){ ns->selected = &ns->cpoint[index]; gtk_widget_queue_draw(GTK_WIDGET(color_wheel)); } } void gtk_color_wheel_set_n_colors(GtkColorWheel* color_wheel, guint32 number_of_colors) { GtkColorWheelPrivate *ns = GET_PRIVATE(color_wheel); if (number_of_colors <= 10){ if (ns->n_cpoint != number_of_colors){ ns->n_cpoint = number_of_colors; if (ns->selected){ uint32_t index = get_color_index(ns, ns->selected); if (index >= number_of_colors){ ns->selected = &ns->cpoint[0]; } } gtk_widget_queue_draw(GTK_WIDGET(color_wheel)); } } } void gtk_color_wheel_set_hue(GtkColorWheel* color_wheel, guint32 index, double hue) { GtkColorWheelPrivate *ns = GET_PRIVATE(color_wheel); if (index < 10){ ns->cpoint[index].hue = hue; gtk_widget_queue_draw(GTK_WIDGET(color_wheel)); } } void gtk_color_wheel_set_saturation(GtkColorWheel* color_wheel, guint32 index, double saturation) { GtkColorWheelPrivate *ns = GET_PRIVATE(color_wheel); if (index < 10){ ns->cpoint[index].saturation = saturation; if (&ns->cpoint[index] == ns->selected) gtk_widget_queue_draw(GTK_WIDGET(color_wheel)); } } void gtk_color_wheel_set_value(GtkColorWheel* color_wheel, guint32 index, double value) { GtkColorWheelPrivate *ns = GET_PRIVATE(color_wheel); if (index < 10){ ns->cpoint[index].lightness = value; if (&ns->cpoint[index] == ns->selected) gtk_widget_queue_draw(GTK_WIDGET(color_wheel)); } } double gtk_color_wheel_get_hue(GtkColorWheel* color_wheel, guint32 index) { GtkColorWheelPrivate *ns = GET_PRIVATE(color_wheel); if (index < 10){ return ns->cpoint[index].hue; } return 0; } double gtk_color_wheel_get_saturation(GtkColorWheel* color_wheel, guint32 index) { GtkColorWheelPrivate *ns = GET_PRIVATE(color_wheel); if (index < 10){ return ns->cpoint[index].saturation; } return 0; } double gtk_color_wheel_get_value(GtkColorWheel* color_wheel, guint32 index) { GtkColorWheelPrivate *ns = GET_PRIVATE(color_wheel); if (index < 10){ return ns->cpoint[index].lightness; } return 0; } static void draw_dot(cairo_t *cr, double x, double y, double size) { cairo_arc(cr, x, y, size - 1, 0, 2 * M_PI); cairo_set_source_rgba(cr, 1, 1, 1, 0.5); cairo_set_line_width(cr, 2); cairo_stroke(cr); cairo_arc(cr, x, y, size, 0, 2 * M_PI); cairo_set_source_rgba(cr, 0, 0, 0, 1); cairo_set_line_width(cr, 1); cairo_stroke(cr); } static void draw_sat_val_block(cairo_t *cr, double pos_x, double pos_y, double size, double hue) { cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ceil(size), ceil(size)); unsigned char *data = cairo_image_surface_get_data(surface); int stride = cairo_image_surface_get_stride(surface); int surface_width = cairo_image_surface_get_width(surface); int surface_height = cairo_image_surface_get_height(surface); Color c; unsigned char *line_data; for (int y = 0; y < surface_height; ++y){ line_data = data + stride * y; for (int x = 0; x < surface_width; ++x){ c.hsv.hue = hue; c.hsv.saturation = x / size; c.hsv.value = y / size; color_hsv_to_rgb(&c, &c); line_data[2] = c.rgb.red * 255; line_data[1] = c.rgb.green * 255; line_data[0] = c.rgb.blue * 255; line_data[3] = 0xFF; line_data += 4; } } cairo_surface_mark_dirty(surface); cairo_save(cr); cairo_set_source_surface(cr, surface, pos_x - size / 2, pos_y - size / 2); cairo_surface_destroy(surface); cairo_rectangle(cr, pos_x - size / 2, pos_y - size / 2, size, size); cairo_fill(cr); cairo_restore(cr); } static void draw_wheel(GtkColorWheelPrivate *ns, cairo_t *cr, double radius, double width, const ColorWheelType *wheel) { cairo_surface_t *surface; double inner_radius = radius - width; if (ns->cache_color_wheel){ surface = ns->cache_color_wheel; }else{ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ceil(radius * 2), ceil(radius * 2)); if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS){ cerr << "ColorWheel image surface allocation failed" << endl; return; } unsigned char *data = cairo_image_surface_get_data(surface); int stride = cairo_image_surface_get_stride(surface); int surface_width = cairo_image_surface_get_width(surface); int surface_height = cairo_image_surface_get_height(surface); double radius_sq = radius * radius + 2 * radius + 1; double inner_radius_sq = inner_radius * inner_radius - 2 * inner_radius + 1; Color c; unsigned char *line_data; for (int y = 0; y < surface_height; ++y){ line_data = data + stride * y; for (int x = 0; x < surface_width; ++x){ int dx = -(x - surface_width / 2); int dy = y - surface_height / 2; int dist = dx * dx + dy * dy; if ((dist >= inner_radius_sq) && (dist <= radius_sq)){ double angle = atan2((double)dx, (double)dy) + M_PI; wheel->hue_to_hsl(angle / (M_PI * 2), &c); color_hsl_to_rgb(&c, &c); line_data[2] = c.rgb.red * 255; line_data[1] = c.rgb.green * 255; line_data[0] = c.rgb.blue * 255; line_data[3] = 0xFF; } line_data += 4; } } ns->cache_color_wheel = surface; } cairo_surface_mark_dirty(surface); cairo_save(cr); cairo_set_source_surface(cr, surface, 0, 0); cairo_set_line_width(cr, width); cairo_new_path(cr); cairo_arc(cr, radius, radius, (inner_radius + radius) / 2, 0, M_PI * 2); cairo_stroke(cr); cairo_restore(cr); } static bool is_inside_block(GtkColorWheelPrivate *ns, gint x, gint y) { double size = ns->block_size; if ((x >= ns->radius - size / 2) && (x <= ns->radius + size / 2)){ if ((y >= ns->radius - size / 2) && (y <= ns->radius + size / 2)){ return true; } } return false; } static ColorPoint* get_cpoint_at(GtkColorWheelPrivate *ns, gint x, gint y) { double dx, dy; for (uint32_t i = 0; i != ns->n_cpoint; i++){ dx = ns->radius + (ns->radius - ns->circle_width / 2) * sin(ns->cpoint[i].hue * M_PI * 2) - x; dy = ns->radius - (ns->radius - ns->circle_width / 2) * cos(ns->cpoint[i].hue * M_PI * 2) - y; if (sqrt(dx * dx + dy * dy) < 16){ return &ns->cpoint[i]; } } return 0; } static uint32_t get_color_index(GtkColorWheelPrivate *ns, ColorPoint *cp) { return (uint64_t(cp) - uint64_t(ns)) / sizeof(ColorPoint); } int gtk_color_wheel_get_at(GtkColorWheel *color_wheel, int x, int y) { GtkColorWheelPrivate *ns = GET_PRIVATE(color_wheel); ColorPoint *cp = get_cpoint_at(ns, x, y); if (cp){ return get_color_index(ns, cp); } if (is_inside_block(ns, x, y)) return -1; return -2; } static void offset_xy(GtkWidget *widget, gint &x, gint &y) { #if GTK_MAJOR_VERSION < 3 x = x - widget->style->xthickness; y = y - widget->style->ythickness; #endif } static gboolean motion_notify(GtkWidget *widget, GdkEventMotion *event) { GtkColorWheelPrivate *ns = GET_PRIVATE(widget); int x = event->x, y = event->y; offset_xy(widget, x, y); if (ns->grab_active){ double dx = -(x - ns->radius); double dy = y - ns->radius; double angle = atan2(dx, dy) + M_PI; ns->grab_active->hue = angle / (M_PI * 2); g_signal_emit(widget, signals[HUE_CHANGED], 0, get_color_index(ns, ns->grab_active)); gtk_widget_queue_draw(widget); return true; }else if (ns->grab_block){ double dx = event->x - ns->radius + ns->block_size / 2; double dy = event->y - ns->radius + ns->block_size / 2; ns->selected->saturation = clamp_float(dx / ns->block_size, 0, 1); ns->selected->lightness = clamp_float(dy / ns->block_size, 0, 1); g_signal_emit(widget, signals[SATURATION_VALUE_CHANGED], 0, get_color_index(ns, ns->selected)); gtk_widget_queue_draw(widget); return true; } return false; } static gboolean draw(GtkWidget *widget, cairo_t *cr) { GtkColorWheelPrivate *ns = GET_PRIVATE(widget); draw_wheel(ns, cr, ns->radius, ns->circle_width, ns->color_wheel_type); if (ns->selected){ double block_size = 2 * (ns->radius - ns->circle_width) * sin(M_PI / 4) - 6; Color hsl; ns->color_wheel_type->hue_to_hsl(ns->selected->hue, &hsl); draw_sat_val_block(cr, ns->radius, ns->radius, block_size, hsl.hsl.hue); draw_dot(cr, ns->radius - block_size / 2 + block_size * ns->selected->saturation, ns->radius - block_size / 2 + block_size * ns->selected->lightness, 4); } for (uint32_t i = 0; i != ns->n_cpoint; i++){ draw_dot(cr, ns->radius + (ns->radius - ns->circle_width / 2) * sin(ns->cpoint[i].hue * M_PI * 2), ns->radius - (ns->radius - ns->circle_width / 2) * cos(ns->cpoint[i].hue * M_PI * 2), (&ns->cpoint[i] == ns->selected) ? 7 : 4); } return FALSE; } #if GTK_MAJOR_VERSION < 3 static gboolean expose(GtkWidget *widget, GdkEventExpose *event) { cairo_t *cr; GtkColorWheelPrivate *ns = GET_PRIVATE(widget); cr = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_rectangle(cr, event->area.x, event->area.y, event->area.width, event->area.height); cairo_clip(cr); cairo_translate(cr, widget->style->xthickness + 0.5, widget->style->ythickness + 0.5); gboolean result = draw(widget, cr); cairo_destroy(cr); return result; } #endif static gboolean button_press(GtkWidget *widget, GdkEventButton *event) { GtkColorWheelPrivate *ns = GET_PRIVATE(widget); int x = event->x, y = event->y; offset_xy(widget, x, y); gtk_widget_grab_focus(widget); ColorPoint *p; if (is_inside_block(ns, x, y)){ if ((event->type == GDK_BUTTON_PRESS) && (event->button == 1)){ if (ns->block_editable && ns->selected){ ns->grab_block = true; GdkCursor *cursor = gdk_cursor_new_for_display(gtk_widget_get_display(widget), GDK_CROSS); #if GTK_MAJOR_VERSION >= 3 ns->pointer_grab = event->device; gdk_seat_grab(gdk_device_get_seat(event->device), gtk_widget_get_window(widget), GDK_SEAT_CAPABILITY_ALL, false, cursor, nullptr, nullptr, nullptr); g_object_unref(cursor); #else gdk_pointer_grab(gtk_widget_get_window(widget), false, GdkEventMask(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK), nullptr, cursor, GDK_CURRENT_TIME); gdk_cursor_unref(cursor); #endif return true; } } }else if ((p = get_cpoint_at(ns, x, y))){ if ((event->type == GDK_BUTTON_PRESS) && (event->button == 1)){ ns->grab_active = p; ns->selected = p; GdkCursor *cursor = gdk_cursor_new_for_display(gtk_widget_get_display(widget), GDK_CROSS); #if GTK_MAJOR_VERSION >= 3 ns->pointer_grab = event->device; gdk_seat_grab(gdk_device_get_seat(event->device), gtk_widget_get_window(widget), GDK_SEAT_CAPABILITY_ALL, false, cursor, nullptr, nullptr, nullptr); g_object_unref(cursor); #else gdk_pointer_grab(gtk_widget_get_window(widget), false, GdkEventMask(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK), nullptr, cursor, GDK_CURRENT_TIME); gdk_cursor_unref(cursor); #endif return true; } } return false; } static gboolean button_release(GtkWidget *widget, GdkEventButton *event) { GtkColorWheelPrivate *ns = GET_PRIVATE(widget); #if GTK_MAJOR_VERSION >= 3 if (ns->pointer_grab){ gdk_seat_ungrab(gdk_device_get_seat(ns->pointer_grab)); ns->pointer_grab = nullptr; } #else gdk_pointer_ungrab(GDK_CURRENT_TIME); #endif ns->grab_active = 0; ns->grab_block = false; return false; } gpick-gpick-0.2.6/source/gtk/ColorWheel.h000066400000000000000000000071051377073231300202210ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_GTK_COLOR_WHEEL_H_ #define GPICK_GTK_COLOR_WHEEL_H_ #include #include "../Color.h" #include "../ColorWheelType.h" #define GTK_TYPE_COLOR_WHEEL (gtk_color_wheel_get_type()) #define GTK_COLOR_WHEEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_COLOR_WHEEL, GtkColorWheel)) #define GTK_COLOR_WHEEL_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST((obj), GTK_COLOR_WHEEL, GtkColorWheelClass)) #define GTK_IS_COLOR_WHEEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_COLOR_WHEEL)) #define GTK_IS_COLOR_WHEEL_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((obj), GTK_TYPE_COLOR_WHEEL)) #define GTK_COLOR_WHEEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_COLOR_WHEEL, GtkColorWheelClass)) struct GtkColorWheel { GtkDrawingArea parent; }; struct GtkColorWheelClass { GtkDrawingAreaClass parent_class; void (*hue_changed)(GtkWidget *widget, gint color_id, gpointer userdata); void (*saturation_value_changed)(GtkWidget *widget, gint color_id, gpointer userdata); }; GtkWidget* gtk_color_wheel_new(); void gtk_color_wheel_set_value(GtkColorWheel *color_wheel, guint32 index, double value); void gtk_color_wheel_set_hue(GtkColorWheel *color_wheel, guint32 index, double hue); void gtk_color_wheel_set_saturation(GtkColorWheel *color_wheel, guint32 index, double saturation); void gtk_color_wheel_set_selected(GtkColorWheel *color_wheel, guint32 index); double gtk_color_wheel_get_hue(GtkColorWheel *color_wheel, guint32 index); double gtk_color_wheel_get_saturation(GtkColorWheel *color_wheel, guint32 index); double gtk_color_wheel_get_value(GtkColorWheel *color_wheel, guint32 index); void gtk_color_wheel_set_block_editable(GtkColorWheel *color_wheel, bool editable); bool gtk_color_wheel_get_block_editable(GtkColorWheel *color_wheel); int gtk_color_wheel_get_at(GtkColorWheel *color_wheel, int x, int y); void gtk_color_wheel_set_n_colors(GtkColorWheel *color_wheel, guint32 number_of_colors); void gtk_color_wheel_set_color_wheel_type(GtkColorWheel *color_wheel, const ColorWheelType *color_wheel_type); GType gtk_color_wheel_get_type(); #endif /* GPICK_GTK_COLOR_WHEEL_H_ */ gpick-gpick-0.2.6/source/gtk/ColorWidget.cpp000066400000000000000000000353321377073231300207360ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ColorWidget.h" #include "../Color.h" #include "../MathUtil.h" #include #include #include using namespace std; #define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), GTK_TYPE_COLOR, GtkColorPrivate)) G_DEFINE_TYPE(GtkColor, gtk_color, GTK_TYPE_DRAWING_AREA); static gboolean button_release(GtkWidget *widget, GdkEventButton *event); static gboolean button_press(GtkWidget *widget, GdkEventButton *event); static void finalize(GObject *color_obj); #if GTK_MAJOR_VERSION >= 3 static gboolean draw(GtkWidget *widget, cairo_t *cr); #else static gboolean expose(GtkWidget *widget, GdkEventExpose *event); static void size_request(GtkWidget *widget, GtkRequisition *requisition); #endif enum { ACTIVATED, LAST_SIGNAL, }; static guint signals[LAST_SIGNAL] = {}; struct GtkColorPrivate { Color color, text_color, split_color; std::string text; bool rounded_rectangle, h_center, split; bool secondary_color; double roundness; transformation::Chain *transformation_chain; }; static void gtk_color_class_init(GtkColorClass *color_class) { GObjectClass *obj_class = G_OBJECT_CLASS(color_class); obj_class->finalize = finalize; g_type_class_add_private(obj_class, sizeof(GtkColorPrivate)); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(color_class); widget_class->button_release_event = button_release; widget_class->button_press_event = button_press; #if GTK_MAJOR_VERSION >= 3 widget_class->draw = draw; #else widget_class->expose_event = expose; widget_class->size_request = size_request; #endif signals[ACTIVATED] = g_signal_new("activated", G_OBJECT_CLASS_TYPE(obj_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkColorClass, activated), nullptr, nullptr, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } static void gtk_color_init(GtkColor *color) { gtk_widget_add_events (GTK_WIDGET (color), GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK | GDK_2BUTTON_PRESS | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); } GtkWidget* gtk_color_new() { GtkWidget* widget = (GtkWidget*)g_object_new(GTK_TYPE_COLOR, nullptr); GtkColorPrivate *ns = GET_PRIVATE(widget); new (ns) GtkColorPrivate(); color_set(&ns->color, 0); color_set(&ns->text_color, 0); color_set(&ns->split_color, 0); ns->rounded_rectangle = false; ns->h_center = false; ns->secondary_color = false; ns->split = false; ns->roundness = 20; ns->transformation_chain = 0; gtk_widget_set_can_focus(widget, true); #if GTK_MAJOR_VERSION >= 3 gtk_widget_set_size_request(GTK_WIDGET(widget), 32, 16); #endif return widget; } GtkWidget* gtk_color_new(const Color &color, ColorWidgetConfiguration configuration) { GtkWidget* widget = (GtkWidget*)g_object_new(GTK_TYPE_COLOR, nullptr); GtkColorPrivate *ns = GET_PRIVATE(widget); new (ns) GtkColorPrivate(); color_set(&ns->text_color, 0); color_set(&ns->split_color, 0); ns->color = color; ns->rounded_rectangle = true; ns->h_center = true; ns->secondary_color = false; ns->split = false; ns->roundness = 5; ns->transformation_chain = 0; gtk_widget_set_can_focus(widget, true); #if GTK_MAJOR_VERSION >= 3 gtk_widget_set_size_request(GTK_WIDGET(widget), 32, 16); #endif return widget; } #if GTK_MAJOR_VERSION < 3 static void size_request(GtkWidget *widget, GtkRequisition *requisition) { GtkColorPrivate *ns = GET_PRIVATE(widget); gint width = 32 + widget->style->xthickness * 2; gint height = 16 + widget->style->ythickness * 2; if (ns->rounded_rectangle){ width += ns->roundness; height += ns->roundness; } requisition->width = width; requisition->height = height; } #endif static void finalize(GObject *color_obj) { GtkColorPrivate *ns = GET_PRIVATE(color_obj); ns->~GtkColorPrivate(); gpointer parent_class = g_type_class_peek_parent(G_OBJECT_CLASS(GTK_COLOR_GET_CLASS(color_obj))); G_OBJECT_CLASS(parent_class)->finalize(color_obj); } void gtk_color_get_color(GtkColor* widget, Color* color) { GtkColorPrivate *ns = GET_PRIVATE(widget); color_copy(&ns->color, color); } void gtk_color_set_text_color(GtkColor* widget, Color* color) { GtkColorPrivate *ns = GET_PRIVATE(widget); color_copy(color, &ns->text_color); gtk_widget_queue_draw(GTK_WIDGET(widget)); } void gtk_color_set_roundness(GtkColor* widget, double roundness) { GtkColorPrivate *ns = GET_PRIVATE(widget); ns->roundness = roundness; gint width = 32; gint height = 16; #if GTK_MAJOR_VERSION < 3 width += GTK_WIDGET(widget)->style->xthickness * 2; height += GTK_WIDGET(widget)->style->ythickness * 2; #endif if (ns->rounded_rectangle){ width += ns->roundness; height += ns->roundness; } gtk_widget_set_size_request(GTK_WIDGET(widget), width, height); gtk_widget_queue_draw(GTK_WIDGET(widget)); } void gtk_color_set_color(GtkColor* widget, const Color &color) { GtkColorPrivate *ns = GET_PRIVATE(widget); color_copy(&color, &ns->color); if (ns->transformation_chain){ Color c; ns->transformation_chain->apply(&ns->color, &c); color_get_contrasting(&c, &ns->text_color); }else{ color_get_contrasting(&ns->color, &ns->text_color); } gtk_widget_queue_draw(GTK_WIDGET(widget)); } void gtk_color_set_color(GtkColor* widget, const Color &color, const std::string &text) { GtkColorPrivate *ns = GET_PRIVATE(widget); color_copy(&color, &ns->color); if (ns->secondary_color){ }else{ if (ns->transformation_chain){ Color c; ns->transformation_chain->apply(&ns->color, &c); color_get_contrasting(&c, &ns->text_color); }else{ color_get_contrasting(&ns->color, &ns->text_color); } } ns->text = text; gtk_widget_queue_draw(GTK_WIDGET(widget)); } void gtk_color_set_text(GtkColor* widget, const std::string &text) { GtkColorPrivate *ns = GET_PRIVATE(widget); ns->text = text; gtk_widget_queue_draw(GTK_WIDGET(widget)); } void gtk_color_set_color(GtkColor* widget, const Color* color, const char* text) { GtkColorPrivate *ns = GET_PRIVATE(widget); color_copy(color, &ns->color); if (ns->secondary_color){ }else{ if (ns->transformation_chain){ Color c; ns->transformation_chain->apply(&ns->color, &c); color_get_contrasting(&c, &ns->text_color); }else{ color_get_contrasting(&ns->color, &ns->text_color); } } ns->text = text; gtk_widget_queue_draw(GTK_WIDGET(widget)); } void gtk_color_set_rounded(GtkColor* widget, bool rounded_rectangle) { GtkColorPrivate *ns = GET_PRIVATE(widget); ns->rounded_rectangle = rounded_rectangle; gtk_widget_queue_draw(GTK_WIDGET(widget)); } void gtk_color_set_hcenter(GtkColor* widget, bool hcenter) { GtkColorPrivate *ns = GET_PRIVATE(widget); ns->h_center = hcenter; gtk_widget_queue_draw(GTK_WIDGET(widget)); } static void cairo_rounded_rectangle(cairo_t *cr, double x, double y, double width, double height, double roundness) { double strength = 0.3; cairo_new_path(cr); cairo_move_to(cr, x+roundness, y); cairo_line_to(cr, x+width-roundness, y); cairo_curve_to(cr, x+width-roundness*strength, y, x+width, y+roundness*strength, x+width, y+roundness); cairo_line_to(cr, x+width, y+height-roundness); cairo_curve_to(cr, x+width, y+height-roundness*strength, x+width-roundness*strength, y+height, x+width-roundness, y+height); cairo_line_to(cr, x+roundness, y+height); cairo_curve_to(cr, x+roundness*strength, y+height, x, y+height-roundness*strength, x, y+height-roundness); cairo_line_to(cr, x, y+roundness); cairo_curve_to(cr, x, y+roundness*strength, x+roundness*strength, y, x+roundness, y); cairo_close_path(cr); } static void cairo_split_rectangle(cairo_t *cr, double x, double y, double width, double height, double tilt) { cairo_new_path(cr); cairo_move_to(cr, x, y + height / 2); cairo_line_to(cr, x + width, y + height / 2 + tilt); cairo_line_to(cr, x + width, y + height); cairo_line_to(cr, x, y + height); cairo_line_to(cr, x, y + height / 2); cairo_close_path(cr); } static void cairo_set_color(cairo_t *cr, Color &color) { using namespace boost::math; cairo_set_source_rgb(cr, round(color.rgb.red * 255.0) / 255.0, round(color.rgb.green * 255.0) / 255.0, round(color.rgb.blue * 255.0) / 255.0); } static gboolean draw(GtkWidget *widget, cairo_t *cr) { GtkColorPrivate *ns = GET_PRIVATE(widget); Color color, split_color; #if GTK_MAJOR_VERSION >= 3 int width = gtk_widget_get_allocated_width(widget), height = gtk_widget_get_allocated_height(widget); #else GtkAllocation rectangle; gtk_widget_get_allocation(widget, &rectangle); int width = rectangle.width - widget->style->xthickness * 2 - 1, height = rectangle.height - widget->style->ythickness * 2 - 1; #endif bool sensitive = gtk_widget_get_sensitive(widget); if (ns->transformation_chain){ ns->transformation_chain->apply(&ns->color, &color); if (ns->split){ ns->transformation_chain->apply(&ns->split_color, &split_color); } }else{ color_copy(&ns->color, &color); if (ns->split){ color_copy(&ns->split_color, &split_color); } } if (ns->rounded_rectangle){ if (sensitive){ cairo_rounded_rectangle(cr, 0, 0, width, height, ns->roundness); cairo_set_color(cr, color); cairo_fill(cr); } if (ns->split && sensitive){ cairo_save(cr); cairo_split_rectangle(cr, 0, 0, width, height, height / 6); cairo_clip_preserve(cr); cairo_rounded_rectangle(cr, 0, 0, width, height, ns->roundness); cairo_set_color(cr, split_color); cairo_fill(cr); cairo_restore(cr); } cairo_rounded_rectangle(cr, 0, 0, width, height, ns->roundness); if (gtk_widget_has_focus(widget)){ #if GTK_MAJOR_VERSION >= 3 //TODO: GTK3 get border color #else cairo_set_source_rgb(cr, widget->style->fg[GTK_STATE_NORMAL].red / 65536.0, widget->style->fg[GTK_STATE_NORMAL].green / 65536.0, widget->style->fg[GTK_STATE_NORMAL].blue / 65536.0); #endif cairo_set_line_width(cr, 3); }else{ if (sensitive) { cairo_set_source_rgb(cr, 0, 0, 0); } else { cairo_set_source_rgba(cr, 0, 0, 0, 0.33f); } cairo_set_line_width(cr, 1); } cairo_stroke(cr); }else{ if (ns->split && sensitive){ cairo_save(cr); cairo_split_rectangle(cr, 0, 0, width, height, height / 6); cairo_clip_preserve(cr); cairo_rounded_rectangle(cr, 0, 0, width, height, ns->roundness); cairo_set_color(cr, split_color); cairo_fill(cr); cairo_restore(cr); } if (sensitive){ cairo_set_color(cr, color); cairo_paint(cr); } } if (sensitive && !ns->text.empty()){ PangoLayout *layout; PangoFontDescription *font_description; font_description = pango_font_description_new(); layout = pango_cairo_create_layout(cr); pango_font_description_set_family(font_description, "monospace"); pango_font_description_set_weight(font_description, PANGO_WEIGHT_NORMAL); pango_font_description_set_absolute_size(font_description, 14 * PANGO_SCALE); pango_layout_set_font_description(layout, font_description); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); if (ns->transformation_chain){ if (ns->secondary_color){ ns->transformation_chain->apply(&ns->text_color, &color); }else{ color_copy(&ns->text_color, &color); } }else{ color_copy(&ns->text_color, &color); } cairo_set_color(cr, color); pango_layout_set_markup(layout, ns->text.c_str(), -1); pango_layout_set_width(layout, (width - 10) * PANGO_SCALE); pango_layout_set_height(layout, height * PANGO_SCALE); int layout_width, layout_height; pango_layout_get_pixel_size(layout, &layout_width, &layout_height); cairo_move_to(cr, 5, (height - layout_height) / 2); if (ns->h_center) pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); else pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); pango_cairo_update_layout(cr, layout); pango_cairo_show_layout(cr, layout); g_object_unref(layout); pango_font_description_free(font_description); } return FALSE; } #if GTK_MAJOR_VERSION < 3 static gboolean expose(GtkWidget *widget, GdkEventExpose *event) { cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_rectangle(cr, event->area.x, event->area.y, event->area.width, event->area.height); cairo_clip(cr); cairo_translate(cr, widget->style->xthickness + 0.5, widget->style->ythickness + 0.5); gboolean result = draw(widget, cr); cairo_destroy(cr); return result; } #endif static gboolean button_release(GtkWidget *widget, GdkEventButton *event) { gtk_widget_grab_focus(widget); return FALSE; } static gboolean button_press(GtkWidget *widget, GdkEventButton *event) { gtk_widget_grab_focus(widget); if ((event->type == GDK_2BUTTON_PRESS) && (event->button == 1)) { g_signal_emit(widget, signals[ACTIVATED], 0); } return FALSE; } void gtk_color_set_transformation_chain(GtkColor* widget, transformation::Chain *chain) { GtkColorPrivate *ns = GET_PRIVATE(widget); ns->transformation_chain = chain; if (!ns->secondary_color){ if (ns->transformation_chain){ Color c; ns->transformation_chain->apply(&ns->color, &c); color_get_contrasting(&c, &ns->text_color); }else{ color_get_contrasting(&ns->color, &ns->text_color); } } gtk_widget_queue_draw(GTK_WIDGET(widget)); } void gtk_color_set_split_color(GtkColor* widget, const Color* color) { GtkColorPrivate *ns = GET_PRIVATE(widget); color_copy(color, &ns->split_color); gtk_widget_queue_draw(GTK_WIDGET(widget)); } void gtk_color_get_split_color(GtkColor* widget, Color* color) { GtkColorPrivate *ns = GET_PRIVATE(widget); color_copy(&ns->split_color, color); } void gtk_color_enable_split(GtkColor* widget, bool enable) { GtkColorPrivate *ns = GET_PRIVATE(widget); ns->split = enable; gtk_widget_queue_draw(GTK_WIDGET(widget)); } gpick-gpick-0.2.6/source/gtk/ColorWidget.h000066400000000000000000000066531377073231300204070ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_GTK_COLOR_WIDGET_H_ #define GPICK_GTK_COLOR_WIDGET_H_ #include #include #include "../Color.h" #include "../transformation/Chain.h" #define GTK_TYPE_COLOR (gtk_color_get_type()) #define GTK_COLOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_COLOR, GtkColor)) #define GTK_COLOR_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST((obj), GTK_COLOR, GtkColorClass)) #define GTK_IS_COLOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_COLOR)) #define GTK_IS_COLOR_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((obj), GTK_TYPE_COLOR)) #define GTK_COLOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_COLOR, GtkColorClass)) struct GtkColor { GtkDrawingArea parent; }; struct GtkColorClass { GtkDrawingAreaClass parent_class; void (*activated)(GtkWidget* widget, gpointer userdata); }; GtkWidget* gtk_color_new(); enum class ColorWidgetConfiguration { standard, }; GtkWidget* gtk_color_new(const Color &color, ColorWidgetConfiguration configuration); void gtk_color_set_color(GtkColor* widget, const Color* color, const char* text); void gtk_color_set_color(GtkColor* widget, const Color &color); void gtk_color_set_color(GtkColor* widget, const Color &color, const std::string &text); void gtk_color_set_text(GtkColor* widget, const std::string &text); void gtk_color_set_text_color(GtkColor* widget, Color* color); void gtk_color_get_color(GtkColor* widget, Color* color); void gtk_color_set_rounded(GtkColor* widget, bool rounded_rectangle); void gtk_color_set_roundness(GtkColor* widget, double roundness); void gtk_color_set_hcenter(GtkColor* widget, bool hcenter); void gtk_color_set_transformation_chain(GtkColor* widget, transformation::Chain *chain); void gtk_color_set_split_color(GtkColor* widget, const Color* color); void gtk_color_get_split_color(GtkColor* widget, Color* color); void gtk_color_enable_split(GtkColor* widget, bool enable); GType gtk_color_get_type(); #endif /* GPICK_GTK_COLOR_WIDGET_H_ */ gpick-gpick-0.2.6/source/gtk/LayoutPreview.cpp000066400000000000000000000224341377073231300213320ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "LayoutPreview.h" #include "../layout/System.h" #include "../transformation/Chain.h" #include "../Rect2.h" #include #include using namespace std; using namespace math; using namespace layout; #define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), GTK_TYPE_LAYOUT_PREVIEW, GtkLayoutPreviewPrivate)) G_DEFINE_TYPE(GtkLayoutPreview, gtk_layout_preview, GTK_TYPE_DRAWING_AREA); static gboolean button_release(GtkWidget *layout_preview, GdkEventButton *event); static gboolean button_press(GtkWidget *layout_preview, GdkEventButton *event); #if GTK_MAJOR_VERSION >= 3 static gboolean draw(GtkWidget *widget, cairo_t *cr); #else static gboolean expose(GtkWidget *layout_preview, GdkEventExpose *event); #endif enum { COLOR_CHANGED, EMPTY, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = {}; struct GtkLayoutPreviewPrivate { System *system; Rect2 area; Style* selected_style; Box* selected_box; transformation::Chain *transformation_chain; }; static void gtk_layout_preview_class_init(GtkLayoutPreviewClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS(klass); g_type_class_add_private(obj_class, sizeof(GtkLayoutPreviewPrivate)); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); widget_class->button_release_event = button_release; widget_class->button_press_event = button_press; #if GTK_MAJOR_VERSION >= 3 widget_class->draw = draw; #else widget_class->expose_event = expose; #endif signals[COLOR_CHANGED] = g_signal_new("color_changed", G_OBJECT_CLASS_TYPE(obj_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkLayoutPreviewClass, color_changed), nullptr, nullptr, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); } static void gtk_layout_preview_init(GtkLayoutPreview *layout_preview) { gtk_widget_add_events(GTK_WIDGET(layout_preview), GDK_2BUTTON_PRESS | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); } static void destroy(GtkLayoutPreview *widget) { GtkLayoutPreviewPrivate *ns = GET_PRIVATE(widget); if (ns->system) System::unref(ns->system); } GtkWidget* gtk_layout_preview_new() { GtkWidget* widget = (GtkWidget*)g_object_new(GTK_TYPE_LAYOUT_PREVIEW, nullptr); GtkLayoutPreviewPrivate *ns = GET_PRIVATE(widget); ns->area = Rect2(0, 0, 1, 1); ns->selected_style = nullptr; ns->selected_box = nullptr; ns->system = nullptr; ns->transformation_chain = nullptr; g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(destroy), nullptr); gtk_widget_set_can_focus(widget, true); return widget; } static bool set_selected_box(GtkLayoutPreviewPrivate *ns, Box* box) { bool changed = false; if (box && box->style){ if (ns->selected_style) ns->selected_style->SetState(false, 0); ns->selected_style = box->style; ns->selected_style->SetState(true, box); if (ns->selected_box != box) changed=true; ns->selected_box = box; }else{ if (ns->selected_style){ ns->selected_style->SetState(false, 0); changed = true; } ns->selected_style = 0; ns->selected_box = 0; } return changed; } static gboolean draw(GtkWidget *widget, cairo_t *cr) { GtkLayoutPreviewPrivate *ns = GET_PRIVATE(widget); if (ns->system && ns->system->box){ ns->area = Rect2(0, 0, 1, 1); layout::Context context(cr, ns->transformation_chain); ns->system->box->Draw(&context, ns->area); } return true; } #if GTK_MAJOR_VERSION < 3 static gboolean expose(GtkWidget *widget, GdkEventExpose *event) { GtkLayoutPreviewPrivate *ns = GET_PRIVATE(widget); cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_rectangle(cr, event->area.x, event->area.y, event->area.width, event->area.height); cairo_clip(cr); gboolean result = draw(widget, cr); cairo_destroy(cr); return result; } #endif static gboolean button_release(GtkWidget *layout_preview, GdkEventButton *event){ return true; } static gboolean button_press(GtkWidget *widget, GdkEventButton *event) { gtk_widget_grab_focus(widget); GtkLayoutPreviewPrivate *ns = GET_PRIVATE(widget); if (ns->system){ Vec2 point = Vec2((event->x-ns->area.getX()) / ns->area.getWidth(), (event->y-ns->area.getY()) / ns->area.getHeight()); if (set_selected_box(ns, ns->system->GetBoxAt(point))){ gtk_widget_queue_draw(GTK_WIDGET(widget)); } } return false; } int gtk_layout_preview_set_system(GtkLayoutPreview* widget, System* system) { GtkLayoutPreviewPrivate *ns = GET_PRIVATE(widget); if (ns->system){ System::unref(ns->system); } if (system){ ns->system = static_cast(system->ref()); if (ns->system->box) gtk_widget_set_size_request(GTK_WIDGET(widget), ns->system->box->rect.getWidth(), ns->system->box->rect.getHeight()); }else ns->system = 0; return 0; } int gtk_layout_preview_set_color_at(GtkLayoutPreview* widget, Color* color, gdouble x, gdouble y) { GtkLayoutPreviewPrivate *ns = GET_PRIVATE(widget); if (!ns->system) return -1; Vec2 point = Vec2((x-ns->area.getX()) / ns->area.getWidth(), (y-ns->area.getY()) / ns->area.getHeight()); Box* box = ns->system->GetBoxAt(point); if (box && box->style && !box->locked){ color_copy(color, &box->style->color); gtk_widget_queue_draw(GTK_WIDGET(widget)); return 0; } return -1; } int gtk_layout_preview_set_color_named(GtkLayoutPreview* widget, Color* color, const char *name) { GtkLayoutPreviewPrivate *ns = GET_PRIVATE(widget); if (!ns->system) return -1; Box* box = ns->system->GetNamedBox(name); if (box && box->style && !box->locked){ color_copy(color, &box->style->color); gtk_widget_queue_draw(GTK_WIDGET(widget)); return 0; } return -1; } int gtk_layout_preview_set_focus_named(GtkLayoutPreview* widget, const char *name) { GtkLayoutPreviewPrivate *ns = GET_PRIVATE(widget); if (!ns->system) return -1; Box* box; if (set_selected_box(ns, box = ns->system->GetNamedBox(name))){ gtk_widget_queue_draw(GTK_WIDGET(widget)); return (box)?(0):(-1); } return -1; } int gtk_layout_preview_set_focus_at(GtkLayoutPreview* widget, gdouble x, gdouble y) { GtkLayoutPreviewPrivate *ns = GET_PRIVATE(widget); if (!ns->system) return -1; Vec2 point = Vec2((x-ns->area.getX()) / ns->area.getWidth(), (y-ns->area.getY()) / ns->area.getHeight()); Box* box; if (set_selected_box(ns, box = ns->system->GetBoxAt(point))){ gtk_widget_queue_draw(GTK_WIDGET(widget)); return (box)?(0):(-1); } return -1; } int gtk_layout_preview_get_current_style(GtkLayoutPreview* widget, Style** style) { GtkLayoutPreviewPrivate *ns = GET_PRIVATE(widget); if (ns->system && ns->selected_style){ *style = ns->selected_style; return 0; } return -1; } int gtk_layout_preview_get_current_color(GtkLayoutPreview* widget, Color* color) { GtkLayoutPreviewPrivate *ns = GET_PRIVATE(widget); if (ns->system && ns->selected_style){ Box* box = ns->selected_box; color_copy(&box->style->color, color); return 0; } return -1; } int gtk_layout_preview_set_current_color(GtkLayoutPreview* widget, Color* color) { GtkLayoutPreviewPrivate *ns = GET_PRIVATE(widget); if (ns->system && ns->selected_style && !ns->selected_box->locked){ Box* box = ns->selected_box; color_copy(color, &box->style->color); gtk_widget_queue_draw(GTK_WIDGET(widget)); return 0; } return -1; } bool gtk_layout_preview_is_selected(GtkLayoutPreview* widget) { GtkLayoutPreviewPrivate *ns = GET_PRIVATE(widget); if (ns->system && ns->selected_style && ns->selected_box){ return true; } return false; } bool gtk_layout_preview_is_editable(GtkLayoutPreview* widget) { GtkLayoutPreviewPrivate *ns = GET_PRIVATE(widget); if (ns->system && ns->selected_style && ns->selected_box){ return !ns->selected_box->locked; } return false; } void gtk_layout_preview_set_transformation_chain(GtkLayoutPreview* widget, transformation::Chain *chain) { GtkLayoutPreviewPrivate *ns = GET_PRIVATE(widget); ns->transformation_chain = chain; gtk_widget_queue_draw(GTK_WIDGET(widget)); } gpick-gpick-0.2.6/source/gtk/LayoutPreview.h000066400000000000000000000072431377073231300210000ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_GTK_LAYOUT_PREVIEW_H_ #define GPICK_GTK_LAYOUT_PREVIEW_H_ #include #include "../ColorObject.h" #include "../layout/System.h" #include "../transformation/Chain.h" #define GTK_TYPE_LAYOUT_PREVIEW (gtk_layout_preview_get_type()) #define GTK_LAYOUT_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_LAYOUT_PREVIEW, GtkLayoutPreview)) #define GTK_LAYOUT_PREVIEW_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST((obj), GTK_LAYOUT_PREVIEW, GtkLayoutPreviewClass)) #define GTK_IS_LAYOUT_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_LAYOUT_PREVIEW)) #define GTK_IS_LAYOUT_PREVIEW_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((obj), GTK_TYPE_LAYOUT_PREVIEW)) #define GTK_LAYOUT_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_LAYOUT_PREVIEW, GtkLayoutPreviewClass)) struct GtkLayoutPreview { GtkDrawingArea parent; }; struct GtkLayoutPreviewClass { GtkDrawingAreaClass parent_class; void (* active_color_changed)(GtkWidget* widget, gint32 active_color, gpointer userdata); void (* color_changed)(GtkWidget* widget, gpointer userdata); void (* color_activated)(GtkWidget* widget, gpointer userdata); }; GtkWidget* gtk_layout_preview_new(); GType gtk_layout_preview_get_type(); int gtk_layout_preview_set_system(GtkLayoutPreview* widget, layout::System* system); int gtk_layout_preview_set_color_at(GtkLayoutPreview* widget, Color* color, gdouble x, gdouble y); int gtk_layout_preview_set_focus_at(GtkLayoutPreview* widget, gdouble x, gdouble y); int gtk_layout_preview_set_focus_named(GtkLayoutPreview* widget, const char *name); int gtk_layout_preview_set_color_named(GtkLayoutPreview* widget, Color* color, const char *name); int gtk_layout_preview_get_current_color(GtkLayoutPreview* widget, Color* color); int gtk_layout_preview_set_current_color(GtkLayoutPreview* widget, Color* color); bool gtk_layout_preview_is_selected(GtkLayoutPreview* widget); bool gtk_layout_preview_is_editable(GtkLayoutPreview* widget); int gtk_layout_preview_get_current_style(GtkLayoutPreview* widget, layout::Style** style); void gtk_layout_preview_set_transformation_chain(GtkLayoutPreview* widget, transformation::Chain *chain); #endif /* GPICK_GTK_LAYOUT_PREVIEW_H_ */ gpick-gpick-0.2.6/source/gtk/Range2D.cpp000066400000000000000000000267071377073231300177440ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Range2D.h" #include "../Color.h" #include "../MathUtil.h" #include #ifdef _MSC_VER #define M_PI 3.14159265359 #endif #include using namespace std; #define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_RANGE_2D, GtkRange2DPrivate)) G_DEFINE_TYPE (GtkRange2D, gtk_range_2d, GTK_TYPE_DRAWING_AREA); static gboolean button_release(GtkWidget *range_2d, GdkEventButton *event); static gboolean button_press(GtkWidget *range_2d, GdkEventButton *event); static gboolean motion_notify(GtkWidget *widget, GdkEventMotion *event); #if GTK_MAJOR_VERSION >= 3 static gboolean draw(GtkWidget *widget, cairo_t *cr); #else static gboolean expose(GtkWidget *range_2d, GdkEventExpose *event); #endif enum { VALUES_CHANGED, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = {}; struct GtkRange2DPrivate { double x; double y; char *xname; char *yname; double block_size; bool grab_block; cairo_surface_t *cache_range_2d; #if GTK_MAJOR_VERSION >= 3 GdkDevice *pointer_grab; #endif }; static void finalize(GObject *range_2d_obj) { GtkRange2DPrivate *ns = GET_PRIVATE(range_2d_obj); if (ns->xname) g_free(ns->xname); if (ns->yname) g_free(ns->yname); if (ns->cache_range_2d){ cairo_surface_destroy(ns->cache_range_2d); ns->cache_range_2d = 0; } gpointer parent_class = g_type_class_peek_parent(G_OBJECT_CLASS(GTK_RANGE_2D_GET_CLASS(range_2d_obj))); G_OBJECT_CLASS(parent_class)->finalize(range_2d_obj); } static void gtk_range_2d_class_init(GtkRange2DClass *range_2d_class) { GObjectClass *obj_class = G_OBJECT_CLASS(range_2d_class); obj_class->finalize = finalize; g_type_class_add_private(obj_class, sizeof(GtkRange2DPrivate)); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(range_2d_class); widget_class->button_release_event = button_release; widget_class->button_press_event = button_press; widget_class->motion_notify_event = motion_notify; #if GTK_MAJOR_VERSION >= 3 widget_class->draw = draw; #else widget_class->expose_event = expose; #endif signals[VALUES_CHANGED] = g_signal_new("values_changed", G_OBJECT_CLASS_TYPE(obj_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkRange2DClass, values_changed), nullptr, nullptr, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } static void gtk_range_2d_init(GtkRange2D *range_2d) { gtk_widget_add_events(GTK_WIDGET(range_2d), GDK_2BUTTON_PRESS | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); } GtkWidget* gtk_range_2d_new() { GtkWidget* widget = (GtkWidget*) g_object_new(GTK_TYPE_RANGE_2D, nullptr); GtkRange2DPrivate *ns = GET_PRIVATE(widget); ns->block_size = 128; ns->grab_block = false; ns->xname = 0; ns->yname = 0; #if GTK_MAJOR_VERSION >= 3 gtk_widget_set_size_request(GTK_WIDGET(widget), ns->block_size, ns->block_size); #else gtk_widget_set_size_request(GTK_WIDGET(widget), ns->block_size + widget->style->xthickness * 2, ns->block_size + widget->style->ythickness * 2); #endif ns->cache_range_2d = 0; #if GTK_MAJOR_VERSION >= 3 ns->pointer_grab = nullptr; #endif gtk_widget_set_can_focus(widget, true); return widget; } void gtk_range_2d_set_values(GtkRange2D* range_2d, double x, double y) { GtkRange2DPrivate *ns = GET_PRIVATE(range_2d); ns->x = x; ns->y = 1 - y; gtk_widget_queue_draw(GTK_WIDGET(range_2d)); } double gtk_range_2d_get_x(GtkRange2D* range_2d) { GtkRange2DPrivate *ns = GET_PRIVATE(range_2d); return ns->x; } double gtk_range_2d_get_y(GtkRange2D* range_2d) { GtkRange2DPrivate *ns = GET_PRIVATE(range_2d); return 1 - ns->y; } static void draw_dot(cairo_t *cr, double x, double y, double size) { cairo_arc(cr, x, y, size - 1, 0, 2 * M_PI); cairo_set_source_rgba(cr, 1, 1, 1, 0.5); cairo_set_line_width(cr, 2); cairo_stroke(cr); cairo_arc(cr, x, y, size, 0, 2 * M_PI); cairo_set_source_rgba(cr, 0, 0, 0, 1); cairo_set_line_width(cr, 1); cairo_stroke(cr); } static void draw_sat_val_block(GtkRange2DPrivate *ns, cairo_t *cr, double pos_x, double pos_y, double size) { cairo_surface_t *surface; if (ns->cache_range_2d){ surface = ns->cache_range_2d; }else{ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ceil(size), ceil(size)); unsigned char *data = cairo_image_surface_get_data(surface); int stride = cairo_image_surface_get_stride(surface); int surface_width = cairo_image_surface_get_width(surface); int surface_height = cairo_image_surface_get_height(surface); float v; unsigned char *line_data; for (int y = 0; y < surface_height; ++y){ line_data = data + stride * y; for (int x = 0; x < surface_width; ++x){ if ((x % 16 < 8) ^ (y % 16 < 8) ){ v = mix_float(0.5, 1.0, pow(x / size, 2)); }else{ v = mix_float(0.5, 0.0, pow(1 - (y / size), 2)); } line_data[2] = v * 255; line_data[1] = v / 2 * 255; line_data[0] = v / 4 * 255; line_data[3] = 0xFF; line_data += 4; } } ns->cache_range_2d = surface; } cairo_surface_mark_dirty(surface); cairo_save(cr); cairo_set_source_surface(cr, surface, pos_x, pos_y); cairo_rectangle(cr, pos_x, pos_y, size, size); cairo_fill(cr); cairo_restore(cr); } static gboolean motion_notify(GtkWidget *widget, GdkEventMotion *event) { GtkRange2DPrivate *ns = GET_PRIVATE(widget); if (ns->grab_block){ #if GTK_MAJOR_VERSION >= 3 double dx = event->x; double dy = event->y; #else double dx = (event->x - widget->style->xthickness); double dy = (event->y - widget->style->ythickness); #endif ns->x = clamp_float(dx / ns->block_size, 0, 1); ns->y = clamp_float(dy / ns->block_size, 0, 1); g_signal_emit(widget, signals[VALUES_CHANGED], 0); gtk_widget_queue_draw(widget); return true; } return false; } static gboolean draw(GtkWidget *widget, cairo_t *cr) { GtkRange2DPrivate *ns = GET_PRIVATE(widget); draw_sat_val_block(ns, cr, 0, 0, ns->block_size); draw_dot(cr, ns->block_size * ns->x, ns->block_size * ns->y, 6); if (ns->xname){ PangoLayout *layout; PangoFontDescription *font_description; font_description = pango_font_description_new(); layout = pango_cairo_create_layout(cr); pango_font_description_set_family(font_description, "monospace"); pango_font_description_set_weight(font_description, PANGO_WEIGHT_NORMAL); pango_font_description_set_absolute_size(font_description, 12 * PANGO_SCALE); pango_layout_set_font_description(layout, font_description); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); cairo_set_source_rgb(cr, 1, 1, 1); pango_layout_set_text(layout, ns->xname, -1); #if GTK_MAJOR_VERSION >= 3 int width = gtk_widget_get_allocated_width(widget), height = gtk_widget_get_allocated_height(widget); int padding_x = 0, padding_y = 0; #else int width = widget->allocation.width, height = widget->allocation.height; int padding_x = widget->style->xthickness, padding_y = widget->style->ythickness; #endif pango_layout_set_width(layout, (width - padding_x * 2) * PANGO_SCALE); pango_layout_set_height(layout, (height - padding_y * 2) * PANGO_SCALE); pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); pango_cairo_update_layout(cr, layout); int layout_width, layout_height; pango_layout_get_pixel_size(layout, &layout_width, &layout_height); cairo_move_to(cr, 0, ns->block_size - layout_height - 1); pango_cairo_show_layout(cr, layout); PangoContext *context = pango_layout_get_context(layout); pango_context_set_gravity_hint(context, PANGO_GRAVITY_HINT_STRONG); pango_context_set_base_gravity(context, PANGO_GRAVITY_NORTH); pango_layout_context_changed(layout); pango_layout_set_text(layout, ns->yname, -1); pango_layout_get_pixel_size(layout, &layout_width, &layout_height); cairo_move_to(cr, layout_height + 1, 0); cairo_rotate(cr, 90 / (180.0 / M_PI)); pango_cairo_update_layout(cr, layout); pango_cairo_show_layout(cr, layout); g_object_unref(layout); pango_font_description_free(font_description); } return false; } #if GTK_MAJOR_VERSION < 3 static gboolean expose(GtkWidget *widget, GdkEventExpose *event) { cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_rectangle(cr, event->area.x, event->area.y, event->area.width, event->area.height); cairo_clip(cr); cairo_translate(cr, widget->style->xthickness, widget->style->ythickness); gboolean result = draw(widget, cr); cairo_destroy(cr); return result; } #endif static gboolean button_press(GtkWidget *widget, GdkEventButton *event) { GtkRange2DPrivate *ns = GET_PRIVATE(widget); gtk_widget_grab_focus(widget); if ((event->type == GDK_BUTTON_PRESS) && (event->button == 1)){ ns->grab_block = true; GdkCursor *cursor = gdk_cursor_new_for_display(gtk_widget_get_display(widget), GDK_CROSS); #if GTK_MAJOR_VERSION >= 3 ns->pointer_grab = event->device; gdk_seat_grab(gdk_device_get_seat(event->device), gtk_widget_get_window(widget), GDK_SEAT_CAPABILITY_ALL, false, cursor, nullptr, nullptr, nullptr); #else gdk_pointer_grab(gtk_widget_get_window(widget), false, GdkEventMask(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK), nullptr, cursor, GDK_CURRENT_TIME); #endif #if GTK_MAJOR_VERSION >= 3 g_object_unref(cursor); double dx = event->x; double dy = event->y; #else gdk_cursor_unref(cursor); double dx = (event->x - widget->style->xthickness); double dy = (event->y - widget->style->ythickness); #endif ns->x = clamp_float(dx / ns->block_size, 0, 1); ns->y = clamp_float(dy / ns->block_size, 0, 1); g_signal_emit(widget, signals[VALUES_CHANGED], 0); gtk_widget_queue_draw(widget); return true; } return false; } static gboolean button_release(GtkWidget *widget, GdkEventButton *event) { GtkRange2DPrivate *ns = GET_PRIVATE(widget); #if GTK_MAJOR_VERSION >= 3 if (ns->pointer_grab){ gdk_seat_ungrab(gdk_device_get_seat(ns->pointer_grab)); ns->pointer_grab = nullptr; } #else gdk_pointer_ungrab(GDK_CURRENT_TIME); #endif ns->grab_block = false; return false; } void gtk_range_2d_set_axis(GtkRange2D *range_2d, const char *x, const char *y) { GtkRange2DPrivate *ns = GET_PRIVATE(range_2d); if (ns->xname) g_free(ns->xname); ns->xname = g_strdup(x); if (ns->yname) g_free(ns->yname); ns->yname = g_strdup(y); gtk_widget_queue_draw(GTK_WIDGET(range_2d)); } gpick-gpick-0.2.6/source/gtk/Range2D.h000066400000000000000000000051711377073231300174010ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_GTK_RANGE_2D_H_ #define GPICK_GTK_RANGE_2D_H_ #include #define GTK_TYPE_RANGE_2D (gtk_range_2d_get_type ()) #define GTK_RANGE_2D(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_RANGE_2D, GtkRange2D)) #define GTK_RANGE_2D_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), GTK_RANGE_2D, GtkRange2DClass)) #define GTK_IS_RANGE_2D(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_RANGE_2D)) #define GTK_IS_RANGE_2D_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), GTK_TYPE_RANGE_2D)) #define GTK_RANGE_2D_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_RANGE_2D, GtkRange2DClass)) struct GtkRange2D { GtkDrawingArea parent; }; struct GtkRange2DClass { GtkDrawingAreaClass parent_class; void (*values_changed)(GtkWidget *widget, gpointer userdata); }; GtkWidget* gtk_range_2d_new(); void gtk_range_2d_set_values(GtkRange2D *range_2d, double x, double y); void gtk_range_2d_set_axis(GtkRange2D *range_2d, const char *x, const char *y); double gtk_range_2d_get_x(GtkRange2D *range_2d); double gtk_range_2d_get_y(GtkRange2D *range_2d); GType gtk_range_2d_get_type(); #endif /* GPICK_GTK_RANGE_2D_H_ */ gpick-gpick-0.2.6/source/gtk/Swatch.cpp000066400000000000000000000347361377073231300177540ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Swatch.h" #include "../Color.h" #include "../MathUtil.h" #include #include #define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), GTK_TYPE_SWATCH, GtkSwatchPrivate)) G_DEFINE_TYPE (GtkSwatch, gtk_swatch, GTK_TYPE_DRAWING_AREA); static gboolean button_release(GtkWidget *swatch, GdkEventButton *event); static gboolean button_press(GtkWidget *swatch, GdkEventButton *event); #if GTK_MAJOR_VERSION >= 3 static gboolean draw(GtkWidget *widget, cairo_t *cr); #else static gboolean expose(GtkWidget *widget, GdkEventExpose *event); #endif enum { ACTIVE_COLOR_CHANGED, COLOR_CHANGED, COLOR_ACTIVATED, CENTER_ACTIVATED, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = {}; struct GtkSwatchPrivate { Color color[7]; gint32 current_color; gboolean active; transformation::Chain *transformation_chain; #if GTK_MAJOR_VERSION >= 3 GtkStyleContext *context; #endif }; static void finalize(GObject *obj) { GtkSwatchPrivate *ns = GET_PRIVATE(obj); #if GTK_MAJOR_VERSION >= 3 g_object_unref(ns->context); #endif G_OBJECT_CLASS(g_type_class_peek_parent(G_OBJECT_CLASS(GTK_SWATCH_GET_CLASS(obj))))->finalize(obj); } static void gtk_swatch_class_init(GtkSwatchClass *swatch_class) { GObjectClass *obj_class = G_OBJECT_CLASS(swatch_class); obj_class->finalize = finalize; g_type_class_add_private(obj_class, sizeof(GtkSwatchPrivate)); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(swatch_class); widget_class->button_release_event = button_release; widget_class->button_press_event = button_press; #if GTK_MAJOR_VERSION >= 3 widget_class->draw = draw; #else widget_class->expose_event = expose; #endif signals[ACTIVE_COLOR_CHANGED] = g_signal_new("active_color_changed", G_OBJECT_CLASS_TYPE(obj_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkSwatchClass, active_color_changed), nullptr, nullptr, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); signals[COLOR_CHANGED] = g_signal_new("color_changed", G_OBJECT_CLASS_TYPE(obj_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkSwatchClass, color_changed), nullptr, nullptr, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[COLOR_ACTIVATED] = g_signal_new("color_activated", G_OBJECT_CLASS_TYPE(obj_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkSwatchClass, color_activated), nullptr, nullptr, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[CENTER_ACTIVATED] = g_signal_new("center_activated", G_OBJECT_CLASS_TYPE(obj_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkSwatchClass, center_activated), nullptr, nullptr, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } #if GTK_MAJOR_VERSION >= 3 static GtkStyleContext* get_style_context(GType type) { GtkWidgetPath* path = gtk_widget_path_new(); gtk_widget_path_append_type(path, type); GtkStyleContext *context = gtk_style_context_new(); gtk_style_context_set_path(context, path); gtk_widget_path_free(path); return context; } #endif static void gtk_swatch_init(GtkSwatch *swatch) { gtk_widget_add_events(GTK_WIDGET(swatch), GDK_2BUTTON_PRESS | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK); } GtkWidget* gtk_swatch_new() { GtkWidget* widget = (GtkWidget*)g_object_new(GTK_TYPE_SWATCH, nullptr); GtkSwatchPrivate *ns = GET_PRIVATE(widget); #if GTK_MAJOR_VERSION >= 3 gtk_widget_set_size_request(GTK_WIDGET(widget), 150, 136); #else gtk_widget_set_size_request(GTK_WIDGET(widget), 150 + widget->style->xthickness * 2, 136 + widget->style->ythickness * 2); #endif for (gint32 i = 0; i < 7; ++i) color_set(&ns->color[i], i / 7.0); ns->current_color = 1; ns->transformation_chain = 0; ns->active = false; #if GTK_MAJOR_VERSION >= 3 ns->context = get_style_context(GTK_TYPE_SWATCH); #endif gtk_widget_set_can_focus(widget, true); return widget; } void gtk_swatch_set_color_to_main(GtkSwatch* swatch) { GtkSwatchPrivate *ns = GET_PRIVATE(swatch); color_copy(&ns->color[0], &ns->color[ns->current_color]); gtk_widget_queue_draw(GTK_WIDGET(swatch)); } void gtk_swatch_move_active(GtkSwatch* swatch, gint32 direction) { GtkSwatchPrivate *ns = GET_PRIVATE(swatch); if (direction < 0){ if (ns->current_color == 1){ ns->current_color = 7 - 1; }else{ ns->current_color--; } }else{ ns->current_color++; if (ns->current_color >= 7) ns->current_color = 1; } } void gtk_swatch_get_color(GtkSwatch* swatch, guint32 index, Color* color) { GtkSwatchPrivate *ns = GET_PRIVATE(swatch); color_copy(&ns->color[index], color); } void gtk_swatch_get_main_color(GtkSwatch* swatch, Color* color) { GtkSwatchPrivate *ns = GET_PRIVATE(swatch); color_copy(&ns->color[0], color); } gint32 gtk_swatch_get_active_index(GtkSwatch* swatch) { GtkSwatchPrivate *ns = GET_PRIVATE(swatch); return ns->current_color; } void gtk_swatch_get_active_color(GtkSwatch* swatch, Color* color) { GtkSwatchPrivate *ns = GET_PRIVATE(swatch); color_copy(&ns->color[ns->current_color], color); } void gtk_swatch_set_color(GtkSwatch* swatch, guint32 index, Color* color) { GtkSwatchPrivate *ns = GET_PRIVATE(swatch); color_copy(color, &ns->color[index]); gtk_widget_queue_draw(GTK_WIDGET(swatch)); } void gtk_swatch_set_color(GtkSwatch* swatch, guint32 index, const Color &color) { GtkSwatchPrivate *ns = GET_PRIVATE(swatch); color_copy(&color, &ns->color[index]); gtk_widget_queue_draw(GTK_WIDGET(swatch)); } void gtk_swatch_set_main_color(GtkSwatch* swatch, Color* color) { GtkSwatchPrivate *ns = GET_PRIVATE(swatch); color_copy(color, &ns->color[0]); gtk_widget_queue_draw(GTK_WIDGET(swatch)); } void gtk_swatch_set_active_index(GtkSwatch* swatch, guint32 index) { GtkSwatchPrivate *ns = GET_PRIVATE(swatch); ns->current_color = index; gtk_widget_queue_draw(GTK_WIDGET(swatch)); } void gtk_swatch_set_active_color(GtkSwatch* swatch, Color* color) { GtkSwatchPrivate *ns = GET_PRIVATE(swatch); color_copy(color, &ns->color[ns->current_color]); gtk_widget_queue_draw(GTK_WIDGET(swatch)); } void gtk_swatch_set_main_color(GtkSwatch* swatch, guint index, Color* color) { GtkSwatchPrivate *ns = GET_PRIVATE(swatch); color_copy(color, &ns->color[0]); gtk_widget_queue_draw(GTK_WIDGET(swatch)); } static int get_color_by_position(gint x, gint y) { vector2 a, b; vector2_set(&a, 1, 0); vector2_set(&b, x - 75, y - (75 - 7)); float distance = vector2_length(&b); if (distance < 20){ //center color return 0; }else if (distance > 70){ //outside return -1; }else{ vector2_normalize(&b, &b); float angle = acos(vector2_dot(&a, &b)); if (b.y < 0) angle = 2 * PI - angle; angle += (PI / 6) * 3; if (angle < 0) angle += PI * 2; if (angle > 2 * PI) angle -= PI * 2; return 1 + (int)floor(angle / ((PI * 2) / 6)); } } gint gtk_swatch_get_color_at(GtkSwatch* swatch, gint x, gint y) { #if GTK_MAJOR_VERSION >= 3 return get_color_by_position(x, y); #else return get_color_by_position(x - GTK_WIDGET(swatch)->style->xthickness, y - GTK_WIDGET(swatch)->style->ythickness); #endif } static void draw_hexagon(cairo_t *cr, float x, float y, float radius) { cairo_new_sub_path(cr); for (int i = 0; i < 6; ++i) { cairo_line_to(cr, x + sin(i * PI / 3) * radius, y + cos(i * PI / 3) * radius); } cairo_close_path(cr); } static gboolean draw(GtkWidget *widget, cairo_t *cr) { GtkSwatchPrivate *ns = GET_PRIVATE(widget); if (gtk_widget_has_focus(widget) || ns->active){ #if GTK_MAJOR_VERSION >= 3 gtk_render_focus(ns->context, cr, 0, 0, 150, 136); #else gtk_paint_focus(widget->style, widget->window, GTK_STATE_ACTIVE, nullptr, widget, 0, widget->style->xthickness, widget->style->ythickness, 150, 136); #endif cairo_set_source_rgba(cr, 0, 0, 0, 0.5); cairo_arc(cr, 150 - 11.5, 12.5, 6, 0, 2 * PI); cairo_fill(cr); cairo_set_source_rgb(cr, 1, 0, 0); cairo_arc(cr, 150 - 12, 12, 6, 0, 2 * PI); cairo_fill(cr); } cairo_select_font_face(cr, "monospace", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cr, 12); cairo_matrix_t matrix; cairo_get_matrix(cr, &matrix); #if GTK_MAJOR_VERSION >= 3 int padding_x = 0, padding_y = 0; #else int padding_x = widget->style->xthickness, padding_y = widget->style->ythickness; #endif cairo_translate(cr, 75 + padding_x, 75 + padding_y - 7); int edges = 6; cairo_set_source_rgb(cr, 0, 0, 0); float radius_multi = 50 * cos((180 / edges) / (180 / PI)); float rotation = -(PI/6 * 4); //Draw stroke cairo_set_source_rgb(cr, 0, 0, 0); cairo_set_line_width(cr, 3); for (int i = 1; i < 7; ++i) { if (i == ns->current_color) continue; draw_hexagon(cr, radius_multi * cos(rotation + i * (2 * PI) / edges), radius_multi * sin(rotation + i * (2 * PI) / edges), 27); } cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); cairo_stroke(cr); cairo_set_source_rgb(cr, 1, 1, 1); draw_hexagon(cr, radius_multi * cos(rotation + (ns->current_color) * (2 * PI) / edges), radius_multi * sin(rotation + (ns->current_color) * (2 * PI) / edges), 27); cairo_stroke(cr); Color color; //Draw fill for (int i = 1; i < 7; ++i) { if (i == ns->current_color) continue; if (ns->transformation_chain){ ns->transformation_chain->apply(&ns->color[i], &color); }else{ color_copy(&ns->color[i], &color); } cairo_set_source_rgb(cr, boost::math::round(color.rgb.red * 255.0) / 255.0, boost::math::round(color.rgb.green * 255.0) / 255.0, boost::math::round(color.rgb.blue * 255.0) / 255.0); draw_hexagon(cr, radius_multi * cos(rotation + i * (2 * PI) / edges), radius_multi * sin(rotation + i * (2 * PI) / edges), 25.5); cairo_fill(cr); } if (ns->transformation_chain){ ns->transformation_chain->apply(&ns->color[ns->current_color], &color); }else{ color_copy(&ns->color[ns->current_color], &color); } cairo_set_source_rgb(cr, boost::math::round(color.rgb.red * 255.0) / 255.0, boost::math::round(color.rgb.green * 255.0) / 255.0, boost::math::round(color.rgb.blue * 255.0) / 255.0); draw_hexagon(cr, radius_multi * cos(rotation + (ns->current_color) * (2 * PI) / edges), radius_multi * sin(rotation + (ns->current_color) * (2 * PI) / edges), 25.5); cairo_fill(cr); //Draw center if (ns->transformation_chain){ ns->transformation_chain->apply(&ns->color[0], &color); }else{ color_copy(&ns->color[0], &color); } cairo_set_source_rgb(cr, boost::math::round(color.rgb.red * 255.0) / 255.0, boost::math::round(color.rgb.green * 255.0) / 255.0, boost::math::round(color.rgb.blue * 255.0) / 255.0); draw_hexagon(cr, 0, 0, 25.5); cairo_fill(cr); //Draw numbers char numb[2] = " "; for (int i = 1; i < 7; ++i) { Color c; if (ns->transformation_chain){ Color t; ns->transformation_chain->apply(&ns->color[i], &t); color_get_contrasting(&t, &c); }else{ color_get_contrasting(&ns->color[i], &c); } cairo_text_extents_t extends; numb[0] = '0' + i; cairo_text_extents(cr, numb, &extends); cairo_set_source_rgb(cr, boost::math::round(c.rgb.red * 255.0) / 255.0, boost::math::round(c.rgb.green * 255.0) / 255.0, boost::math::round(c.rgb.blue * 255.0) / 255.0); cairo_move_to(cr, radius_multi * cos(rotation + i * (2 * PI) / edges) - extends.width / 2, radius_multi * sin(rotation + i * (2 * PI) / edges) + extends.height / 2); cairo_show_text(cr, numb); } cairo_set_matrix(cr, &matrix); return true; } #if GTK_MAJOR_VERSION < 3 static gboolean expose(GtkWidget *widget, GdkEventExpose *event) { cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_rectangle(cr, event->area.x, event->area.y, event->area.width, event->area.height); cairo_clip(cr); cairo_translate(cr, widget->style->xthickness + 0.5, widget->style->ythickness + 0.5); gboolean result = draw(widget, cr); cairo_destroy(cr); return result; } #endif static void offset_xy(GtkWidget *widget, gint &x, gint &y) { #if GTK_MAJOR_VERSION < 3 x = x - widget->style->xthickness; y = y - widget->style->ythickness; #endif } static gboolean button_press(GtkWidget *widget, GdkEventButton *event) { GtkSwatchPrivate *ns = GET_PRIVATE(widget); int x = event->x, y = event->y; offset_xy(widget, x, y); int new_color = get_color_by_position(x, y); gtk_widget_grab_focus(widget); if ((event->type == GDK_2BUTTON_PRESS) && (event->button == 1)) { if (new_color>0){ g_signal_emit(widget, signals[COLOR_ACTIVATED], 0); } }else if ((event->type == GDK_BUTTON_PRESS) && ((event->button == 1) || (event->button == 3))) { if (new_color == 0){ g_signal_emit(widget, signals[CENTER_ACTIVATED], 0); return true; }else if (new_color<0){ g_signal_emit(widget, signals[ACTIVE_COLOR_CHANGED], 0, ns->current_color); }else{ if (new_color != ns->current_color){ ns->current_color = new_color; g_signal_emit(widget, signals[ACTIVE_COLOR_CHANGED], 0, ns->current_color); gtk_widget_queue_draw(GTK_WIDGET(widget)); } } } return false; } static gboolean button_release(GtkWidget *widget, GdkEventButton *event) { return FALSE; } void gtk_swatch_set_transformation_chain(GtkSwatch* widget, transformation::Chain *chain){ GtkSwatchPrivate *ns = GET_PRIVATE(widget); ns->transformation_chain = chain; gtk_widget_queue_draw(GTK_WIDGET(widget)); } void gtk_swatch_set_active(GtkSwatch* widget, gboolean active) { GtkSwatchPrivate *ns = GET_PRIVATE(widget); ns->active = active; gtk_widget_queue_draw(GTK_WIDGET(widget)); } gpick-gpick-0.2.6/source/gtk/Swatch.h000066400000000000000000000071471377073231300174150ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_GTK_SWATCH_H_ #define GPICK_GTK_SWATCH_H_ #include #include "../Color.h" #include "../transformation/Chain.h" #define GTK_TYPE_SWATCH (gtk_swatch_get_type()) #define GTK_SWATCH(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_SWATCH, GtkSwatch)) #define GTK_SWATCH_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST((obj), GTK_SWATCH, GtkSwatchClass)) #define GTK_IS_SWATCH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_SWATCH)) #define GTK_IS_SWATCH_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((obj), GTK_TYPE_SWATCH)) #define GTK_SWATCH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_SWATCH, GtkSwatchClass)) struct GtkSwatch { GtkDrawingArea parent; }; struct GtkSwatchClass { GtkDrawingAreaClass parent_class; void (*active_color_changed)(GtkWidget* widget, gint32 active_color, gpointer userdata); void (*color_changed)(GtkWidget* widget, gpointer userdata); void (*color_activated)(GtkWidget* widget, gpointer userdata); void (*center_activated)(GtkWidget* widget, gpointer userdata); }; GtkWidget* gtk_swatch_new(); void gtk_swatch_set_color(GtkSwatch* swatch, guint32 index, Color* color); void gtk_swatch_set_color(GtkSwatch* swatch, guint32 index, const Color &color); void gtk_swatch_set_main_color(GtkSwatch* swatch, Color* color); void gtk_swatch_set_active_index(GtkSwatch* swatch, guint32 index); void gtk_swatch_set_active_color(GtkSwatch* swatch, Color* color); void gtk_swatch_move_active(GtkSwatch* swatch, gint32 direction); void gtk_swatch_set_color_to_main(GtkSwatch* swatch); void gtk_swatch_get_color(GtkSwatch* swatch, guint32 index, Color* color); void gtk_swatch_get_main_color(GtkSwatch* swatch, Color* color); gint32 gtk_swatch_get_active_index(GtkSwatch* swatch); void gtk_swatch_get_active_color(GtkSwatch* swatch, Color* color); void gtk_swatch_set_color_count(GtkSwatch* swatch, gint32 colors); gint gtk_swatch_get_color_at(GtkSwatch* swatch, gint x, gint y); void gtk_swatch_set_transformation_chain(GtkSwatch* widget, transformation::Chain *chain); void gtk_swatch_set_active(GtkSwatch* swatch, gboolean active); GType gtk_swatch_get_type(); #endif /* GPICK_GTK_SWATCH_H_ */ gpick-gpick-0.2.6/source/gtk/Zoomed.cpp000066400000000000000000000420631377073231300177500ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Zoomed.h" #include "../Color.h" #include "../MathUtil.h" #include #include #include #include #include using namespace std; #define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), GTK_TYPE_ZOOMED, GtkZoomedPrivate)) G_DEFINE_TYPE(GtkZoomed, gtk_zoomed, GTK_TYPE_DRAWING_AREA); static void finalize(GObject *zoomed_obj); static gboolean button_press(GtkWidget *node_system, GdkEventButton *event); #if GTK_MAJOR_VERSION >= 3 static gboolean draw(GtkWidget *widget, cairo_t *cr); #else static gboolean expose(GtkWidget *widget, GdkEventExpose *event); #endif enum { COLOR_CHANGED, ACTIVATED, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; struct GtkZoomedPrivate { Color color; gfloat zoom; cairo_surface_t *surface; vector2 point; vector2 point_size; int32_t width_height; struct{ bool valid; math::Vec2 position; }marks[2]; math::Vec2 pointer; math::Rect2 screen_rect; bool fade; #if GTK_MAJOR_VERSION >= 3 GtkStyleContext *context; #endif }; static void gtk_zoomed_class_init(GtkZoomedClass *zoomed_class) { GObjectClass *obj_class = G_OBJECT_CLASS(zoomed_class); obj_class->finalize = finalize; g_type_class_add_private(obj_class, sizeof(GtkZoomedPrivate)); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(zoomed_class); widget_class->button_press_event = button_press; #if GTK_MAJOR_VERSION >= 3 widget_class->draw = draw; #else widget_class->expose_event = expose; #endif signals[ACTIVATED] = g_signal_new("activated", G_OBJECT_CLASS_TYPE(obj_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkZoomedClass, activated), nullptr, nullptr, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[COLOR_CHANGED] = g_signal_new("color-changed", G_OBJECT_CLASS_TYPE(obj_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkZoomedClass, color_changed), nullptr, nullptr, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); } static void gtk_zoomed_init(GtkZoomed *zoomed) { gtk_widget_add_events(GTK_WIDGET(zoomed), GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_MOTION_MASK | GDK_2BUTTON_PRESS); } #if GTK_MAJOR_VERSION >= 3 static GtkStyleContext* get_style_context(GType type) { GtkWidgetPath* path = gtk_widget_path_new(); gtk_widget_path_append_type(path, type); GtkStyleContext *context = gtk_style_context_new(); gtk_style_context_set_path(context, path); gtk_widget_path_free(path); return context; } #endif GtkWidget* gtk_zoomed_new() { GtkWidget* widget = (GtkWidget*)g_object_new(GTK_TYPE_ZOOMED, nullptr); GtkZoomedPrivate *ns = GET_PRIVATE(widget); ns->fade = false; ns->zoom = 20; ns->point.x = 0; ns->point.y = 0; ns->width_height = 0; ns->surface = nullptr; #if GTK_MAJOR_VERSION >= 3 ns->context = get_style_context(GTK_TYPE_ZOOMED); #endif gtk_zoomed_set_size(GTK_ZOOMED(widget), 150); return widget; } int32_t gtk_zoomed_get_size(GtkZoomed *zoomed) { GtkZoomedPrivate *ns = GET_PRIVATE(zoomed); return ns->width_height; } void gtk_zoomed_set_size(GtkZoomed *zoomed, int32_t width_height) { GtkZoomedPrivate *ns = GET_PRIVATE(zoomed); if (ns->width_height != width_height){ if (ns->surface){ cairo_surface_destroy(ns->surface); ns->surface = nullptr; } ns->width_height = width_height; ns->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ns->width_height, ns->width_height); #if GTK_MAJOR_VERSION >= 3 gtk_widget_set_size_request(GTK_WIDGET(zoomed), ns->width_height, ns->width_height); #else gtk_widget_set_size_request(GTK_WIDGET(zoomed), ns->width_height + GTK_WIDGET(zoomed)->style->xthickness * 2, ns->width_height + GTK_WIDGET(zoomed)->style->ythickness * 2); #endif } } void gtk_zoomed_set_fade(GtkZoomed* zoomed, bool fade) { GtkZoomedPrivate *ns = GET_PRIVATE(zoomed); ns->fade = fade; gtk_widget_queue_draw(GTK_WIDGET(zoomed)); } static void finalize(GObject *zoomed_obj) { GtkZoomedPrivate *ns = GET_PRIVATE(zoomed_obj); if (ns->surface){ cairo_surface_destroy(ns->surface); ns->surface = nullptr; } #if GTK_MAJOR_VERSION >= 3 g_object_unref(ns->context); #endif G_OBJECT_CLASS(g_type_class_peek_parent(G_OBJECT_CLASS(GTK_ZOOMED_GET_CLASS(zoomed_obj))))->finalize(zoomed_obj); } static double zoom_transformation(double value) { return (1 - log(1 + value * 0.01 * 3) / log((double)(1 + 3))) / 2; } void gtk_zoomed_get_current_screen_rect(GtkZoomed* zoomed, math::Rect2 *rect) { GtkZoomedPrivate *ns = GET_PRIVATE(zoomed); gtk_zoomed_get_screen_rect(zoomed, ns->pointer, ns->screen_rect, rect); } void gtk_zoomed_get_screen_rect(GtkZoomed *zoomed, math::Vec2& pointer, math::Rect2& screen_rect, math::Rect2 *rect) { GtkZoomedPrivate *ns = GET_PRIVATE(zoomed); gint32 x = pointer.x, y = pointer.y; gint32 left, right, top, bottom; gint32 area_width = uint32_t(ns->width_height * zoom_transformation(ns->zoom)); if (!area_width) area_width = 1; left = x - area_width / 2; top = y - area_width / 2; right = x + (area_width - area_width / 2); bottom = y + (area_width - area_width / 2); if (left < screen_rect.getLeft()){ right += -(left - screen_rect.getLeft()); left = screen_rect.getLeft(); } if (right > screen_rect.getRight()){ left -= right - screen_rect.getRight(); right = screen_rect.getRight(); } if (top < screen_rect.getTop()){ bottom += -(top - screen_rect.getTop()); top = screen_rect.getTop(); } if (bottom > screen_rect.getBottom()){ top -= bottom - screen_rect.getBottom(); bottom = screen_rect.getBottom(); } *rect = math::Rect2(left, top, right, bottom); } math::Vec2 gtk_zoomed_get_screen_position(GtkZoomed *zoomed, const math::Vec2& position) { GtkZoomedPrivate *ns = GET_PRIVATE(zoomed); gint32 x = ns->pointer.x, y = ns->pointer.y; gint32 left, right, top, bottom; gint32 area_width = uint32_t(ns->width_height * zoom_transformation(ns->zoom)); if (!area_width) area_width = 1; left = x - area_width / 2; top = y - area_width / 2; right = x + (area_width - area_width / 2); bottom = y + (area_width - area_width / 2); if (left < ns->screen_rect.getLeft()){ right += -(left - ns->screen_rect.getLeft()); left = ns->screen_rect.getLeft(); } if (right > ns->screen_rect.getRight()){ left -= right - ns->screen_rect.getRight(); right = ns->screen_rect.getRight(); } if (top < ns->screen_rect.getTop()){ bottom += -(top - ns->screen_rect.getTop()); top = ns->screen_rect.getTop(); } if (bottom > ns->screen_rect.getBottom()){ top -= bottom - ns->screen_rect.getBottom(); bottom = ns->screen_rect.getBottom(); } gint32 xl = ((position.x - left) * ns->width_height) / area_width; gint32 xh = (((position.x + 1) - left) * ns->width_height) / area_width; gint32 yl = ((position.y - top) * ns->width_height) / area_width; gint32 yh = (((position.y + 1) - top) * ns->width_height) / area_width; math::Vec2 result((xl + xh) / 2.0, (yl + yh) / 2.0); return result; } void gtk_zoomed_update(GtkZoomed *zoomed, math::Vec2& pointer, math::Rect2& screen_rect, math::Vec2& offset, cairo_surface_t *surface) { GtkZoomedPrivate *ns = GET_PRIVATE(zoomed); ns->pointer = pointer; ns->screen_rect = screen_rect; gint32 x = pointer.x, y = pointer.y; gint32 left, right, top, bottom; gint32 area_width = uint32_t(ns->width_height * zoom_transformation(ns->zoom)); if (!area_width) area_width = 1; left = x - area_width / 2; top = y - area_width / 2; right = x + (area_width - area_width / 2); bottom = y + (area_width - area_width / 2); if (left < ns->screen_rect.getLeft()){ right += -(left - ns->screen_rect.getLeft()); left = ns->screen_rect.getLeft(); } if (right > ns->screen_rect.getRight()){ left -= right - ns->screen_rect.getRight(); right = ns->screen_rect.getRight(); } if (top < ns->screen_rect.getTop()){ bottom += -(top - ns->screen_rect.getTop()); top = ns->screen_rect.getTop(); } if (bottom > ns->screen_rect.getBottom()){ top -= bottom - ns->screen_rect.getBottom(); bottom = ns->screen_rect.getBottom(); } gint32 xl = ((x - left) * ns->width_height) / area_width; gint32 xh = (((x + 1) - left) * ns->width_height) / area_width; gint32 yl = ((y - top) * ns->width_height) / area_width; gint32 yh = (((y + 1) - top) * ns->width_height) / area_width; ns->point.x = (xl + xh) / 2.0; ns->point.y = (yl + yh) / 2.0; ns->point_size.x = xh - xl; ns->point_size.y = yh - yl; int width = right - left; int height = bottom - top; cairo_t *cr = cairo_create(ns->surface); cairo_scale(cr, ns->width_height / (double)width, ns->width_height / (double)height); cairo_set_source_surface(cr, surface, offset.x, offset.y); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST); cairo_rectangle(cr, 0, 0, ns->width_height, ns->width_height); cairo_fill(cr); cairo_destroy(cr); gtk_widget_queue_draw(GTK_WIDGET(zoomed)); } void gtk_zoomed_set_zoom(GtkZoomed *zoomed, gfloat zoom) { GtkZoomedPrivate *ns = GET_PRIVATE(zoomed); if (zoom < 0){ ns->zoom = 0; }else if (zoom > 100){ ns->zoom = 100; }else{ ns->zoom = zoom; } gtk_widget_queue_draw(GTK_WIDGET(zoomed)); } gfloat gtk_zoomed_get_zoom(GtkZoomed* zoomed) { GtkZoomedPrivate *ns = GET_PRIVATE(zoomed); return ns->zoom; } static gboolean draw(GtkWidget *widget, cairo_t *cr) { GtkZoomedPrivate *ns = GET_PRIVATE(widget); #if GTK_MAJOR_VERSION >= 3 int padding_x = 0, padding_y = 0; gint pixbuf_x = padding_x; gint pixbuf_y = padding_y; #else int padding_x = widget->style->xthickness, padding_y = widget->style->ythickness; gint pixbuf_x = -padding_x; gint pixbuf_y = -padding_y; #endif if (ns->surface){ gint pixbuf_width = min(ns->width_height - pixbuf_x, ns->width_height); gint pixbuf_height = min(ns->width_height - pixbuf_y, ns->width_height); if (pixbuf_width > 0 && pixbuf_height > 0){ cairo_set_source_surface(cr, ns->surface, pixbuf_x, pixbuf_y); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST); if (ns->fade){ cairo_paint_with_alpha(cr, 0.2); }else{ cairo_paint(cr); } } } if (!ns->fade){ float radius; float size = vector2_length(&ns->point_size); if (size < 5){ radius = 5; }else if (size < 25){ radius = 7; }else if (size < 50){ radius = 10; }else{ radius = 15; } cairo_set_source_rgba(cr, 0, 0, 0, 0.75); cairo_arc(cr, ns->point.x, ns->point.y, radius + 0.5, -PI, PI); cairo_stroke(cr); cairo_set_source_rgba(cr, 1, 1, 1, 0.75); cairo_arc(cr, ns->point.x, ns->point.y, radius, -PI, PI); cairo_stroke(cr); } PangoLayout *layout; PangoFontDescription *font_description; font_description = pango_font_description_new(); layout = pango_cairo_create_layout(cr); pango_font_description_set_family(font_description, "sans"); pango_font_description_set_absolute_size(font_description, 12 * PANGO_SCALE); pango_layout_set_font_description(layout, font_description); math::Rect2 area_rect; math::Rect2 widget_rect = math::Rect2(5, 5, ns->width_height - 5, ns->width_height - 5); gtk_zoomed_get_current_screen_rect(GTK_ZOOMED(widget), &area_rect); cairo_rectangle(cr, 0, 0, ns->width_height - padding_x * 2, ns->width_height - padding_y * 2); cairo_clip(cr); vector > relative_positions(2); bool draw_distance = true; for (int i = 0; i < 2; i++){ if (ns->marks[i].valid){ relative_positions[i] = gtk_zoomed_get_screen_position(GTK_ZOOMED(widget), ns->marks[i].position); }else{ draw_distance = false; } } for (int layer = 0; layer != 2; layer++){ if (draw_distance){ cairo_move_to(cr, relative_positions[0].x, relative_positions[0].y); for (int i = 1; i < 2; i++){ cairo_line_to(cr, relative_positions[i].x, relative_positions[i].y); } if (layer == 0){ cairo_set_source_rgba(cr, 0, 0, 0, 1); cairo_set_line_width(cr, 3); }else{ cairo_set_source_rgba(cr, 1, 1, 1, 1); cairo_set_line_width(cr, 1); } cairo_stroke(cr); } for (int i = 0; i < 2; i++){ if (ns->marks[i].valid){ cairo_arc(cr, relative_positions[i].x, relative_positions[i].y, 2, -PI, PI); if (layer == 0){ cairo_set_source_rgba(cr, 0, 0, 0, 1); cairo_set_line_width(cr, 2); cairo_stroke(cr); }else{ cairo_set_source_rgba(cr, 1, 1, 1, 1); cairo_fill(cr); } stringstream ss; ss << ns->marks[i].position.x << "x" << ns->marks[i].position.y; auto text = ss.str(); pango_layout_set_text(layout, text.c_str(), -1); pango_cairo_update_layout(cr, layout); cairo_move_to(cr, relative_positions[i].x + 5, relative_positions[i].y); if (layer == 0){ cairo_set_source_rgba(cr, 0, 0, 0, 1); pango_cairo_layout_path(cr, layout); cairo_set_line_width(cr, 1.5); cairo_stroke(cr); }else{ cairo_set_source_rgba(cr, 1, 1, 1, 1); pango_cairo_show_layout(cr, layout); } } } } for (int layer = 0; layer != 2; layer++){ if (draw_distance){ double distance = math::Vec2::distance( math::Vec2(ns->marks[0].position.x, ns->marks[0].position.y), math::Vec2(ns->marks[1].position.x, ns->marks[1].position.y) ); math::Vec2 center = (ns->marks[0].position + ns->marks[1].position) * 0.5; stringstream ss; ss << fixed << setprecision(1) << distance << endl << 1 + abs(ns->marks[0].position.x - ns->marks[1].position.x) << "x" << 1 + abs(ns->marks[0].position.y - ns->marks[1].position.y); auto text = ss.str(); pango_layout_set_text(layout, text.c_str(), -1); pango_cairo_update_layout(cr, layout); math::Vec2 relative_position = gtk_zoomed_get_screen_position(GTK_ZOOMED(widget), center); PangoRectangle rect; pango_layout_get_pixel_extents(layout, nullptr, &rect); int text_width = rect.width; int text_height = rect.height; math::Rect2 text_rect(relative_position.x + 10, relative_position.y, relative_position.x + 10 + text_width, relative_position.y + text_height); if (!text_rect.isInside(widget_rect)) text_rect = widget_rect.positionInside(text_rect); cairo_move_to(cr, text_rect.getX(), text_rect.getY()); if (layer == 0){ cairo_set_source_rgba(cr, 0, 0, 0, 1); pango_cairo_layout_path(cr, layout); cairo_set_line_width(cr, 1.5); cairo_stroke(cr); }else{ cairo_set_source_rgba(cr, 1, 1, 1, 1); pango_cairo_show_layout(cr, layout); } } } g_object_unref(layout); pango_font_description_free(font_description); #if GTK_MAJOR_VERSION >= 3 gtk_render_frame(ns->context, cr, 0, 0, ns->width_height, ns->width_height); #else gtk_paint_shadow(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, nullptr, widget, 0, widget->style->xthickness, widget->style->ythickness, ns->width_height + widget->style->xthickness * 2, ns->width_height + widget->style->ythickness * 2); #endif return true; } #if GTK_MAJOR_VERSION < 3 static gboolean expose(GtkWidget *widget, GdkEventExpose *event) { cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_rectangle(cr, event->area.x, event->area.y, event->area.width, event->area.height); cairo_clip(cr); cairo_translate(cr, widget->style->xthickness + 0.5, widget->style->ythickness + 0.5); gboolean result = draw(widget, cr); cairo_destroy(cr); return result; } #endif static gboolean button_press(GtkWidget *widget, GdkEventButton *event) { gtk_widget_grab_focus(widget); if ((event->type == GDK_2BUTTON_PRESS) && (event->button == 1)) { g_signal_emit(widget, signals[ACTIVATED], 0); } return FALSE; } void gtk_zoomed_set_mark(GtkZoomed *zoomed, int index, math::Vec2& position) { GtkZoomedPrivate *ns = GET_PRIVATE(zoomed); ns->marks[index].position = position; ns->marks[index].valid = true; gtk_widget_queue_draw(GTK_WIDGET(zoomed)); } void gtk_zoomed_clear_mark(GtkZoomed *zoomed, int index) { GtkZoomedPrivate *ns = GET_PRIVATE(zoomed); ns->marks[index].valid = false; gtk_widget_queue_draw(GTK_WIDGET(zoomed)); } gpick-gpick-0.2.6/source/gtk/Zoomed.h000066400000000000000000000062531377073231300174160ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_GTK_ZOOMED_H_ #define GPICK_GTK_ZOOMED_H_ #include #include #include "../Color.h" #include "../Rect2.h" #include "../Vector2.h" #define GTK_TYPE_ZOOMED (gtk_zoomed_get_type()) #define GTK_ZOOMED(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_ZOOMED, GtkZoomed)) #define GTK_ZOOMED_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST((obj), GTK_ZOOMED, GtkZoomedClass)) #define GTK_IS_ZOOMED(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_ZOOMED)) #define GTK_IS_ZOOMED_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((obj), GTK_TYPE_ZOOMED)) #define GTK_ZOOMED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_ZOOMED, GtkZoomedClass)) struct GtkZoomed { GtkDrawingArea parent; }; struct GtkZoomedClass { GtkDrawingAreaClass parent_class; void (* color_changed)(GtkWidget* widget, Color* c, gpointer userdata); void (*activated)(GtkWidget* widget, gpointer userdata); }; GtkWidget* gtk_zoomed_new(); void gtk_zoomed_set_zoom(GtkZoomed* zoomed, gfloat zoom); gfloat gtk_zoomed_get_zoom(GtkZoomed* zoomed); void gtk_zoomed_set_fade(GtkZoomed* zoomed, bool fade); int32_t gtk_zoomed_get_size(GtkZoomed *zoomed); void gtk_zoomed_set_size(GtkZoomed *zoomed, int32_t width_height); void gtk_zoomed_set_mark(GtkZoomed *zoomed, int index, math::Vec2& position); void gtk_zoomed_clear_mark(GtkZoomed *zoomed, int index); void gtk_zoomed_update(GtkZoomed* zoomed, math::Vec2& pointer, math::Rect2& screen_rect, math::Vec2& offset, cairo_surface_t *surface); void gtk_zoomed_get_screen_rect(GtkZoomed* zoomed, math::Vec2& pointer, math::Rect2& screen_rect, math::Rect2 *rect); GType gtk_zoomed_get_type(); #endif /* GPICK_GTK_ZOOMED_H_ */ gpick-gpick-0.2.6/source/i18n/000077500000000000000000000000001377073231300157745ustar00rootroot00000000000000gpick-gpick-0.2.6/source/i18n/I18N.cpp000066400000000000000000000036261377073231300171660ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef ENABLE_NLS #include #endif #include #include #include #define TO_STRING(x) #x #define T_(x) TO_STRING(x) void initialize_i18n() { #ifdef ENABLE_NLS bindtextdomain("gpick", T_(LOCALEDIR)); char *td = textdomain("gpick"); if (!(td && (strcmp(td, "gpick") == 0))){ fprintf(stderr, "failed to load textdomain \"gpick\"\n"); } #endif } gpick-gpick-0.2.6/source/layout/000077500000000000000000000000001377073231300165325ustar00rootroot00000000000000gpick-gpick-0.2.6/source/layout/Box.cpp000066400000000000000000000134051377073231300177710ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Box.h" #include #include #include #include using namespace std; using namespace math; namespace layout{ void Box::SetStyle(Style *_style){ if (style){ unref(style); style=0; } if (_style){ style = static_cast(_style->ref()); } } void Box::Draw(Context *context, const Rect2& parent_rect ){ DrawChildren(context, parent_rect); } void Box::DrawChildren(Context *context, const math::Rect2& parent_rect ){ Rect2 child_rect = rect.impose( parent_rect ); for (list::iterator i = child.begin(); i != child.end(); i++){ (*i)->Draw(context, child_rect); } } void Box::AddChild(Box* box){ child.push_back(box); } Box::Box(const char* _name, float x, float y, float width, float height){ style = 0; name = _name; rect = Rect2(x, y, x+width, y+height); helper_only = false; locked = false; } Box::~Box(){ SetStyle(0); for (list::iterator i = child.begin(); i != child.end(); i++){ unref(*i); } } Box* Box::GetNamedBox(const char *name_){ if (name.compare(name_) == 0){ return this; } Box* r; for (list::iterator i = child.begin(); i != child.end(); i++){ if ((r = (*i)->GetNamedBox(name_))){ if (!r->helper_only) return r; } } return 0; } Box* Box::GetBoxAt(const Vec2& point){ if (rect.isInside(point.x, point.y)){ Vec2 transformed_point = Vec2((point.x-rect.getX()) / rect.getWidth(), (point.y-rect.getY()) / rect.getHeight()); Box* r; for (list::iterator i = child.begin(); i != child.end(); i++){ if ((r = (*i)->GetBoxAt(transformed_point))){ if (!r->helper_only) return r; } } if (typeid(*this) == typeid(Box)) //do not match Box, because it is invisible return 0; else return this; }else{ return 0; } } void Text::Draw(Context *context, const Rect2& parent_rect ){ Rect2 draw_rect = rect.impose( parent_rect ); cairo_t *cr = context->getCairo(); if (text != ""){ if (helper_only){ cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_ITALIC, CAIRO_FONT_WEIGHT_NORMAL); }else{ cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); } if (style){ cairo_set_font_size(cr, style->font_size * draw_rect.getHeight()); Color color; if (context->getTransformationChain()){ context->getTransformationChain()->apply(&style->color, &color); }else{ color_copy(&style->color, &color); } cairo_set_source_rgb(cr, boost::math::round(color.rgb.red * 255.0) / 255.0, boost::math::round(color.rgb.green * 255.0) / 255.0, boost::math::round(color.rgb.blue * 255.0) / 255.0); }else{ cairo_set_font_size(cr, draw_rect.getHeight()); cairo_set_source_rgb(cr, 0, 0, 0); } cairo_text_extents_t extents; cairo_text_extents(cr, text.c_str(), &extents); cairo_move_to(cr, draw_rect.getX() + draw_rect.getWidth()/2 - (extents.width/2 + extents.x_bearing), draw_rect.getY() + draw_rect.getHeight()/2 - (extents.height/2 + extents.y_bearing)); cairo_show_text(cr, text.c_str()); if (style && style->GetBox() == this){ cairo_rectangle(cr, draw_rect.getX()+1, draw_rect.getY()+1, draw_rect.getWidth()-2, draw_rect.getHeight()-2); cairo_set_source_rgb(cr, 1, 1, 1); cairo_set_line_width(cr, 2); cairo_stroke(cr); } } DrawChildren(context, parent_rect); } void Fill::Draw(Context *context, const Rect2& parent_rect ){ Rect2 draw_rect = rect.impose( parent_rect ); cairo_t *cr = context->getCairo(); Color color; if (context->getTransformationChain()){ context->getTransformationChain()->apply(&style->color, &color); }else{ color_copy(&style->color, &color); } cairo_set_source_rgb(cr, boost::math::round(color.rgb.red * 255.0) / 255.0, boost::math::round(color.rgb.green * 255.0) / 255.0, boost::math::round(color.rgb.blue * 255.0) / 255.0); cairo_rectangle(cr, draw_rect.getX(), draw_rect.getY(), draw_rect.getWidth(), draw_rect.getHeight()); cairo_fill(cr); if (style->GetBox() == this){ cairo_rectangle(cr, draw_rect.getX()+1, draw_rect.getY()+1, draw_rect.getWidth()-2, draw_rect.getHeight()-2); cairo_set_source_rgb(cr, 1, 1, 1); cairo_set_line_width(cr, 2); cairo_stroke(cr); } DrawChildren(context, parent_rect); } } gpick-gpick-0.2.6/source/layout/Box.h000066400000000000000000000054271377073231300174430ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_LAYOUT_BOX_H_ #define GPICK_LAYOUT_BOX_H_ #include "../Color.h" #include "../Rect2.h" #include "../Vector2.h" #include "ReferenceCounter.h" #include "Style.h" #include "Context.h" #include #include #include namespace layout { struct Box: public ReferenceCounter { virtual void Draw(Context *context, const math::Rect2& parent_rect); void DrawChildren(Context *context, const math::Rect2& parent_rect); void AddChild(Box* box); void SetStyle(Style *style); Box* GetBoxAt(const math::Vec2& point); Box* GetNamedBox(const char *name); Box(const char* name, float x, float y, float width, float height); virtual ~Box(); std::string name; Style *style; bool helper_only; bool locked; math::Rect2 rect; std::list child; }; struct Text: public Box { virtual void Draw(Context *context, const math::Rect2& parent_rect ); Text(const char* name, float x, float y, float width, float height): Box(name,x,y,width,height) { }; std::string text; }; struct Fill: public Box { virtual void Draw(Context *context, const math::Rect2& parent_rect ); Fill(const char* name, float x, float y, float width, float height): Box(name,x,y,width,height) { }; }; } #endif /* GPICK_LAYOUT_BOX_H_ */ gpick-gpick-0.2.6/source/layout/Context.cpp000066400000000000000000000034651377073231300206720ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Context.h" namespace layout { Context::Context(cairo_t *cr_, transformation::Chain *chain_) { cr = cr_; chain = chain_; } Context::~Context() { } cairo_t* Context::getCairo() const { return cr; } transformation::Chain* Context::getTransformationChain() const { return chain; } } gpick-gpick-0.2.6/source/layout/Context.h000066400000000000000000000040071377073231300203300ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_LAYOUT_CONTEXT_H_ #define GPICK_LAYOUT_CONTEXT_H_ #include "../transformation/Chain.h" #include #ifndef _MSC_VER #include #endif #include #include #include namespace layout { struct Context { Context(cairo_t *cr, transformation::Chain *chain); ~Context(); cairo_t* getCairo() const; transformation::Chain* getTransformationChain() const; private: cairo_t *cr; transformation::Chain *chain; }; } #endif /* GPICK_LAYOUT_CONTEXT_H_ */ gpick-gpick-0.2.6/source/layout/Layout.cpp000066400000000000000000000045611377073231300205210ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Layout.h" #include "System.h" #include "../lua/Layout.h" #include extern "C"{ #include #include } using namespace std; namespace layout { Layout::Layout(const char *name, const char *label, int mask, lua::Ref &&callback): m_name(name), m_label(label), m_mask(mask), m_callback(move(callback)) { } const std::string &Layout::name() const { return m_name; } const std::string &Layout::label() const { return m_label; } const int Layout::mask() const { return m_mask; } System *Layout::build() { lua_State *L = m_callback.script(); m_callback.get(); System *system = new System(); lua::pushLayoutSystem(L, system); int status; if ((status = lua_pcall(L, 1, 0, 0)) == 0){ return system; }else{ cerr << "layout.build: " << lua_tostring(L, -1) << endl; } lua_pop(L, 1); delete system; return nullptr; } } gpick-gpick-0.2.6/source/layout/Layout.h000066400000000000000000000040111377073231300201540ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_LAYOUT_LAYOUT_H_ #define GPICK_LAYOUT_LAYOUT_H_ #include "../lua/Ref.h" #include #include #include namespace layout { struct System; struct Layout { Layout(const char *name, const char *label, int mask, lua::Ref &&callback); const std::string &name() const; const std::string &label() const; const int mask() const; System *build(); private: std::string m_name; std::string m_label; int m_mask; lua::Ref m_callback; }; } #endif /* GPICK_LAYOUT_LAYOUT_H_ */ gpick-gpick-0.2.6/source/layout/Layouts.cpp000066400000000000000000000040561377073231300207030ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Layouts.h" #include "Layout.h" #include "System.h" using namespace std; namespace layout { Layouts::Layouts() { } Layouts::~Layouts() { for (auto layout: m_all_layouts){ delete layout; } } void Layouts::add(Layout *layout) { m_all_layouts.push_back(layout); m_layouts[layout->name()] = layout; } const std::vector &Layouts::all() const { return m_all_layouts; } Layout* Layouts::byName(const char *name) const { auto i = m_layouts.find(name); if (i != m_layouts.end()){ return i->second; } return nullptr; } } gpick-gpick-0.2.6/source/layout/Layouts.h000066400000000000000000000037011377073231300203440ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_LAYOUT_LAYOUTS_H_ #define GPICK_LAYOUT_LAYOUTS_H_ #include #include #include namespace layout { struct Layout; struct Layouts { Layouts(); ~Layouts(); void add(Layout *layout); const std::vector &all() const; Layout* byName(const char *name) const; private: std::map m_layouts; std::vector m_all_layouts; }; } #endif /* GPICK_LAYOUT_LAYOUTS_H_ */ gpick-gpick-0.2.6/source/layout/ReferenceCounter.cpp000066400000000000000000000036171377073231300225030ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ReferenceCounter.h" using namespace std; namespace layout { ReferenceCounter::ReferenceCounter() { refcnt = 0; } ReferenceCounter::~ReferenceCounter() { } ReferenceCounter* ReferenceCounter::ref() { refcnt++; return this; } bool ReferenceCounter::unref(ReferenceCounter* rc) { if (rc->refcnt){ rc->refcnt--; return false; }else{ delete rc; return true; } } } gpick-gpick-0.2.6/source/layout/ReferenceCounter.h000066400000000000000000000036041377073231300221440ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LAYOUT_REFERENCECOUNTER_H_ #define LAYOUT_REFERENCECOUNTER_H_ #include #ifndef _MSC_VER #include #endif namespace layout { struct ReferenceCounter { ReferenceCounter(); virtual ~ReferenceCounter(); ReferenceCounter* ref(); static bool unref(ReferenceCounter* rc); private: uint32_t refcnt; }; } #endif /* LAYOUT_REFERENCECOUNTER_H_ */ gpick-gpick-0.2.6/source/layout/Style.cpp000066400000000000000000000051141377073231300203370ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Box.h" #include #include using namespace std; using namespace math; namespace layout { Style::Style(const char* _name, Color* _color, float _font_size) { string name = string(_name); size_t pos = name.find(":"); if (pos != string::npos){ ident_name = name.substr(0, pos); label = name.substr(pos+1); }else{ ident_name = name; label = name; } style_type = TYPE_UNKNOWN; if ((pos = ident_name.rfind("_")) != string::npos){ string flags = ident_name.substr(pos); if (flags.find("t") != string::npos){ style_type = TYPE_COLOR; }else if (flags.find("b") != string::npos){ style_type = TYPE_BACKGROUND; } } color_copy(_color, &color); font_size = _font_size; dirty = true; highlight = false; selected_box = 0; } Style::~Style() { } bool Style::IsDirty() { return dirty; } void Style::SetDirty(bool _dirty) { dirty = _dirty; } bool Style::GetHighlight() { return highlight; } Box* Style::GetBox() { return selected_box; } void Style::SetState(bool _highlight, Box *box) { selected_box = box; highlight = _highlight; } } gpick-gpick-0.2.6/source/layout/Style.h000066400000000000000000000042751377073231300200130ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_LAYOUT_STYLE_H_ #define GPICK_LAYOUT_STYLE_H_ #include "../Color.h" #include "ReferenceCounter.h" #include "Box.h" #include #include namespace layout { struct Box; struct Style: public ReferenceCounter { std::string ident_name; std::string label; Color color; float font_size; enum{ TYPE_UNKNOWN = 0, TYPE_COLOR, TYPE_BACKGROUND, TYPE_BORDER, }style_type; bool dirty; bool highlight; Box* selected_box; bool IsDirty(); void SetDirty(bool dirty); bool GetHighlight(); Box* GetBox(); void SetState(bool highlight, Box *box); Style(const char* name, Color* color, float font_size); virtual ~Style(); }; } #endif /* LAYOUT_STYLE_H_ */ gpick-gpick-0.2.6/source/layout/System.cpp000066400000000000000000000045001377073231300205210ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "System.h" using namespace std; namespace layout { System::System() { box = 0; } System::~System() { for (list::iterator i=styles.begin(); i != styles.end(); i++){ Style::unref(*i); } styles.clear(); Box::unref(box); } void System::Draw(Context *context, const math::Rect2& parent_rect) { if (!box) return; box->Draw(context, parent_rect); } void System::AddStyle(Style *_style) { styles.push_back(static_cast(_style->ref())); } void System::SetBox(Box *_box) { if (box){ Box::unref(box); box = 0; } box = static_cast(_box->ref()); } Box* System::GetBoxAt(const math::Vec2& point) { if (box) return box->GetBoxAt(point); else return 0; } Box* System::GetNamedBox(const char *name) { if (box) return box->GetNamedBox(name); else return 0; } } gpick-gpick-0.2.6/source/layout/System.h000066400000000000000000000043061377073231300201720ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_LAYOUT_SYSTEM_H_ #define GPICK_LAYOUT_SYSTEM_H_ #include "../Rect2.h" #include "../Vector2.h" #include "Box.h" #include "Style.h" #include "Context.h" #include "ReferenceCounter.h" #include #ifndef _MSC_VER #include #endif #include #include #include namespace layout { struct System: public ReferenceCounter { System(); virtual ~System(); void Draw(Context *context, const math::Rect2& parent_rect ); Box* GetBoxAt(const math::Vec2& point); Box* GetNamedBox(const char *name); void AddStyle(Style *style); void SetBox(Box *box); std::list styles; Box* box; }; } #endif /* GPICK_LAYOUT_SYSTEM_H_ */ gpick-gpick-0.2.6/source/lua/000077500000000000000000000000001377073231300157765ustar00rootroot00000000000000gpick-gpick-0.2.6/source/lua/Callbacks.cpp000066400000000000000000000036261377073231300203700ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Callbacks.h" #include using namespace std; namespace lua { Callbacks::Callbacks() { } Ref &Callbacks::optionChange() { return m_option_change; } void Callbacks::optionChange(Ref &&ref) { m_option_change = move(ref); } Ref &Callbacks::componentToText() { return m_component_to_text; } void Callbacks::componentToText(Ref &&ref) { m_component_to_text = move(ref); } } gpick-gpick-0.2.6/source/lua/Callbacks.h000066400000000000000000000036611377073231300200340ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_LUA_CALLBACKS_H_ #define GPICK_LUA_CALLBACKS_H_ #include "Ref.h" namespace lua { struct Callbacks { Callbacks(); Callbacks(const Ref &) = delete; Callbacks &operator=(const Ref&) = delete; Ref &optionChange(); void optionChange(Ref &&ref); Ref &componentToText(); void componentToText(Ref &&ref); private: Ref m_option_change; Ref m_component_to_text; }; } #endif /* GPICK_LUA_CALLBACKS_H_ */ gpick-gpick-0.2.6/source/lua/Color.cpp000066400000000000000000000205241377073231300175630ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Color.h" #include "../Color.h" extern "C"{ #include #include } namespace lua { static int newColor(lua_State *L) { Color *c = reinterpret_cast(lua_newuserdata(L, sizeof(Color))); luaL_getmetatable(L, "color"); lua_setmetatable(L, -2); if (lua_type(L, 2) == LUA_TNUMBER && lua_type(L, 3) == LUA_TNUMBER && lua_type(L, 4) == LUA_TNUMBER ){ c->rgb.red = luaL_checknumber(L, 2); c->rgb.green = luaL_checknumber(L, 3); c->rgb.blue = luaL_checknumber(L, 4); }else{ color_zero(c); } return 1; } Color &checkColor(lua_State *L, int index) { void *ud = luaL_checkudata(L, index, "color"); luaL_argcheck(L, ud != nullptr, index, "`color' expected"); return *reinterpret_cast(ud); } int pushColor(lua_State *L, const Color &color) { Color *c = reinterpret_cast(lua_newuserdata(L, sizeof(Color))); luaL_getmetatable(L, "color"); lua_setmetatable(L, -2); color_copy(&color, c); return 1; } static int toString(lua_State *L) { Color &c = checkColor(L, 1); lua_pushfstring(L, "color(%f, %f, %f)", c.rgb.red, c.rgb.green, c.rgb.blue); return 1; } static int colorRgb(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER && lua_type(L, 3) == LUA_TNUMBER && lua_type(L, 4) == LUA_TNUMBER){ c.rgb.red = luaL_checknumber(L, 2); c.rgb.green = luaL_checknumber(L, 3); c.rgb.blue = luaL_checknumber(L, 4); } lua_pushnumber(L, c.rgb.red); lua_pushnumber(L, c.rgb.green); lua_pushnumber(L, c.rgb.blue); return 3; } static int colorRed(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER){ c.rgb.red = luaL_checknumber(L, 2); } lua_pushnumber(L, c.rgb.red); return 1; } static int colorGreen(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER){ c.rgb.green = luaL_checknumber(L, 2); } lua_pushnumber(L, c.rgb.green); return 1; } static int colorBlue(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER){ c.rgb.blue = luaL_checknumber(L, 2); } lua_pushnumber(L, c.rgb.blue); return 1; } static int colorHsl(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER && lua_type(L, 3) == LUA_TNUMBER && lua_type(L, 4) == LUA_TNUMBER){ c.hsl.hue = luaL_checknumber(L, 2); c.hsl.saturation = luaL_checknumber(L, 3); c.hsl.lightness = luaL_checknumber(L, 4); } lua_pushnumber(L, c.hsl.hue); lua_pushnumber(L, c.hsl.saturation); lua_pushnumber(L, c.hsl.lightness); return 3; } static int colorHue(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER){ c.hsl.hue = luaL_checknumber(L, 2); } lua_pushnumber(L, c.hsl.hue); return 1; } static int colorSaturation(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER){ c.hsl.saturation = luaL_checknumber(L, 2); } lua_pushnumber(L, c.hsl.saturation); return 1; } static int colorLightness(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER){ c.hsl.lightness = luaL_checknumber(L, 2); } lua_pushnumber(L, c.hsl.lightness); return 1; } static int colorCmyk(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER && lua_type(L, 3) == LUA_TNUMBER && lua_type(L, 4) == LUA_TNUMBER && lua_type(L, 5) == LUA_TNUMBER){ c.cmyk.c = luaL_checknumber(L, 2); c.cmyk.m = luaL_checknumber(L, 3); c.cmyk.y = luaL_checknumber(L, 4); c.cmyk.k = luaL_checknumber(L, 5); } lua_pushnumber(L, c.cmyk.c); lua_pushnumber(L, c.cmyk.m); lua_pushnumber(L, c.cmyk.y); lua_pushnumber(L, c.cmyk.k); return 4; } static int colorCyan(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER){ c.cmyk.c = luaL_checknumber(L, 2); } lua_pushnumber(L, c.cmyk.c); return 1; } static int colorMagenta(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER){ c.cmyk.m = luaL_checknumber(L, 2); } lua_pushnumber(L, c.cmyk.m); return 1; } static int colorYellow(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER){ c.cmyk.y = luaL_checknumber(L, 2); } lua_pushnumber(L, c.cmyk.y); return 1; } static int colorKeyBlack(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER){ c.cmyk.k = luaL_checknumber(L, 2); } lua_pushnumber(L, c.cmyk.k); return 1; } static int colorLabLightness(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER){ c.lab.L = luaL_checknumber(L, 2); } lua_pushnumber(L, c.lab.L); return 1; } static int colorLabA(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER){ c.lab.a = luaL_checknumber(L, 2); } lua_pushnumber(L, c.lab.a); return 1; } static int colorLabB(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER){ c.lab.b = luaL_checknumber(L, 2); } lua_pushnumber(L, c.lab.b); return 1; } static int colorRgbToHsl(lua_State *L) { Color &c = checkColor(L, 1); Color c2; color_rgb_to_hsl(&c, &c2); pushColor(L, c2); return 1; } static int colorHslToRgb(lua_State *L) { Color &c = checkColor(L, 1); Color c2; color_hsl_to_rgb(&c, &c2); pushColor(L, c2); return 1; } static int colorRgbToCmyk(lua_State *L) { Color &c = checkColor(L, 1); Color c2, c3; color_rgb_to_cmy(&c, &c3); color_cmy_to_cmyk(&c3, &c2); pushColor(L, c2); return 1; } static int colorLchLightness(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER){ c.lch.L = luaL_checknumber(L, 2); } lua_pushnumber(L, c.lch.L); return 1; } static int colorLchChroma(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER){ c.lch.C = luaL_checknumber(L, 2); } lua_pushnumber(L, c.lch.C); return 1; } static int colorLchHue(lua_State *L) { Color &c = checkColor(L, 1); if (lua_type(L, 2) == LUA_TNUMBER){ c.lch.h = luaL_checknumber(L, 2); } lua_pushnumber(L, c.lch.h); return 1; } static const struct luaL_Reg color_functions[] = { {"new", newColor}, {nullptr, nullptr} }; static const struct luaL_Reg color_members[] = { {"__tostring", toString}, {"red", colorRed}, {"green", colorGreen}, {"blue", colorBlue}, {"rgb", colorRgb}, {"hue", colorHue}, {"saturation", colorSaturation}, {"lightness", colorLightness}, {"value", colorLightness}, {"hsl", colorHsl}, {"cyan", colorCyan}, {"magenta", colorMagenta}, {"yellow", colorYellow}, {"key_black", colorKeyBlack}, {"cmyk", colorCmyk}, {"labLightness", colorLabLightness}, {"labA", colorLabA}, {"labB", colorLabB}, {"lchLightness", colorLchLightness}, {"lchChroma", colorLchChroma}, {"lchHue", colorLchHue}, {"rgbToHsl", colorRgbToHsl}, {"hslToRgb", colorHslToRgb}, {"rgbToCmyk", colorRgbToCmyk}, {nullptr, nullptr} }; int registerColor(lua_State *L) { luaL_newmetatable(L, "color"); lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); luaL_setfuncs(L, color_members, 0); lua_pop(L, 1); luaL_newlib(L, color_functions); return 1; } } gpick-gpick-0.2.6/source/lua/Color.h000066400000000000000000000034261377073231300172320ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_LUA_COLOR_H_ #define GPICK_LUA_COLOR_H_ struct lua_State; struct Color; namespace lua { int registerColor(lua_State *L); int pushColor(lua_State *L, const Color &color); Color &checkColor(lua_State *L, int index); } #endif /* GPICK_LUA_COLOR_H_ */ gpick-gpick-0.2.6/source/lua/ColorObject.cpp000066400000000000000000000065171377073231300207200ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ColorObject.h" #include "Color.h" #include "Script.h" #include "../ColorObject.h" extern "C"{ #include #include } namespace lua { static int newColorObject(lua_State *L) { ColorObject** c = reinterpret_cast(lua_newuserdata(L, sizeof(ColorObject*))); luaL_getmetatable(L, "colorObject"); lua_setmetatable(L, -2); *c = nullptr; return 1; } ColorObject* checkColorObject(lua_State *L, int index) { void *ud = luaL_checkudata(L, index, "colorObject"); luaL_argcheck(L, ud != nullptr, index, "`colorObject' expected"); return *reinterpret_cast(ud); } int pushColorObject(lua_State *L, ColorObject* color_object) { ColorObject** c = reinterpret_cast(lua_newuserdata(L, sizeof(ColorObject*))); luaL_getmetatable(L, "colorObject"); lua_setmetatable(L, -2); *c = color_object; return 1; } int getColor(lua_State *L) { ColorObject *color_object = checkColorObject(L, 1); const Color &tmp = color_object->getColor(); pushColor(L, tmp); return 1; } int setColor(lua_State *L) { ColorObject *color_object = checkColorObject(L, 1); const Color &color = checkColor(L, 2); color_object->setColor(color); return 0; } int getName(lua_State *L) { ColorObject *color_object = checkColorObject(L, 1); lua_pushstring(L, color_object->getName().c_str()); return 1; } static const struct luaL_Reg color_object_functions[] = { {"new", newColorObject}, {nullptr, nullptr} }; static const struct luaL_Reg color_object_members[] = { {"getColor", getColor}, {"setColor", setColor}, {"getName", getName}, {nullptr, nullptr} }; int registerColorObject(lua_State *L) { luaL_newmetatable(L, "colorObject"); lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); luaL_setfuncs(L, color_object_members, 0); lua_pop(L, 1); luaL_newlib(L, color_object_functions); return 1; } } gpick-gpick-0.2.6/source/lua/ColorObject.h000066400000000000000000000035201377073231300203540ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_LUA_COLOR_OBJECT_H_ #define GPICK_LUA_COLOR_OBJECT_H_ struct lua_State; struct ColorObject; namespace lua { int registerColorObject(lua_State *L); ColorObject* checkColorObject(lua_State *L, int index); int pushColorObject(lua_State *L, ColorObject* color_object); } #endif /* GPICK_LUA_COLOR_OBJECT_H_ */ gpick-gpick-0.2.6/source/lua/DynvSystem.cpp000066400000000000000000000051501377073231300206300ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "DynvSystem.h" extern "C"{ #include #include } namespace lua { dynv::Ref checkDynvSystem(lua_State *L, int index) { void *ud = luaL_checkudata(L, index, "dynvSystem"); luaL_argcheck(L, ud != nullptr, index, "`dynvSystem' expected"); return *reinterpret_cast(ud); } int pushDynvSystem(lua_State *L, const dynv::Ref &system) { new (lua_newuserdata(L, sizeof(dynv::Ref))) dynv::Ref(system); luaL_getmetatable(L, "dynvSystem"); lua_setmetatable(L, -2); return 1; } int getString(lua_State *L) { auto system = checkDynvSystem(L, 1); if (!system) { lua_pushnil(L); return 1; } const char *name = luaL_checkstring(L, 2); const char *defaultValue = luaL_checkstring(L, 3); lua_pushstring(L, system->getString(name, defaultValue).c_str()); return 1; } static const struct luaL_Reg dynvSystemMembers[] = { {"getString", getString}, {nullptr, nullptr} }; int registerDynvSystem(lua_State *L) { luaL_newmetatable(L, "dynvSystem"); lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); luaL_setfuncs(L, dynvSystemMembers, 0); lua_pop(L, 1); return 0; } } gpick-gpick-0.2.6/source/lua/DynvSystem.h000066400000000000000000000035101377073231300202730ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_LUA_DYNV_SYSTEM_H_ #define GPICK_LUA_DYNV_SYSTEM_H_ #include "dynv/Map.h" struct lua_State; namespace lua { int registerDynvSystem(lua_State *L); int pushDynvSystem(lua_State *L, const dynv::Ref &options); dynv::Ref checkDynvSystem(lua_State *L, int index); } #endif /* GPICK_LUA_DYNV_SYSTEM_H_ */ gpick-gpick-0.2.6/source/lua/Extensions.cpp000066400000000000000000000100621377073231300206400ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Extensions.h" #include "Script.h" #include "Color.h" #include "ColorObject.h" #include "DynvSystem.h" #include "Layout.h" #include "I18N.h" #include "GlobalState.h" #include "Callbacks.h" #include "../GlobalState.h" #include "../layout/Layouts.h" #include "../layout/Layout.h" #include "../Converters.h" #include "../Converter.h" #include "../version/Version.h" extern "C"{ #include #include } namespace lua { static void checkArgumentIsFunctionOrNil(lua_State *L, int index) { auto type = lua_type(L, index); bool type_matches = type == LUA_TFUNCTION || type == LUA_TNIL; luaL_argcheck(L, type_matches, index, "function or nil expected"); } static int addLayout(lua_State *L) { const char *name = luaL_checkstring(L, 2); const char *label = luaL_checkstring(L, 3); checkArgumentIsFunctionOrNil(L, 4); int mask = luaL_optinteger(L, 5, 0); getGlobalState(L).layouts().add(new layout::Layout(name, label, mask, Ref(L, 4))); return 0; } static int addConverter(lua_State *L) { const char *name = luaL_checkstring(L, 2); const char *label = luaL_checkstring(L, 3); checkArgumentIsFunctionOrNil(L, 4); if (lua_gettop(L) >= 5) checkArgumentIsFunctionOrNil(L, 5); if (lua_gettop(L) == 4) getGlobalState(L).converters().add(new Converter(name, label, Ref(L, 4), Ref())); else if (lua_gettop(L) >= 5) getGlobalState(L).converters().add(new Converter(name, label, Ref(L, 4), Ref(L, 5))); return 0; } static int setOptionChangeCallback(lua_State *L) { getGlobalState(L).callbacks().optionChange(Ref(L, 2)); return 0; } static int setComponentToTextCallback(lua_State *L) { getGlobalState(L).callbacks().componentToText(Ref(L, 2)); return 0; } static const struct luaL_Reg functions[] = { {"addLayout", addLayout}, {"addConverter", addConverter}, {"setComponentToTextCallback", setComponentToTextCallback}, {"setOptionChangeCallback", setOptionChangeCallback}, {nullptr, nullptr} }; void registerAll(lua_State *L, GlobalState &global_state) { Script script(L); script.registerExtension("color", registerColor); script.registerExtension("colorObject", registerColorObject); script.registerExtension("dynvSystem", registerDynvSystem); script.registerExtension("layout", registerLayout); script.registerExtension(nullptr, [](lua_State *L){ luaL_newlib(L, functions); lua_pushstring(L, gpick_build_version); lua_setfield(L, -2, "version"); lua_pushstring(L, gpick_build_revision); lua_setfield(L, -2, "revision"); lua_pushcclosure(L, getText, 0); lua_setfield(L, -2, "_"); return 1; }); setGlobalState(L, global_state); } } gpick-gpick-0.2.6/source/lua/Extensions.h000066400000000000000000000033501377073231300203070ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_LUA_EXTENSIONS_H_ #define GPICK_LUA_EXTENSIONS_H_ struct lua_State; struct GlobalState; namespace lua { void registerAll(lua_State *L, GlobalState &global_state); } #endif /* GPICK_LUA_EXTENSIONS_H_ */ gpick-gpick-0.2.6/source/lua/GlobalState.cpp000066400000000000000000000040571377073231300207110ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "GlobalState.h" #include "../GlobalState.h" extern "C"{ #include #include } namespace lua { void setGlobalState(lua_State *L, GlobalState &global_state) { lua_pushglobaltable(L); lua_pushlightuserdata(L, &global_state); lua_setfield(L, -2, "__global_state"); lua_pop(L, 1); } GlobalState &getGlobalState(lua_State *L) { lua_pushglobaltable(L); lua_getfield(L, -1, "__global_state"); GlobalState &global_state = *static_cast(lua_touserdata(L, -1)); lua_pop(L, 1); return global_state; } } gpick-gpick-0.2.6/source/lua/GlobalState.h000066400000000000000000000034341377073231300203540ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_LUA_GLOBAL_STATE_H_ #define GPICK_LUA_GLOBAL_STATE_H_ struct lua_State; struct GlobalState; namespace lua { GlobalState &getGlobalState(lua_State *L); void setGlobalState(lua_State *L, GlobalState &global_state); } #endif /* GPICK_LUA_GLOBAL_STATE_H_ */ gpick-gpick-0.2.6/source/lua/I18N.cpp000066400000000000000000000033621377073231300171650ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "I18N.h" #include "../I18N.h" extern "C"{ #include #include } namespace lua { int getText(lua_State *L) { const char *text = luaL_checkstring(L, 1); lua_pushstring(L, _(text)); return 1; } } gpick-gpick-0.2.6/source/lua/I18N.h000066400000000000000000000032421377073231300166270ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_LUA_I18N_H_ #define GPICK_LUA_I18N_H_ struct lua_State; namespace lua { int getText(lua_State *L); } #endif /* GPICK_LUA_I18N_H_ */ gpick-gpick-0.2.6/source/lua/Layout.cpp000066400000000000000000000162151377073231300177640ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Layout.h" #include "Script.h" #include "Color.h" #include "GlobalState.h" #include "../layout/Box.h" #include "../layout/System.h" #include "../layout/Layout.h" extern "C"{ #include #include } #include #include using namespace std; using namespace layout; namespace lua { static int newLayoutStyle(lua_State *L) { const char *name = luaL_checkstring(L, 2); Color &color = checkColor(L, 3); double font_size = luaL_optnumber(L, 4, 1.0); Style **c = static_cast(lua_newuserdata(L, sizeof(Style*))); luaL_getmetatable(L, "layoutStyle"); lua_setmetatable(L, -2); *c = new Style(name, &color, font_size); return 1; } Style *checkLayoutStyle(lua_State *L, int index) { Style **c = static_cast(luaL_checkudata(L, index, "layoutStyle")); luaL_argcheck(L, c != nullptr, index, "`layoutStyle' expected"); return *c; } int pushLayoutStyle(lua_State *L, Style *style) { Style **c = static_cast(lua_newuserdata(L, sizeof(Style*))); luaL_getmetatable(L, "layoutStyle"); lua_setmetatable(L, -2); *c = style; return 1; } int styleGc(lua_State *L) { Style *style = checkLayoutStyle(L, 1); Style::unref(style); return 0; } int styleLabel(lua_State *L) { Style *style = checkLayoutStyle(L, 1); if (lua_type(L, 2) == LUA_TSTRING){ const char *name = luaL_checkstring(L, 2); style->label = name; return 0; }else{ lua_pushstring(L, style->label.c_str()); return 1; } } static int newLayoutBox(lua_State *L) { const char *name = luaL_checkstring(L, 2); double x = luaL_checknumber(L, 3); double y = luaL_checknumber(L, 4); double w = luaL_checknumber(L, 5); double h = luaL_checknumber(L, 6); Box **c = static_cast(lua_newuserdata(L, sizeof(Box*))); luaL_getmetatable(L, "layout"); lua_setmetatable(L, -2); *c = new Box(name, x, y, w, h); return 1; } static int newLayoutFill(lua_State *L) { const char *name = luaL_checkstring(L, 2); double x = luaL_checknumber(L, 3); double y = luaL_checknumber(L, 4); double w = luaL_checknumber(L, 5); double h = luaL_checknumber(L, 6); Style *style = checkLayoutStyle(L, 7); Box **c = static_cast(lua_newuserdata(L, sizeof(Box*))); luaL_getmetatable(L, "layout"); lua_setmetatable(L, -2); Fill *e = new Fill(name, x, y, w, h); e->SetStyle(style); *c = e; return 1; } static int newLayoutText(lua_State *L) { const char *name = luaL_checkstring(L, 2); double x = luaL_checknumber(L, 3); double y = luaL_checknumber(L, 4); double w = luaL_checknumber(L, 5); double h = luaL_checknumber(L, 6); Style *style = nullptr; if (lua_type(L, 7) != LUA_TNIL){ style = checkLayoutStyle(L, 7); } const char *text = luaL_checkstring(L, 8); Box **c = static_cast(lua_newuserdata(L, sizeof(Box*))); luaL_getmetatable(L, "layout"); lua_setmetatable(L, -2); Text *e = new Text(name, x, y, w, h); if (style) e->SetStyle(style); e->text = text; *c = e; return 1; } Box *checkLayoutBox(lua_State *L, int index) { Box **c = static_cast(luaL_checkudata(L, index, "layout")); luaL_argcheck(L, c != nullptr, index, "`layout' expected"); return *c; } int pushLayoutBox(lua_State *L, Box *box) { Box **c = static_cast(lua_newuserdata(L, sizeof(Box*))); luaL_getmetatable(L, "layout"); lua_setmetatable(L, -2); *c = static_cast(box->ref()); return 1; } int boxAdd(lua_State *L) { Box *box = checkLayoutBox(L, 1); Box *box2 = checkLayoutBox(L, 2); box->AddChild(static_cast(box2->ref())); pushLayoutBox(L, box); return 1; } int boxHelperOnly(lua_State *L) { Box *box = checkLayoutBox(L, 1); if (lua_type(L, 2) == LUA_TBOOLEAN){ int v = lua_toboolean(L, 2); if (v){ box->helper_only = true; }else{ box->helper_only = false; } return 0; }else{ lua_pushboolean(L, box->helper_only); return 1; } } int boxLocked(lua_State *L) { Box *box = checkLayoutBox(L, 1); if (lua_type(L, 2) == LUA_TBOOLEAN){ int v = lua_toboolean(L, 2); if (v){ box->locked = true; }else{ box->locked = false; } return 0; }else{ lua_pushboolean(L, box->locked); return 1; } } int boxGc(lua_State *L) { Box *box = checkLayoutBox(L, 1); Box::unref(box); return 0; } System *checkLayoutSystem(lua_State *L, int index) { System **c = static_cast(luaL_checkudata(L, index, "layoutSystem")); luaL_argcheck(L, c != nullptr, index, "`layoutSystem' expected"); return *c; } int pushLayoutSystem(lua_State *L, System *system) { System **c = static_cast(lua_newuserdata(L, sizeof(System*))); luaL_getmetatable(L, "layoutSystem"); lua_setmetatable(L, -2); *c = system; return 1; } int systemAddStyle(lua_State *L) { System *system = checkLayoutSystem(L, 1); Style *style = checkLayoutStyle(L, 2); system->AddStyle(style); return 0; } int systemSetBox(lua_State *L) { System *system = checkLayoutSystem(L, 1); Box *box = checkLayoutBox(L, 2); system->SetBox(box); return 0; } static const struct luaL_Reg system_members[] = { {"addStyle", systemAddStyle}, {"setBox", systemSetBox}, {nullptr, nullptr} }; static const struct luaL_Reg box_members[] = { {"add", boxAdd}, {"helperOnly", boxHelperOnly}, {"locked", boxLocked}, {"__gc", boxGc}, {nullptr, nullptr} }; static const struct luaL_Reg style_members[] = { {"label", styleLabel}, {"__gc", styleGc}, {nullptr, nullptr} }; static const struct luaL_Reg functions[] = { {"newBox", newLayoutBox}, {"newText", newLayoutText}, {"newFill", newLayoutFill}, {"newStyle", newLayoutStyle}, {nullptr, nullptr} }; int registerLayout(lua_State *L) { Script script(L); script.createType("layout", box_members); script.createType("layoutStyle", style_members); script.createType("layoutSystem", system_members); luaL_newlib(L, functions); return 1; } } gpick-gpick-0.2.6/source/lua/Layout.h000066400000000000000000000034171377073231300174310ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_LUA_LAYOUT_H_ #define GPICK_LUA_LAYOUT_H_ struct lua_State; namespace layout { struct System; } namespace lua { int registerLayout(lua_State *L); int pushLayoutSystem(lua_State *L, layout::System *system); } #endif /* GPICK_LUA_LAYOUT_H_ */ gpick-gpick-0.2.6/source/lua/Ref.cpp000066400000000000000000000044241377073231300172220ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Ref.h" extern "C"{ #include #include } namespace lua { Ref::Ref(): m_ref(LUA_NOREF), m_L(nullptr) { } Ref::Ref(lua_State *L, int index) { lua_pushvalue(L, index); m_ref = luaL_ref(L, LUA_REGISTRYINDEX); m_L = L; } Ref::Ref(Ref &&ref) { m_ref = ref.m_ref; m_L = ref.m_L; ref.m_ref = LUA_NOREF; ref.m_L = nullptr; } Ref::~Ref() { if (m_L && m_ref != LUA_NOREF) luaL_unref(m_L, LUA_REGISTRYINDEX, m_ref); } void Ref::get() { if (!m_L) return; lua_rawgeti(m_L, LUA_REGISTRYINDEX, m_ref); } lua_State *Ref::script() { return m_L; } Ref &Ref::operator=(Ref &&ref) { m_ref = ref.m_ref; m_L = ref.m_L; ref.m_ref = LUA_NOREF; ref.m_L = nullptr; return *this; } bool Ref::valid() const { return m_L && m_ref != LUA_NOREF; } } gpick-gpick-0.2.6/source/lua/Ref.h000066400000000000000000000036161377073231300166710ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_LUA_REF_H_ #define GPICK_LUA_REF_H_ struct lua_State; namespace lua { struct Ref { Ref(); Ref(lua_State *L, int index); Ref(Ref &&ref); Ref &operator=(Ref&&); Ref(const Ref &) = delete; Ref &operator=(const Ref&) = delete; ~Ref(); void get(); lua_State *script(); bool valid() const; private: int m_ref; lua_State *m_L; }; } #endif /* GPICK_LUA_REF_H_ */ gpick-gpick-0.2.6/source/lua/Script.cpp000066400000000000000000000107551377073231300177560ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Script.h" #include extern "C"{ #include #include } #include using namespace std; namespace lua { Script::Script() { m_state = luaL_newstate(); m_state_owned = true; luaL_openlibs(m_state); } Script::Script(lua_State *state) { m_state = state; m_state_owned = false; } Script::~Script() { if (m_state_owned) lua_close(m_state); m_state = nullptr; } Script::operator lua_State*() { return m_state; } void Script::setPaths(const std::vector &include_paths) { string paths = ";./?.lua;"; for (vector::const_iterator i = include_paths.begin(); i != include_paths.end(); i++){ paths += *i; paths += "/?.lua;"; } lua_getglobal(m_state, "package"); lua_pushstring(m_state, "path"); lua_pushstring(m_state, paths.c_str()); lua_settable(m_state, -3); lua_pop(m_state, 1); } bool Script::load(const char *script_name) { int status; lua_getglobal(m_state, "require"); lua_pushstring(m_state, script_name); status = lua_pcall(m_state, 1, 1, 0); if (status) { stringstream ss; ss << lua_tostring(m_state, -1); m_last_error = ss.str(); return false; } return true; } bool Script::loadCode(const char *script_code) { int status; status = luaL_loadstring(m_state, script_code); if (status){ m_last_error = lua_tostring(m_state, -1); return false; } return true; } bool Script::run(int arguments_on_stack, int results) { lua_State *L = m_state; int status; if (lua_type(L, -1) != LUA_TNIL){ if ((status = lua_pcall(L, arguments_on_stack, results, 0))){ stringstream ss; ss << "call failed: " << lua_tostring(L, -1); m_last_error = ss.str(); return false; }else{ return true; } }else{ m_last_error = "requested function was not found"; return false; } } static int registerLuaPackage(lua_State *L) { lua_getglobal(L, "__script"); auto &script = *reinterpret_cast(lua_touserdata(L, -1)); lua_getglobal(L, "__extension"); auto &extension = *reinterpret_cast*>(lua_touserdata(L, -1)); lua_pop(L, 2); return extension(script); } bool Script::registerExtension(const char *name, std::function extension) { lua_State *L = m_state; string full_name; if (name == nullptr) full_name = "gpick"; else full_name = string("gpick/") + name; lua_pushlightuserdata(L, this); lua_setglobal(L, "__script"); lua_pushlightuserdata(L, &extension); lua_setglobal(L, "__extension"); luaL_requiref(m_state, full_name.c_str(), registerLuaPackage, 0); lua_pushnil(L); lua_setglobal(L, "__script"); lua_pushnil(L); lua_setglobal(L, "__extension"); lua_pop(L, 1); return true; } std::string Script::getString(int index) { return lua_tostring(m_state, index); } void Script::createType(const char *name, const luaL_Reg *members) { lua_State *L = m_state; luaL_newmetatable(L, name); lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); luaL_setfuncs(L, members, 0); lua_pop(L, 1); } const std::string &Script::getLastError() { return m_last_error; } } gpick-gpick-0.2.6/source/lua/Script.h000066400000000000000000000044241377073231300174170ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_LUA_SCRIPT_H_ #define GPICK_LUA_SCRIPT_H_ #include #include #include struct lua_State; struct luaL_Reg; namespace lua { struct Script { Script(); Script(lua_State *L); ~Script(); operator lua_State*(); void setPaths(const std::vector &include_paths); bool load(const char *script_name); bool loadCode(const char *script_code); bool run(int arguments_on_stack, int results); bool registerExtension(const char *name, std::function extension); void createType(const char *name, const luaL_Reg *members); const std::string &getLastError(); std::string getString(int index); private: lua_State *m_state; bool m_state_owned; std::string m_last_error; }; } #endif /* GPICK_LUA_SCRIPT_H_ */ gpick-gpick-0.2.6/source/main.cpp000066400000000000000000000121231377073231300166440ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "main.h" #include "Paths.h" #include "uiAbout.h" #include "uiApp.h" #include "I18N.h" #include "version/Version.h" #include "dynv/Map.h" #include #include #include using namespace std; static gchar **commandline_filename = nullptr; static gchar *commandline_geometry = nullptr; static gboolean pick_color = FALSE; static gboolean output_picked_color = FALSE; static gboolean output_without_newline = FALSE; static gboolean single_color_pick_mode = FALSE; static gboolean version_information = FALSE; static gboolean do_not_start = FALSE; static gchar *converter_name = nullptr; static GOptionEntry commandline_entries[] = { {"geometry", 'g', 0, G_OPTION_ARG_STRING, &commandline_geometry, "Window geometry", "GEOMETRY"}, {"pick", 'p', 0, G_OPTION_ARG_NONE, &pick_color, "Pick a color", nullptr}, {"single", 's', 0, G_OPTION_ARG_NONE, &single_color_pick_mode, "Pick one color and exit", nullptr}, {"output", 'o', 0, G_OPTION_ARG_NONE, &output_picked_color, "Output picked color", nullptr}, {"no-newline", 0, 0, G_OPTION_ARG_NONE, &output_without_newline, "Output picked color without newline", nullptr}, {"no-start", 0, 0, G_OPTION_ARG_NONE, &do_not_start, "Do not start Gpick if it is not already running", nullptr}, {"converter-name", 'c', 0, G_OPTION_ARG_STRING, &converter_name, "Converter name used for floating picker mode", nullptr}, {"version", 'v', 0, G_OPTION_ARG_NONE, &version_information, "Print version information", nullptr}, {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &commandline_filename, nullptr, "[FILE...]"}, {nullptr} }; int main(int argc, char **argv) { setlocale(LC_ALL, ""); gtk_init(&argc, &argv); initialize_i18n(); g_set_application_name(program_name); GError *error = nullptr; GOptionContext *context = g_option_context_new("- advanced color picker"); g_option_context_add_main_entries(context, commandline_entries, 0); g_option_context_add_group(context, gtk_get_option_group(TRUE)); gchar **argv_copy; #ifdef WIN32 argv_copy = g_win32_get_command_line(); #else argv_copy = g_strdupv(argv); #endif if (!g_option_context_parse_strv(context, &argv_copy, &error)){ g_print("option parsing failed: %s\n", error->message); g_clear_error(&error); g_option_context_free(context); g_strfreev(argv_copy); return -1; } if (version_information){ string version = string(program_name) + " version " + string(gpick_build_version); string revision = "Revision " + string(gpick_build_revision); string build_date = "Date " + string(gpick_build_date); g_print("%s\n%s\n%s\n", version.c_str(), revision.c_str(), build_date.c_str()); g_option_context_free(context); g_strfreev(argv_copy); return 0; } StartupOptions options; options.floating_picker_mode = pick_color; options.output_picked_color = output_picked_color; options.output_without_newline = output_without_newline; options.single_color_pick_mode = single_color_pick_mode; options.do_not_start = do_not_start; if (converter_name != nullptr) options.converter_name = converter_name; int return_value = 0; app_initialize(); AppArgs *args = app_create_main(options, return_value); if (args){ if (!single_color_pick_mode){ if (commandline_filename){ app_load_file(args, commandline_filename[0]); }else{ if (app_is_autoload_enabled(args)){ auto autosaveFile = buildConfigPath("autosave.gpa"); app_load_file(args, autosaveFile, true); } } } if (commandline_geometry) app_parse_geometry(args, commandline_geometry); return_value = app_run(args); } g_option_context_free(context); g_strfreev(argv_copy); return return_value; } gpick-gpick-0.2.6/source/main.h000066400000000000000000000031301377073231300163070ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_MAIN_H_ #define GPICK_MAIN_H_ #endif /* GPICK_MAIN_H_ */ gpick-gpick-0.2.6/source/parser/000077500000000000000000000000001377073231300165115ustar00rootroot00000000000000gpick-gpick-0.2.6/source/parser/TextFile.cpp000066400000000000000000000040261377073231300207430ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "TextFile.h" namespace text_file_parser { Configuration::Configuration() { single_line_c_comments = true; single_line_hash_comments = true; multi_line_c_comments = true; short_hex = true; full_hex = true; css_rgb = true; css_rgba = true; float_values = true; int_values = true; } bool scanner(TextFile &text_file, const Configuration &configuration); bool TextFile::parse(const Configuration &configuration) { return scanner(*this, configuration); } TextFile::~TextFile() { } } gpick-gpick-0.2.6/source/parser/TextFile.h000066400000000000000000000044161377073231300204130ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_PARSER_TEXT_FILE_H_ #define GPICK_PARSER_TEXT_FILE_H_ #include struct Color; namespace text_file_parser { struct Configuration { Configuration(); bool single_line_c_comments; bool single_line_hash_comments; bool multi_line_c_comments; bool short_hex; bool full_hex; bool css_rgb; bool css_rgba; bool float_values; bool int_values; }; struct TextFile { bool parse(const Configuration &configuration); virtual ~TextFile(); virtual void outOfMemory() = 0; virtual void syntaxError(size_t start_line, size_t start_column, size_t end_line, size_t end_colunn) = 0; virtual size_t read(char *buffer, size_t length) = 0; virtual void addColor(const Color &color) = 0; }; } #endif /* GPICK_PARSER_TEXT_FILE_H_ */ gpick-gpick-0.2.6/source/parser/TextFileParser.rl000066400000000000000000000151161377073231300217550ustar00rootroot00000000000000#include "parser/TextFile.h" #include "Color.h" #include #include #include #include #include #include #include #include using namespace std; namespace text_file_parser { struct FSM { public: int cs; char separator; int act; int top; char *ts; char *te; int stack[256]; char buffer[8 * 1024]; int line; int column; int line_start; int buffer_offset; int64_t number_i64; vector numbers_i64; char *number_double_start; vector numbers_double; function addColor; void handleNewline() { line++; column = 0; line_start = te - buffer; } int hexToInt(char hex) { if (hex >= '0' && hex <= '9') return hex - '0'; if (hex >= 'a' && hex <= 'f') return hex - 'a' + 10; if (hex >= 'A' && hex <= 'F') return hex - 'A' + 10; return 0; } int hexPairToInt(const char *hex_pair) { return hexToInt(hex_pair[0]) << 4 | hexToInt(hex_pair[1]); } void colorHexFull(bool with_hash_symbol) { Color color; int start_index = with_hash_symbol ? 1 : 0; color.rgb.red = hexPairToInt(ts + start_index) / 255.0; color.rgb.green = hexPairToInt(ts + start_index + 2) / 255.0; color.rgb.blue = hexPairToInt(ts + start_index + 4) / 255.0; color.ma[3] = 0; addColor(color); } void colorHexShort(bool with_hash_symbol) { Color color; int start_index = with_hash_symbol ? 1 : 0; color.rgb.red = hexToInt(ts[start_index + 0]) / 15.0; color.rgb.green = hexToInt(ts[start_index + 1]) / 15.0; color.rgb.blue = hexToInt(ts[start_index + 2]) / 15.0; color.ma[3] = 0; addColor(color); } void colorRgb() { Color color; color.rgb.red = numbers_i64[0] / 255.0; color.rgb.green = numbers_i64[1] / 255.0; color.rgb.blue = numbers_i64[2] / 255.0; color.ma[3] = 0; numbers_i64.clear(); addColor(color); } void colorRgba() { Color color; color.rgb.red = numbers_i64[0] / 255.0; color.rgb.green = numbers_i64[1] / 255.0; color.rgb.blue = numbers_i64[2] / 255.0; color.ma[3] = numbers_double[0]; numbers_i64.clear(); numbers_double.clear(); addColor(color); } void colorValues() { Color color; color.rgb.red = numbers_double[0]; color.rgb.green = numbers_double[1]; color.rgb.blue = numbers_double[2]; color.ma[3] = 0; numbers_double.clear(); addColor(color); } void colorValueIntegers() { Color color; color.rgb.red = numbers_i64[0] / 255.0; color.rgb.green = numbers_i64[1] / 255.0; color.rgb.blue = numbers_i64[2] / 255.0; color.ma[3] = 0; numbers_i64.clear(); addColor(color); } double parseDouble(const char *start, const char *end) { string v(start, end); try { return stod(v.c_str()); } catch(...) { return 0; } } void clearNumberStacks() { numbers_i64.clear(); numbers_double.clear(); } }; %%{ machine text_file; access fsm->; number_i64 = digit+ >{ fsm->number_i64 = 0; } ${ fsm->number_i64 = fsm->number_i64 * 10 + (*p - '0'); }; sign = '-' | '+'; number_double = sign? (([0-9]+ '.' [0-9]+) | ('.' [0-9]+) | ([0-9]+)) ('e'i sign? digit+)?; number = number_i64 %{ fsm->numbers_i64.push_back(fsm->number_i64); }; real_number = number_double >{ fsm->number_double_start = p; } %{ fsm->numbers_double.push_back(fsm->parseDouble(fsm->number_double_start, p)); }; newline = ('\n' | '\r\n') @{ fsm->handleNewline(); }; anything = any | newline; multi_line_comment := anything* :>> '*/' @{ fgoto main; }; single_line_comment := (any - newline)* :>> ('\n' | '\r\n') @{ fgoto main; }; main := |* ( '#'[0-9a-fA-F]{6} ) { if (configuration.full_hex) fsm->colorHexFull(true); }; ( '#'[0-9a-fA-F]{3} ) { if (configuration.short_hex) fsm->colorHexShort(true); }; ( [0-9a-fA-F]{6} ) { if (configuration.full_hex) fsm->colorHexFull(false); }; ( [0-9a-fA-F]{3} ) { if (configuration.short_hex) fsm->colorHexShort(false); }; ( 'rgb'i '(' space* number space* ',' space* number space* ',' space* number space* ')' ) { if (configuration.css_rgb) fsm->colorRgb(); else fsm->clearNumberStacks(); }; ( 'rgba'i '(' space* number space* ',' space* number space* ',' space* number space* ',' space* real_number space* ')' ) { if (configuration.css_rgba) fsm->colorRgba(); else fsm->clearNumberStacks(); }; ( number space* ',' space* number space* ',' space* number ) { if (configuration.int_values) fsm->colorValueIntegers(); else fsm->clearNumberStacks(); }; ( number space+ number space+ number ) { if (configuration.int_values) fsm->colorValueIntegers(); else fsm->clearNumberStacks(); }; ( real_number space* ',' space* real_number space* ',' space* real_number ) { if (configuration.float_values) fsm->colorValues(); else fsm->clearNumberStacks(); }; ( real_number space+ real_number space+ real_number ) { if (configuration.float_values) fsm->colorValues(); else fsm->clearNumberStacks(); }; ( '//' ) { if (configuration.single_line_c_comments) fgoto single_line_comment; }; ( '/*' ) { if (configuration.multi_line_c_comments) fgoto multi_line_comment; }; ( '#' ) { if (configuration.single_line_hash_comments) fgoto single_line_comment; }; ( space+ ) { }; ( punct+ ) { }; ( (any - (newline | space | punct | '//' | '/*'))+ ) { }; ( newline ) { }; *|; }%% %% write data; bool scanner(TextFile &text_file, const Configuration &configuration) { FSM fsm_struct; FSM *fsm = &fsm_struct; fsm->ts = 0; fsm->te = 0; fsm->line = 0; fsm->line_start = 0; fsm->column = 0; fsm->buffer_offset = 0; bool parse_error = false; fsm->addColor = [&text_file](const Color &color){ Color c = color; color_rgb_normalize(&c); text_file.addColor(c); }; %% write init; int have = 0; while (1){ char *p = fsm->buffer + have; int space = sizeof(fsm->buffer) - have; if (space == 0){ text_file.outOfMemory(); break; } char *eof = 0; auto read_size = text_file.read(fsm->buffer + have, space); char *pe = p + read_size; if (read_size > 0){ if (read_size < sizeof(fsm->buffer)) eof = pe; %% write exec; if (fsm->cs == text_file_error) { parse_error = true; text_file.syntaxError(fsm->line, fsm->ts - fsm->buffer - fsm->line_start, fsm->line, fsm->te - fsm->buffer - fsm->line_start); break; } if (fsm->ts == 0){ have = 0; fsm->line_start -= sizeof(fsm->buffer); }else{ have = pe - fsm->ts; memmove(fsm->buffer, fsm->ts, have); int buffer_movement = fsm->ts - fsm->buffer; fsm->te -= buffer_movement; fsm->line_start -= buffer_movement; fsm->ts = fsm->buffer; fsm->buffer_offset += fsm->ts - fsm->buffer; } }else{ break; } } return parse_error == false; } } gpick-gpick-0.2.6/source/test/000077500000000000000000000000001377073231300161745ustar00rootroot00000000000000gpick-gpick-0.2.6/source/test/Dynv.cpp000066400000000000000000000207651377073231300176320ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include "dynv/Map.h" #include "Color.h" using Map = dynv::Map; using Ref = dynv::Ref; std::ostream &operator<<(std::ostream &stream, const Color &color) { stream << color.ma[0] << "," << color.ma[1] << "," << color.ma[2] << "," << color.ma[3]; return stream; } namespace dynv { std::ostream &operator<<(std::ostream &stream, const Ref &map) { if (map) stream << &*map; else stream << "-"; return stream; } } BOOST_AUTO_TEST_SUITE(dynv); BOOST_AUTO_TEST_CASE(basicBool) { Map map; map.set("bool", true); BOOST_CHECK_EQUAL(map.getBool("bool-", false), false); BOOST_CHECK_EQUAL(map.getBool("bool-", true), true); BOOST_CHECK_EQUAL(map.getBool("bool", false), true); BOOST_CHECK_EQUAL(map.getBool("bool", true), true); } BOOST_AUTO_TEST_CASE(basicFloat) { Map map; map.set("float", 0.5f); BOOST_CHECK_EQUAL(map.getFloat("float-", 0.0f), 0.0f); BOOST_CHECK_EQUAL(map.getFloat("float-", 1.0f), 1.0f); BOOST_CHECK_EQUAL(map.getFloat("float", 0.0f), 0.5f); BOOST_CHECK_EQUAL(map.getFloat("float", 1.0f), 0.5f); } BOOST_AUTO_TEST_CASE(basicInt32) { Map map; map.set("int32", 5); BOOST_CHECK_EQUAL(map.getInt32("int32-", 0), 0); BOOST_CHECK_EQUAL(map.getInt32("int32-", 1), 1); BOOST_CHECK_EQUAL(map.getInt32("int32", 0), 5); BOOST_CHECK_EQUAL(map.getInt32("int32", 1), 5); } BOOST_AUTO_TEST_CASE(basicString) { Map map; map.set("string", "a"); BOOST_CHECK_EQUAL(map.size(), 1); BOOST_CHECK(map.contains("string")); BOOST_CHECK_EQUAL(map.type("string"), "string"); BOOST_CHECK_EQUAL(map.getString("string-", "0"), "0"); BOOST_CHECK_EQUAL(map.getString("string-", "1"), "1"); BOOST_CHECK_EQUAL(map.getString("string", "0"), "a"); BOOST_CHECK_EQUAL(map.getString("string", "1"), "a"); } BOOST_AUTO_TEST_CASE(basicSystem) { Map map; Ref innerMap(new Map()); map.set("map", innerMap); innerMap->set("string", "a"); BOOST_CHECK_EQUAL(map.size(), 1); BOOST_CHECK(map.contains("map")); auto returnedSystem = map.getMap("map-"); BOOST_CHECK(!returnedSystem); returnedSystem = map.getMap("map"); BOOST_REQUIRE(returnedSystem); BOOST_CHECK_EQUAL(returnedSystem->size(), 1); } BOOST_AUTO_TEST_CASE(stringArray) { Map map; std::vector data { "a", "b", "c" }; map.set("a", data); auto result = map.getStrings("a"); BOOST_REQUIRE_EQUAL(result.size(), 3); for (int i = 0; i < 3; i++) { BOOST_CHECK_EQUAL(result[i], data[i]); } } BOOST_AUTO_TEST_CASE(constStringArray) { Map map; std::vector data { "a", "b", "c" }; map.set("a", data); auto result = map.getStrings("a"); BOOST_REQUIRE_EQUAL(result.size(), 3); for (int i = 0; i < 3; i++) { BOOST_CHECK_EQUAL(result[i], data[i]); } } BOOST_AUTO_TEST_CASE(stringArrayOverwrite) { Map map; std::vector data { "a", "b", "c" }; map.set("a", data); map.set("a", data); BOOST_CHECK_EQUAL(map.size(), 1); auto result = map.getStrings("a"); BOOST_REQUIRE_EQUAL(result.size(), 3); for (int i = 0; i < 3; i++) { BOOST_CHECK_EQUAL(result[i], data[i]); } } BOOST_AUTO_TEST_CASE(mapArray) { Map map; std::vector data { new Map(), new Map(), new Map() }; map.set("a", data); auto result = map.getMaps("a"); BOOST_CHECK_EQUAL(data.size(), 3); BOOST_REQUIRE_EQUAL(result.size(), 3); for (int i = 0; i < 3; i++) { BOOST_CHECK_EQUAL(result[i], data[i]); BOOST_CHECK_EQUAL(result[i]->references(), 3); } } BOOST_AUTO_TEST_CASE(noMoveOnSet) { Map map; std::vector data { new Map() }; map.set("a", data); BOOST_CHECK_EQUAL(map.size(), 1); BOOST_CHECK_EQUAL(data.size(), 1); } BOOST_AUTO_TEST_CASE(xmlDeserialize) { Map map; std::ifstream file("test/config01.xml"); BOOST_REQUIRE(file.is_open()); BOOST_REQUIRE(map.deserializeXml(file)); file.close(); BOOST_CHECK_EQUAL(map.size(), 1); BOOST_REQUIRE(map.contains("test")); auto values = map.getStrings("test"); BOOST_REQUIRE_EQUAL(values.size(), 3); const char *data[] = { "a", "b", "c" }; for (int i = 0; i < 3; i++) { BOOST_CHECK_EQUAL(values[i], data[i]); } } BOOST_AUTO_TEST_CASE(xmlSerializeDeserialize) { Map map; std::vector items; for (int i = 0; i < 10; i++) { Ref item(new Map()); item->set("name", "a"); item->set("color", Color(static_cast(1.0f / (10 - 1) * i))); items.push_back(item); } map.set("items", items); std::stringstream output; map.serializeXml(output); auto text = output.str(); BOOST_TEST_MESSAGE("Serialized XML: " << text); std::stringstream input(text); Map result; result.deserializeXml(input); BOOST_CHECK_EQUAL(result.size(), 1); BOOST_REQUIRE(result.contains("items")); auto resultItems = result.getMaps("items"); BOOST_CHECK_EQUAL(resultItems.size(), 10); Color nullColor { 0 }; for (int i = 0; i < 10; i++) { BOOST_CHECK_EQUAL(resultItems[i]->getString("name", ""), "a"); BOOST_CHECK_EQUAL(resultItems[i]->getColor("color", nullColor), Color(static_cast(1.0f / (10 - 1) * i))); } } BOOST_AUTO_TEST_CASE(missingPathSegmentCreationOnSet) { Map map; map.set("values.bool", true); BOOST_CHECK_EQUAL(map.size(), 1); BOOST_CHECK(map.contains("values")); BOOST_CHECK(map.contains("values.bool")); auto values = map.getMap("values"); BOOST_REQUIRE(values); BOOST_CHECK(values->contains("bool")); BOOST_CHECK_EQUAL(values->getBool("bool", false), true); } BOOST_AUTO_TEST_CASE(noMissingPathSegmentCreationOnGet) { Map map; map.getBool("values.bool", false); BOOST_CHECK_EQUAL(map.size(), 0); } BOOST_AUTO_TEST_CASE(getOrCreateMap) { Map map; auto values = map.getOrCreateMap("values"); BOOST_CHECK_EQUAL(map.size(), 1); BOOST_CHECK(map.contains("values")); BOOST_REQUIRE(values); } BOOST_AUTO_TEST_CASE(nestedPathCreation) { Map map; map.set("a.b.c.d", "value"); BOOST_CHECK(map.getMap("a")); BOOST_CHECK(map.getMap("a.b")); BOOST_CHECK(map.getMap("a.b.c")); auto result = map.getMap("a.b.c"); BOOST_REQUIRE(result); BOOST_CHECK_EQUAL(result->getString("d", ""), "value"); } BOOST_AUTO_TEST_CASE(typeForcing) { Map map; map.set("value", 1); BOOST_CHECK_EQUAL(map.getBool("value", false), true); } BOOST_AUTO_TEST_CASE(stringTypes) { Map map; const char *constCharPointer = "value"; auto charPointer = const_cast(constCharPointer); using CustomString = char *; auto customString = reinterpret_cast(charPointer); for (int i = 0; i < 2; i++) { map.set("a", constCharPointer); map.set("b", charPointer); map.set("c", customString); BOOST_CHECK_EQUAL(map.getString("a", ""), "value"); BOOST_CHECK_EQUAL(map.getString("b", ""), "value"); BOOST_CHECK_EQUAL(map.getString("c", ""), "value"); } } BOOST_AUTO_TEST_CASE(spans) { Map map; bool bools[] = { true, true, false }; int ints[] = { 0, 1, 2 }; const char *strings[] = { "a", "b", "c" }; map.set("bools", common::Span(bools, 3)); map.set("ints", common::Span(ints, 3)); map.set("strings", common::Span(strings, 3)); BOOST_CHECK_EQUAL(map.getBools("bools").size(), 3); BOOST_CHECK_EQUAL(map.getInt32s("ints").size(), 3); BOOST_CHECK_EQUAL(map.getStrings("strings").size(), 3); } BOOST_AUTO_TEST_SUITE_END() gpick-gpick-0.2.6/source/test/Format.cpp000066400000000000000000000044121377073231300201310ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "common/Format.h" using namespace common; BOOST_AUTO_TEST_CASE(format_empty) { BOOST_CHECK_EQUAL(format(""), ""); } BOOST_AUTO_TEST_CASE(format_missing_value) { BOOST_CHECK_EQUAL(format("{}"), ""); } BOOST_AUTO_TEST_CASE(format_useless_value) { BOOST_CHECK_EQUAL(format("", 123), ""); } BOOST_AUTO_TEST_CASE(format_int) { BOOST_CHECK_EQUAL(format("Hello world {}", 123), "Hello world 123"); } BOOST_AUTO_TEST_CASE(format_string) { BOOST_CHECK_EQUAL(format("Hello {}", "world"), "Hello world"); } BOOST_AUTO_TEST_CASE(format_mixed) { BOOST_CHECK_EQUAL(format("Hello {} {}", "world", 123), "Hello world 123"); } BOOST_AUTO_TEST_CASE(format_unterminated) { BOOST_CHECK_EQUAL(format("Hello {", 123), "Hello {"); } gpick-gpick-0.2.6/source/test/Main.cpp000066400000000000000000000031241377073231300175640ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #define BOOST_TEST_MODULE tests #include gpick-gpick-0.2.6/source/test/Result.cpp000066400000000000000000000074321377073231300201640ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "common/Result.h" using namespace common; BOOST_AUTO_TEST_SUITE(result); BOOST_AUTO_TEST_CASE(booleanValue) { Result resultEmpty; Result resultTrue(true); Result resultFalse(false); BOOST_CHECK(!resultEmpty); BOOST_CHECK(resultTrue); BOOST_CHECK(resultFalse); BOOST_CHECK(resultTrue.value()); BOOST_CHECK(!resultFalse.value()); } BOOST_AUTO_TEST_CASE(booleanError) { Result resultEmpty; Result errorTrue(true); Result errorFalse(false); BOOST_CHECK(resultEmpty); BOOST_CHECK(!errorTrue); BOOST_CHECK(!errorFalse); BOOST_CHECK(errorTrue.error()); BOOST_CHECK(!errorFalse.error()); } BOOST_AUTO_TEST_CASE(booleanValueAndError) { Result resultEmpty; Result resultTrue(true, true); Result resultFalse(true, false); Result errorTrue(false, true); Result errorFalse(false, false); BOOST_CHECK(!resultEmpty); BOOST_CHECK(resultTrue); BOOST_CHECK(resultFalse); BOOST_CHECK(resultTrue.value()); BOOST_CHECK(!resultFalse.value()); BOOST_CHECK(!errorTrue); BOOST_CHECK(!errorFalse); BOOST_CHECK(errorTrue.error()); BOOST_CHECK(!errorFalse.error()); } struct Movable { Movable() { } Movable(const Movable &) = delete; Movable(Movable &&movable) { } Movable &operator=(const Movable &) = delete; Movable &operator=(Movable &&movable) { return *this; } }; static Result returnMovableValue() { return Result(Movable()); } static Result returnMovableError() { return Result(Movable()); } static Result returnMovableValueAndError(bool status) { return Result(status, Movable()); } static Result returnMovableErrorWithValue() { return Result(Movable()); } static Result returnMovableValueWithError() { return Result(Movable()); } BOOST_AUTO_TEST_CASE(movable) { BOOST_CHECK(returnMovableValue()); BOOST_CHECK(!returnMovableError()); BOOST_CHECK(returnMovableValueAndError(true)); BOOST_CHECK(!returnMovableValueAndError(false)); BOOST_CHECK(returnMovableValueWithError()); BOOST_CHECK(!returnMovableErrorWithValue()); } BOOST_AUTO_TEST_SUITE_END() gpick-gpick-0.2.6/source/test/Scoped.cpp000066400000000000000000000046461377073231300201270ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "common/Scoped.h" #include using namespace common; BOOST_AUTO_TEST_SUITE(scoped); BOOST_AUTO_TEST_CASE(test10) { bool result = false; std::function callable = [&result]() { result = true; }; { Scoped> callOnScopeEnd(callable); } BOOST_CHECK_EQUAL(result, true); } BOOST_AUTO_TEST_CASE(test11) { bool result = false; std::function callable = [&result]() { result = true; }; { makeScoped(callable); } BOOST_CHECK_EQUAL(result, true); } static void makeTrue(bool *value) { *value = true; } BOOST_AUTO_TEST_CASE(test20) { bool result = false; { Scoped callOnScopeEnd(makeTrue, &result); } BOOST_CHECK_EQUAL(result, true); } BOOST_AUTO_TEST_CASE(test21) { bool result = false; { makeScoped(&makeTrue, &result); } BOOST_CHECK_EQUAL(result, true); } BOOST_AUTO_TEST_SUITE_END() gpick-gpick-0.2.6/source/test/Script.cpp000066400000000000000000000054471377073231300201560ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "lua/Script.h" extern "C" { #include #include } using namespace lua; static int test(lua_State *L) { lua_pushstring(L, "ok"); return 1; } BOOST_AUTO_TEST_CASE(register_extension) { Script script; bool status = script.registerExtension("test", [](Script &script) { static const struct luaL_Reg functions[] = { { "test", test }, { nullptr, nullptr } }; luaL_newlib(script, functions); return 1; }); BOOST_CHECK(status == true); status = script.loadCode("test = require(\"gpick/test\")\nreturn test.test()"); BOOST_CHECK(status == true); status = script.run(0, 1); BOOST_CHECK(status == true); std::string returnValue = script.getString(-1); BOOST_CHECK(returnValue == "ok"); } BOOST_AUTO_TEST_CASE(register_nullptr_extension) { Script script; bool status = script.registerExtension(nullptr, [](Script &script) { lua_State *L = script; lua_newtable(L); lua_pushstring(L, "ok"); lua_setfield(L, -2, "test"); return 1; }); BOOST_CHECK(status == true); status = script.loadCode("test = require(\"gpick\")\nreturn test.test"); BOOST_CHECK(status == true); status = script.run(0, 1); BOOST_CHECK(status == true); std::string returnValue = script.getString(-1); BOOST_CHECK(returnValue == "ok"); } gpick-gpick-0.2.6/source/test/Span.cpp000066400000000000000000000051011377073231300175760ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "common/Span.h" #include using namespace common; BOOST_AUTO_TEST_SUITE(span); BOOST_AUTO_TEST_CASE(iteration) { size_t j = 0; std::string result; for (auto i: Span("test", 4)) { j++; result += i; } BOOST_CHECK_EQUAL(j, 4); BOOST_CHECK_EQUAL(result, "test"); } BOOST_AUTO_TEST_CASE(constIteration) { size_t j = 0; std::string result; auto span = Span("test", 4); const auto &values = span; for (auto i: values) { j++; result += i; } BOOST_CHECK_EQUAL(j, 4); BOOST_CHECK_EQUAL(result, "test"); } BOOST_AUTO_TEST_CASE(size) { BOOST_CHECK_EQUAL(Span("value", 5).size(), 5); } BOOST_AUTO_TEST_CASE(vectorInitialization) { auto span = Span("value", 5); std::vector value(span.begin(), span.end()); BOOST_CHECK_EQUAL(value.size(), 5); } BOOST_AUTO_TEST_CASE(startEndInitialization) { bool bools[] = { false, true, false, true, false }; auto span = Span(bools, bools + 5); BOOST_CHECK_EQUAL(span.size(), 5); } BOOST_AUTO_TEST_SUITE_END() gpick-gpick-0.2.6/source/test/TextFileParser.cpp000066400000000000000000000137011377073231300216030ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include "parser/TextFile.h" #include "Color.h" using namespace text_file_parser; struct Parser: public TextFile { std::istream *m_stream; std::vector m_colors; bool m_failed; Parser(std::istream *stream) { m_stream = stream; m_failed = false; } virtual ~Parser() { } virtual void outOfMemory() { m_failed = true; } virtual void syntaxError(size_t start_line, size_t start_column, size_t end_line, size_t end_colunn) { m_failed = true; } virtual size_t read(char *buffer, size_t length) { m_stream->read(buffer, length); size_t bytes = m_stream->gcount(); if (bytes > 0) return bytes; if (m_stream->eof()) return 0; if (!m_stream->good()) { m_failed = true; } return 0; } virtual void addColor(const Color &color) { m_colors.push_back(color); } size_t count() { return m_colors.size(); } bool checkColor(size_t index, const Color &color) { return color_equal(&m_colors[index], &color); } void parse() { Configuration configuration; TextFile::parse(configuration); } }; BOOST_AUTO_TEST_CASE(full_hex) { std::ifstream file("test/textImport01.txt"); BOOST_REQUIRE(file.is_open()); Parser parser(&file); parser.parse(); BOOST_CHECK(parser.count() == 1); Color color; color_set(&color, 0xaa, 0xbb, 0xcc); BOOST_CHECK(parser.checkColor(0, color)); file.close(); } BOOST_AUTO_TEST_CASE(short_hex) { std::ifstream file("test/textImport02.txt"); BOOST_REQUIRE(file.is_open()); Parser parser(&file); parser.parse(); BOOST_CHECK(parser.count() == 1); Color color; color_set(&color, 0xaa, 0xbb, 0xcc); BOOST_CHECK(parser.checkColor(0, color)); file.close(); } BOOST_AUTO_TEST_CASE(css_rgb) { std::ifstream file("test/textImport03.txt"); BOOST_REQUIRE(file.is_open()); Parser parser(&file); parser.parse(); BOOST_CHECK(parser.count() == 1); Color color; color_set(&color, 0xaa, 0xbb, 0xcc); BOOST_CHECK(parser.checkColor(0, color)); file.close(); } BOOST_AUTO_TEST_CASE(css_rgba) { std::ifstream file("test/textImport04.txt"); BOOST_REQUIRE(file.is_open()); Parser parser(&file); parser.parse(); BOOST_CHECK(parser.count() == 1); Color color; color_set(&color, 0xaa, 0xbb, 0xcc); color.ma[3] = 0.5; BOOST_CHECK(parser.checkColor(0, color)); file.close(); } BOOST_AUTO_TEST_CASE(int_values) { std::ifstream file("test/textImport05.txt"); BOOST_REQUIRE(file.is_open()); Parser parser(&file); parser.parse(); BOOST_CHECK(parser.count() == 1); Color color; color_set(&color, 0xaa, 0xbb, 0xcc); BOOST_CHECK(parser.checkColor(0, color)); file.close(); } BOOST_AUTO_TEST_CASE(float_values_separated_by_comma) { std::ifstream file("test/textImport06.txt"); BOOST_REQUIRE(file.is_open()); Parser parser(&file); parser.parse(); BOOST_CHECK(parser.count() == 1); Color color; color_set(&color, 0xaa, 0xbb, 0xcc); BOOST_CHECK(parser.checkColor(0, color)); file.close(); } BOOST_AUTO_TEST_CASE(float_values_separated_by_space) { std::ifstream file("test/textImport10.txt"); BOOST_REQUIRE(file.is_open()); Parser parser(&file); parser.parse(); BOOST_CHECK(parser.count() == 1); Color color; color_set(&color, 0xaa, 0xbb, 0xcc); BOOST_CHECK(parser.checkColor(0, color)); file.close(); } BOOST_AUTO_TEST_CASE(single_line_c_comments) { std::ifstream file("test/textImport07.txt"); BOOST_REQUIRE(file.is_open()); Parser parser(&file); parser.parse(); BOOST_CHECK(parser.count() == 1); Color color; color_set(&color, 0xaa, 0xbb, 0xcc); BOOST_CHECK(parser.checkColor(0, color)); file.close(); } BOOST_AUTO_TEST_CASE(multi_line_c_comments) { std::ifstream file("test/textImport08.txt"); BOOST_REQUIRE(file.is_open()); Parser parser(&file); parser.parse(); BOOST_CHECK(parser.count() == 1); Color color; color_set(&color, 0xaa, 0xbb, 0xcc); BOOST_CHECK(parser.checkColor(0, color)); file.close(); } BOOST_AUTO_TEST_CASE(single_line_hash_comments) { std::ifstream file("test/textImport09.txt"); BOOST_REQUIRE(file.is_open()); Parser parser(&file); parser.parse(); BOOST_CHECK(parser.count() == 1); Color color; color_set(&color, 0xaa, 0xbb, 0xcc); BOOST_CHECK(parser.checkColor(0, color)); file.close(); } BOOST_AUTO_TEST_CASE(out_of_range_float_value) { std::ifstream file("test/textImport11.txt"); BOOST_REQUIRE(file.is_open()); Parser parser(&file); parser.parse(); BOOST_CHECK(parser.count() == 1); Color color; color_set(&color, 0xaa, 0xbb, 0); BOOST_CHECK(parser.checkColor(0, color)); file.close(); } gpick-gpick-0.2.6/source/tools/000077500000000000000000000000001377073231300163555ustar00rootroot00000000000000gpick-gpick-0.2.6/source/tools/ColorSpaceSampler.cpp000066400000000000000000000304641377073231300224460ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ColorSpaceSampler.h" #include "ColorList.h" #include "ColorObject.h" #include "GlobalState.h" #include "I18N.h" #include "dynv/Map.h" #include "uiListPalette.h" #include "uiUtilities.h" #include "ToolColorNaming.h" #include #include using namespace std; #define N_AXIS 3 struct AxisOptions { GtkWidget *range_samples; GtkWidget *range_min_value; GtkWidget *range_max_value; GtkWidget *toggle_include_max_value; int samples; float min_value; float max_value; bool include_max_value; }; struct ColorSpaceSamplerArgs { GtkWidget *combo_color_space; GtkWidget *toggle_linearization; int color_space; bool linearization; AxisOptions axis[N_AXIS]; GtkWidget *preview_expander; ColorList *color_list; ColorList *preview_color_list; dynv::Ref options; GlobalState* gs; }; struct ColorSpaceSamplerNameAssigner: public ToolColorNameAssigner { protected: stringstream m_stream; public: ColorSpaceSamplerNameAssigner(GlobalState *gs): ToolColorNameAssigner(gs) { } void assign(ColorObject *color_object, const Color *color) { ToolColorNameAssigner::assign(color_object, color); } virtual std::string getToolSpecificName(ColorObject *color_object, const Color *color) { m_stream.str(""); m_stream << _("color space"); return m_stream.str(); } }; static void calc(ColorSpaceSamplerArgs *args, bool preview, size_t limit) { ColorSpaceSamplerNameAssigner name_assigner(args->gs); ColorList *color_list; if (preview) color_list = args->preview_color_list; else color_list = args->gs->getColorList(); vector values; size_t value_count = args->axis[0].samples * args->axis[1].samples * args->axis[2].samples; if (preview) value_count = std::min(limit, value_count); values.resize(value_count); size_t value_i = 0; for (int x = 0; x < args->axis[0].samples; x++){ float x_value = (args->axis[0].samples > 1) ? (args->axis[0].min_value + (args->axis[0].max_value - args->axis[0].min_value) * (x / (float)(args->axis[0].samples - 1))) : args->axis[0].min_value; for (int y = 0; y < args->axis[1].samples; y++){ float y_value = (args->axis[1].samples > 1) ? (args->axis[1].min_value + (args->axis[1].max_value - args->axis[1].min_value) * (y / (float)(args->axis[1].samples - 1))) : args->axis[1].min_value; for (int z = 0; z < args->axis[2].samples; z++){ float z_value = (args->axis[2].samples > 1) ? (args->axis[2].min_value + (args->axis[2].max_value - args->axis[2].min_value) * (z / (float)(args->axis[2].samples - 1))) : args->axis[2].min_value; values[value_i].ma[0] = x_value; values[value_i].ma[1] = y_value; values[value_i].ma[2] = z_value; value_i++; if (preview && value_i >= limit){ x = args->axis[0].samples; y = args->axis[1].samples; break; } } } } Color t; for (size_t i = 0; i < value_count; i++){ if (preview){ if (limit <= 0) return; limit--; } switch (args->color_space){ case 0: color_copy(&values[i], &t); break; case 1: color_hsv_to_rgb(&values[i], &t); break; case 2: color_hsl_to_rgb(&values[i], &t); break; case 3: color_copy(&values[i], &t); t.lab.L *= 100; t.lab.a = (t.lab.a - 0.5f) * 290; t.lab.b = (t.lab.b - 0.5f) * 290; color_lab_to_rgb_d50(&t, &t); break; case 4: color_copy(&values[i], &t); t.lch.L *= 100; t.lch.C *= 136; t.lch.h *= 360; color_lch_to_rgb_d50(&t, &t); break; } if (args->linearization) color_linear_get_rgb(&t, &t); color_rgb_normalize(&t); ColorObject *color_object = color_list_new_color_object(color_list, &t); name_assigner.assign(color_object, &t); color_list_add_color_object(color_list, color_object, 1); color_object->release(); } } static void destroy_cb(GtkWidget* widget, ColorSpaceSamplerArgs *args) { color_list_destroy(args->preview_color_list); delete args; } static void get_settings(ColorSpaceSamplerArgs *args) { args->color_space = gtk_combo_box_get_active(GTK_COMBO_BOX(args->combo_color_space)); args->linearization = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->toggle_linearization)); for (int i = 0; i < N_AXIS; i++){ args->axis[i].samples = gtk_spin_button_get_value(GTK_SPIN_BUTTON(args->axis[i].range_samples)); args->axis[i].min_value = gtk_spin_button_get_value(GTK_SPIN_BUTTON(args->axis[i].range_min_value)); args->axis[i].max_value = gtk_spin_button_get_value(GTK_SPIN_BUTTON(args->axis[i].range_max_value)); } } static dynv::Ref get_axis_config(int axis, ColorSpaceSamplerArgs *args) { stringstream config_name; config_name << "axis" << axis; string config_name_string = config_name.str(); return args->options->getOrCreateMap(config_name_string); } static void save_settings(ColorSpaceSamplerArgs *args) { args->options->set("color_space", args->color_space); args->options->set("linearization", args->linearization); for (int i = 0; i < N_AXIS; i++){ auto axis_config = get_axis_config(i, args); axis_config->set("samples", args->axis[i].samples); axis_config->set("min_value", args->axis[i].min_value); axis_config->set("max_value", args->axis[i].max_value); } } static void update(GtkWidget *widget, ColorSpaceSamplerArgs *args) { color_list_remove_all(args->preview_color_list); get_settings(args); calc(args, true, 100); } static void response_cb(GtkWidget* widget, gint response_id, ColorSpaceSamplerArgs *args) { get_settings(args); save_settings(args); gint width, height; gtk_window_get_size(GTK_WINDOW(widget), &width, &height); args->options->set("window.width", width); args->options->set("window.height", height); args->options->set("show_preview", gtk_expander_get_expanded(GTK_EXPANDER(args->preview_expander))); switch (response_id){ case GTK_RESPONSE_APPLY: calc(args, false, 0); break; case GTK_RESPONSE_DELETE_EVENT: break; case GTK_RESPONSE_CLOSE: gtk_widget_destroy(widget); break; } } void tools_color_space_sampler_show(GtkWindow* parent, GlobalState* gs) { ColorSpaceSamplerArgs *args = new ColorSpaceSamplerArgs; args->gs = gs; args->options = args->gs->settings().getOrCreateMap("gpick.tools.color_space_sampler"); int table_m_y; GtkWidget *table, *table_m, *widget; GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Color space sampler"), parent, GtkDialogFlags(GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, GTK_STOCK_ADD, GTK_RESPONSE_APPLY, nullptr); gtk_window_set_default_size(GTK_WINDOW(dialog), args->options->getInt32("window.width", -1), args->options->getInt32("window.height", -1)); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_APPLY, GTK_RESPONSE_CLOSE, -1); table_m = gtk_table_new(3, 1, FALSE); table_m_y = 0; int table_y; table = gtk_table_new(7, 3, FALSE); gtk_table_attach(GTK_TABLE(table_m), table, 0, 1, table_m_y, table_m_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); table_m_y++; table_y = 0; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Color space:")), 0, 1, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 5, 5); args->combo_color_space = widget = gtk_combo_box_text_new(); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), _("RGB")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), _("HSV")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), _("HSL")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), _("LAB")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), _("LCH")); gtk_combo_box_set_active(GTK_COMBO_BOX(widget), args->options->getInt32("color_space", 0)); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 5, 0); g_signal_connect(G_OBJECT(widget), "changed", G_CALLBACK(update), args); table_y++; args->toggle_linearization = gtk_check_button_new_with_mnemonic(_("_Linearization")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(args->toggle_linearization), args->options->getBool("linearization", false)); gtk_table_attach(GTK_TABLE(table), args->toggle_linearization,1,4,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); g_signal_connect(G_OBJECT(args->toggle_linearization), "toggled", G_CALLBACK(update), args); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Sample count")), 1, 3, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 5, 5); gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Minimal value")), 3, 5, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 5, 5); gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Maximal value")), 5, 7, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 5, 5); table_y++; const char *axis_names[] = { _("X axis"), _("Y axis"), _("Z axis"), }; for (int i = 0; i < N_AXIS; i++){ string axis_name = string(axis_names[i]) + ":"; auto axis_config = get_axis_config(i, args); gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(axis_name.c_str()), 0, 1, table_y, table_y + 1, GtkAttachOptions(GTK_FILL), GTK_FILL, 5, 5); args->axis[i].range_samples = widget = gtk_spin_button_new_with_range(1, 255, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), axis_config->getInt32("samples", 12)); gtk_table_attach(GTK_TABLE(table), widget, 1, 3, table_y, table_y + 1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL, 3, 3); g_signal_connect(G_OBJECT(widget), "value-changed", G_CALLBACK(update), args); args->axis[i].range_min_value = widget = gtk_spin_button_new_with_range(0, 1, 0.001); gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), axis_config->getFloat("min_value", 0)); gtk_table_attach(GTK_TABLE(table), widget, 3, 5, table_y, table_y + 1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL, 3, 3); g_signal_connect(G_OBJECT(widget), "value-changed", G_CALLBACK(update), args); args->axis[i].range_max_value = widget = gtk_spin_button_new_with_range(0, 1, 0.001); gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), axis_config->getFloat("max_value", 1)); gtk_table_attach(GTK_TABLE(table), widget, 5, 7, table_y, table_y + 1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL, 3, 3); g_signal_connect(G_OBJECT(widget), "value-changed", G_CALLBACK(update), args); table_y++; } ColorList* preview_color_list = nullptr; gtk_table_attach(GTK_TABLE(table_m), args->preview_expander = palette_list_preview_new(gs, true, args->options->getBool("show_preview", true), gs->getColorList(), &preview_color_list), 0, 1, table_m_y, table_m_y+1 , GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL | GTK_EXPAND), 5, 5); table_m_y++; args->preview_color_list = preview_color_list; get_settings(args); calc(args, true, 100); gtk_widget_show_all(table_m); setDialogContent(dialog, table_m); g_signal_connect(G_OBJECT(dialog), "destroy", G_CALLBACK(destroy_cb), args); g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(response_cb), args); gtk_widget_show(dialog); } gpick-gpick-0.2.6/source/tools/ColorSpaceSampler.h000066400000000000000000000034101377073231300221020ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_TOOLS_COLOR_SPACE_SAMPLER_H_ #define GPICK_TOOLS_COLOR_SPACE_SAMPLER_H_ #include struct GlobalState; void tools_color_space_sampler_show(GtkWindow* parent, GlobalState* gs); #endif /* GPICK_TOOLS_COLOR_SPACE_SAMPLER_H_ */ gpick-gpick-0.2.6/source/tools/PaletteFromImage.cpp000066400000000000000000000435121377073231300222530ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "PaletteFromImage.h" #include "ColorList.h" #include "ColorObject.h" #include "uiUtilities.h" #include "uiListPalette.h" #include "GlobalState.h" #include "ToolColorNaming.h" #include "dynv/Map.h" #include "I18N.h" #include #include #include #include #include using namespace std; /** \file PaletteFromImage.cpp * \brief */ /** \struct Node * \brief Node is a cube in space with color information * * Each node can b */ struct Node{ uint32_t n_pixels; /**< Number of colors in current Node and its children */ uint32_t n_pixels_in; /**< Number of colors in current Node */ float color[3]; /**< Sum of color values */ float distance; /**< Squared distances from Node center of colors in Node */ Node *child[8]; /**< Pointers to child Nodes */ Node *parent; /**< Pointer to parent Node */ }; /** \struct Cube * \brief Cube structure holds all information necessary to define cube size and position in space */ struct Cube{ float x; /**< X position */ float w; /**< Width */ float y; /**< Y position */ float h; /**< Height */ float z; /**< Z position */ float d; /**< Depth */ }; struct PaletteFromImageArgs{ GtkWidget *file_browser; GtkWidget *range_colors; GtkWidget *merge_threshold; GtkWidget *preview_expander; string filename; uint32_t n_colors; string previous_filename; Node *previous_node; ColorList *color_list; ColorList *preview_color_list; dynv::Ref options; GlobalState* gs; }; struct PaletteColorNameAssigner: public ToolColorNameAssigner { protected: stringstream m_stream; const char *m_filename; int m_index; public: PaletteColorNameAssigner(GlobalState *gs): ToolColorNameAssigner(gs) { m_index = 0; } void assign(ColorObject *color_object, const Color *color, const char *filename, const int index) { m_filename = filename; m_index = index; ToolColorNameAssigner::assign(color_object, color); } virtual std::string getToolSpecificName(ColorObject *color_object, const Color *color) { m_stream.str(""); m_stream << m_filename << " #" << m_index; return m_stream.str(); } }; /** * Allocate and initialize a new node with specified parent * @param[in] parent Parent node * @return New node */ static Node* node_new(Node *parent){ Node *n = new Node; n->color[0] = n->color[1] = n->color[2] = 0; n->distance = 0; n->n_pixels = 0; n->n_pixels_in = 0; n->parent = parent; for (int i = 0; i < 8; i++){ n->child[i] = 0; } return n; } /** * Deallocate node and its children * @param[in] node Node to deallocate */ static void node_delete(Node *node){ for (int i = 0; i < 8; i++){ if (node->child[i]){ node_delete(node->child[i]); } } delete node; } /** * Copy node and assing new parent * @param[in] node Node to copy * @param[in] parent Parent of copied node * @return A copy of node */ static Node* node_copy(Node *node, Node *parent){ Node *n = node_new(0); memcpy(n, node, sizeof(Node)); n->parent = parent; for (int i = 0; i < 8; i++){ if (node->child[i]){ n->child[i] = node_copy(node->child[i], n); }else{ n->child[i] = 0; } } return n; } /** * Get the number of nodes with available color information in them * @param[in] node Start from this node * @return Number of nodes with available color information in them */ static uint32_t node_count_leafs(Node *node){ uint32_t r = 0; if (node->n_pixels_in) r++; for (int i = 0; i < 8; i++){ if (node->child[i]) r += node_count_leafs(node->child[i]); } return r; } /** * Call callback on all nodes with available color information in them * @param[in] node Start from this node * @param[in] leaf_cb Callback function * @param[in] userdata User supplied pointer which is passed when calling callback */ static void node_leaf_callback(Node *node, void (*leaf_cb)(Node* node, void* userdata), void* userdata){ if (node->n_pixels_in > 0) leaf_cb(node, userdata); for (int i = 0; i < 8; i++){ if (node->child[i]) node_leaf_callback(node->child[i], leaf_cb, userdata); } } /** * Merge node information into its parent node * @param[in] node Node to merge */ static void node_prune(Node *node){ for (int i = 0; i < 8; i++){ if (node->child[i]){ node_prune(node->child[i]); node->child[i] = 0; } } if (node->parent){ node->parent->n_pixels_in += node->n_pixels_in; node->parent->color[0] += node->color[0]; node->parent->color[1] += node->color[1]; node->parent->color[2] += node->color[2]; } node_delete(node); } typedef struct PruneData{ float threshold; float min_distance; uint32_t n_colors; uint32_t n_colors_target; Node *prune_node; uint32_t distant_nodes; }PruneData; static bool node_prune_threshold(Node *node, PruneData *prune_data){ if (node->distance <= prune_data->threshold){ uint32_t colors_removed = node_count_leafs(node); node_prune(node); prune_data->n_colors -= colors_removed; return true; } if (node->distance < prune_data->min_distance){ prune_data->min_distance = node->distance; } uint32_t n = node->n_pixels_in; for (int i = 0; i < 8; i++){ if (node->child[i]){ if (node_prune_threshold(node->child[i], prune_data)){ node->child[i] = 0; } } } if (node->n_pixels_in > 0 && n == 0) prune_data->n_colors++; return false; } static void node_reduce(Node *node, uint32_t colors){ PruneData prune_data; prune_data.n_colors = node_count_leafs(node); prune_data.n_colors_target = colors; prune_data.threshold = 0; while (prune_data.n_colors > colors){ prune_data.min_distance = node->distance; if (node_prune_threshold(node, &prune_data)) break; prune_data.threshold = prune_data.min_distance; } } static void node_update(Node *node, Color *color, Cube *cube, uint32_t max_depth){ Cube new_cube; new_cube.w = cube->w / 2; new_cube.h = cube->h / 2; new_cube.d = cube->d / 2; node->n_pixels++; node->distance += (color->xyz.x - (cube->x + new_cube.w)) * (color->xyz.x - (cube->x + new_cube.w)) + (color->xyz.y - (cube->y + new_cube.h)) * (color->xyz.y - (cube->y + new_cube.h)) + (color->xyz.z - (cube->z + new_cube.d)) * (color->xyz.z - (cube->z + new_cube.d)); if (!max_depth){ node->n_pixels_in++; node->color[0] += color->xyz.x; node->color[1] += color->xyz.y; node->color[2] += color->xyz.z; }else{ int x, y, z; if (color->xyz.x - cube->x < new_cube.w) x = 0; else x = 1; if (color->xyz.y - cube->y < new_cube.h) y = 0; else y = 1; if (color->xyz.z - cube->z < new_cube.d) z = 0; else z = 1; new_cube.x = cube->x + new_cube.w * x; new_cube.y = cube->y + new_cube.h * y; new_cube.z = cube->z + new_cube.d * z; int i = x | (y<<1) | (z<<2); if (!node->child[i]) node->child[i] = node_new(node); node->n_pixels++; node_update(node->child[x | (y<<1) | (z<<2)], color, &new_cube, max_depth - 1); } } static void leaf_cb(Node *node, void *userdata){ list *l = static_cast*>(userdata); Color c; c.xyz.x = node->color[0] / node->n_pixels_in; c.xyz.y = node->color[1] / node->n_pixels_in; c.xyz.z = node->color[2] / node->n_pixels_in; l->push_back(c); } static Node* process_image(PaletteFromImageArgs *args, const char *filename, Node* node){ if (args->previous_filename == filename){ if (args->previous_node) return node_copy(args->previous_node, 0); else return 0; } args->previous_filename = filename; if (args->previous_node){ node_delete(args->previous_node); args->previous_node = 0; } GError *error = nullptr; GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(filename, &error); if (error){ cout << error->message << endl; g_error_free(error); return 0; } int channels = gdk_pixbuf_get_n_channels(pixbuf); int width = gdk_pixbuf_get_width(pixbuf); int height = gdk_pixbuf_get_height(pixbuf); int rowstride = gdk_pixbuf_get_rowstride(pixbuf); guchar *image_data = gdk_pixbuf_get_pixels(pixbuf); guchar *ptr = image_data; Cube cube; cube.x = 0; cube.y = 0; cube.z = 0; cube.w = 1; cube.h = 1; cube.d = 1; Color color; args->previous_node = node_new(0); for (int y = 0; y < height; y++){ ptr = image_data + rowstride * y; for (int x = 0; x < width; x++){ color.xyz.x = ptr[0] / 255.0f; color.xyz.y = ptr[1] / 255.0f; color.xyz.z = ptr[2] / 255.0f; node_update(args->previous_node, &color, &cube, 5); ptr += channels; } } g_object_unref(pixbuf); node_reduce(args->previous_node, 200); return node_copy(args->previous_node, 0); } static void get_settings(PaletteFromImageArgs *args){ gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(args->file_browser)); if (filename){ args->filename = filename; g_free(filename); }else{ args->filename.clear(); } args->n_colors = gtk_spin_button_get_value(GTK_SPIN_BUTTON(args->range_colors)); } static void save_settings(PaletteFromImageArgs *args){ args->options->set("colors", static_cast(args->n_colors)); gchar *current_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(args->file_browser)); if (current_folder){ args->options->set("current_folder", current_folder); g_free(current_folder); } GtkFileFilter *filter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(args->file_browser)); if (filter){ const char *filter_name = static_cast(g_object_get_data(G_OBJECT(filter), "name")); args->options->set("filter", filter_name); } } static void calc(PaletteFromImageArgs *args, bool preview, int limit){ Node *root_node = 0; int index = 0; gchar *name = g_path_get_basename(args->filename.c_str()); PaletteColorNameAssigner name_assigner(args->gs); if (!args->filename.empty()) root_node = process_image(args, args->filename.c_str(), root_node); ColorList *color_list; if (preview) color_list = args->preview_color_list; else color_list = args->gs->getColorList(); list tmp_list; if (root_node){ node_reduce(root_node, args->n_colors); node_leaf_callback(root_node, leaf_cb, &tmp_list); node_delete(root_node); } for (list::iterator i = tmp_list.begin(); i != tmp_list.end(); i++){ ColorObject *color_object = color_list_new_color_object(color_list, &(*i)); name_assigner.assign(color_object, &(*i), name, index); color_list_add_color_object(color_list, color_object, 1); color_object->release(); index++; } } static void update(GtkWidget *widget, PaletteFromImageArgs *args ){ color_list_remove_all(args->preview_color_list); get_settings(args); calc(args, true, 100); } static gchar* format_threshold_value_cb(GtkScale *scale, gdouble value){ return g_strdup_printf("%0.01f%%", value); } static void destroy_cb(GtkWidget* widget, PaletteFromImageArgs *args){ if (args->previous_node) node_delete(args->previous_node); color_list_destroy(args->preview_color_list); delete args; } static void response_cb(GtkWidget* widget, gint response_id, PaletteFromImageArgs *args){ get_settings(args); save_settings(args); gint width, height; gtk_window_get_size(GTK_WINDOW(widget), &width, &height); args->options->set("window.width", width); args->options->set("window.height", height); args->options->set("show_preview", gtk_expander_get_expanded(GTK_EXPANDER(args->preview_expander))); switch (response_id){ case GTK_RESPONSE_APPLY: calc(args, false, 0); break; case GTK_RESPONSE_DELETE_EVENT: break; case GTK_RESPONSE_CLOSE: gtk_widget_destroy(widget); break; } } void tools_palette_from_image_show(GtkWindow* parent, GlobalState* gs) { PaletteFromImageArgs *args = new PaletteFromImageArgs; args->previous_filename = ""; args->gs = gs; args->options = args->gs->settings().getOrCreateMap("gpick.tools.palette_from_image"); args->previous_node = 0; GtkWidget *table, *table_m, *widget; GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Palette from image"), parent, GtkDialogFlags(GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, GTK_STOCK_ADD, GTK_RESPONSE_APPLY, nullptr); gtk_window_set_default_size(GTK_WINDOW(dialog), args->options->getInt32("window.width", -1), args->options->getInt32("window.height", -1)); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_APPLY, GTK_RESPONSE_CLOSE, -1); GtkWidget *frame; gint table_y, table_m_y; table_m = gtk_table_new(3, 1, FALSE); table_m_y = 0; frame = gtk_frame_new(_("Image")); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); gtk_table_attach(GTK_TABLE(table_m), frame, 0, 1, table_m_y, table_m_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); table_m_y++; table = gtk_table_new(5, 3, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(frame), table); args->file_browser = widget = gtk_file_chooser_button_new(_("Image file"), GTK_FILE_CHOOSER_ACTION_OPEN); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(widget), args->options->getString("current_folder", "").c_str()); gtk_table_attach(GTK_TABLE(table), widget, 0, 3, table_y, table_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); g_signal_connect(G_OBJECT(args->file_browser), "file-set", G_CALLBACK(update), args); table_y++; auto selected_filter = args->options->getString("filter", "all_images"); GtkFileFilter *filter; GtkFileFilter *all_image_filter; filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("All files")); gtk_file_filter_add_pattern(filter, "*"); g_object_set_data_full(G_OBJECT(filter), "name", (void*)"all_files", GDestroyNotify(nullptr)); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(widget), filter); if ("all_files" == selected_filter) gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(widget), filter); all_image_filter = gtk_file_filter_new(); gtk_file_filter_set_name(all_image_filter, _("All images")); g_object_set_data_full(G_OBJECT(all_image_filter), "name", (void*)"all_images", GDestroyNotify(nullptr)); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(widget), all_image_filter); if ("all_images" == selected_filter) gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(widget), all_image_filter); stringstream ss; GSList *formats = gdk_pixbuf_get_formats(); GSList *i = formats; while (i){ GdkPixbufFormat *format = static_cast(g_slist_nth_data(i, 0)); filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, gdk_pixbuf_format_get_description(format)); gchar **extensions = gdk_pixbuf_format_get_extensions(format); if (extensions){ for (int j = 0; extensions[j]; j++){ ss.str(""); ss << "*." << extensions[j]; auto pattern = ss.str(); gtk_file_filter_add_pattern(filter, pattern.c_str()); gtk_file_filter_add_pattern(all_image_filter, pattern.c_str()); } g_strfreev(extensions); } g_object_set_data_full(G_OBJECT(filter), "name", gdk_pixbuf_format_get_name(format), GDestroyNotify(nullptr)); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(widget), filter); if (gdk_pixbuf_format_get_name(format) == selected_filter) gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(widget), filter); i = g_slist_next(i); } if (formats) g_slist_free(formats); frame = gtk_frame_new(_("Options")); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); gtk_table_attach(GTK_TABLE(table_m), frame, 0, 1, table_m_y, table_m_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); table_m_y++; table = gtk_table_new(5, 3, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(frame), table); gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Colors:"),0,0,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); args->range_colors = widget = gtk_spin_button_new_with_range (1, 100, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(args->range_colors), args->options->getInt32("colors", 3)); gtk_table_attach(GTK_TABLE(table), widget,1,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); g_signal_connect(G_OBJECT(args->range_colors), "value-changed", G_CALLBACK(update), args); table_y++; ColorList* preview_color_list = nullptr; gtk_table_attach(GTK_TABLE(table_m), args->preview_expander = palette_list_preview_new(gs, true, args->options->getBool("show_preview", true), gs->getColorList(), &preview_color_list), 0, 1, table_m_y, table_m_y+1 , GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL | GTK_EXPAND), 5, 5); table_m_y++; args->preview_color_list = preview_color_list; gtk_widget_show_all(table_m); setDialogContent(dialog, table_m); g_signal_connect(G_OBJECT(dialog), "destroy", G_CALLBACK(destroy_cb), args); g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(response_cb), args); gtk_widget_show(dialog); } gpick-gpick-0.2.6/source/tools/PaletteFromImage.h000066400000000000000000000034041377073231300217140ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_TOOLS_PALETTE_FROM_IMAGE_H_ #define GPICK_TOOLS_PALETTE_FROM_IMAGE_H_ #include struct GlobalState; void tools_palette_from_image_show(GtkWindow* parent, GlobalState* gs); #endif /* GPICK_TOOLS_PALETTE_FROM_IMAGE_H_ */ gpick-gpick-0.2.6/source/tools/TextParser.cpp000066400000000000000000000276601377073231300211750ustar00rootroot00000000000000/* * Copyright (c) 2009-2020, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "TextParser.h" #include "ColorList.h" #include "ColorObject.h" #include "GlobalState.h" #include "ToolColorNaming.h" #include "I18N.h" #include "dynv/Map.h" #include "uiListPalette.h" #include "uiUtilities.h" #include "parser/TextFile.h" #include using namespace std::string_literals; struct TextParserDialog: public ToolColorNameAssigner { TextParserDialog(GtkWindow *parent, GlobalState *gs); ~TextParserDialog(); bool show(); virtual std::string getToolSpecificName(ColorObject *colorObject, const Color *color) override; struct TextParser: public text_file_parser::TextFile { TextParser(const std::string &text): m_text(text), m_failed(false) { } virtual ~TextParser() { } virtual void outOfMemory() { m_failed = true; } virtual void syntaxError(size_t, size_t, size_t, size_t) { m_failed = true; } virtual size_t read(char *buffer, size_t length) { m_text.read(buffer, length); size_t bytes = m_text.gcount(); if (bytes > 0) return bytes; if (m_text.eof()) return 0; if (!m_text.good()) { m_failed = true; } return 0; } virtual void addColor(const Color &color) { m_colors.push_back(color); } bool failed() const { return m_failed; } const std::list &colors() const { return m_colors; } private: std::stringstream m_text; std::list m_colors; bool m_failed; }; private: GtkWindow *m_parent; GtkWidget *m_dialog, *m_textView; GtkWidget *m_single_line_c_comments, *m_multi_line_c_comments, *m_single_line_hash_comments, *m_css_rgb, *m_css_rgba, *m_short_hex, *m_full_hex, *m_float_values, *m_int_values; GtkWidget *m_preview_expander; ColorList *m_preview_color_list; GlobalState *m_gs; size_t m_index; dynv::Ref m_options; bool isSingleLineCCommentsEnabled(); bool isMultiLineCCommentsEnabled(); bool isSingleLineHashCommentsEnabled(); bool isCssRgbEnabled(); bool isCssRgbaEnabled(); bool isFullHexEnabled(); bool isShortHexEnabled(); bool isIntValuesEnabled(); bool isFloatValuesEnabled(); void saveSettings(); void preview(); void apply(); bool parse(ColorList *color_list); static void onDestroy(GtkWidget *widget, TextParserDialog *dialog); static void onResponse(GtkWidget *widget, gint response_id, TextParserDialog *dialog); static void onChange(GtkWidget *widget, TextParserDialog *dialog); }; TextParserDialog::TextParserDialog(GtkWindow *parent, GlobalState *gs): ToolColorNameAssigner(gs), m_parent(parent), m_gs(gs) { m_options = m_gs->settings().getOrCreateMap("gpick.tools.text_parser"); GtkWidget *dialog = m_dialog = gtk_dialog_new_with_buttons(_("Text parser"), m_parent, GtkDialogFlags(GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, GTK_STOCK_ADD, GTK_RESPONSE_APPLY, nullptr); gtk_window_set_default_size(GTK_WINDOW(dialog), m_options->getInt32("window.width", -1), m_options->getInt32("window.height", -1)); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_APPLY, GTK_RESPONSE_CLOSE, -1); GtkWidget *table = gtk_table_new(5, 9, false); GtkWidget *scrolled_window = gtk_scrolled_window_new(0, 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), m_textView = newTextView(m_options->getString("text", "").c_str())); g_signal_connect(G_OBJECT(gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_textView))), "changed", G_CALLBACK(onChange), this); GtkWidget *vbox = gtk_vbox_new(false, 0); gtk_box_pack_start(GTK_BOX(vbox), newLabel(_("Text") + ":"s), false, false, 0); gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, true, true, 0); gtk_table_attach(GTK_TABLE(table), vbox, 0, 8, 0, 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL | GTK_EXPAND), 5, 5); int y = 1; addOption(m_single_line_c_comments = newCheckbox(_("C style single-line comments") + " (//abc)"s, m_options->getBool("single_line_c_comments", true)), 0, y, table); addOption(m_multi_line_c_comments = newCheckbox(_("C style multi-line comments") + " (/*abc*/)"s, m_options->getBool("multi_line_c_comments", true)), 0, y, table); addOption(m_single_line_hash_comments = newCheckbox(_("Hash single-line comments") + " (#abc)"s, m_options->getBool("single_line_hash_comments", true)), 0, y, table); y = 1; addOption(m_css_rgb = newCheckbox("CSS rgb()", m_options->getBool("css_rgb", true)), 1, y, table); addOption(m_css_rgba = newCheckbox("CSS rgba()", m_options->getBool("css_rgba", true)), 1, y, table); addOption(m_full_hex = newCheckbox(_("Full hex"), m_options->getBool("full_hex", true)), 1, y, table); y = 1; addOption(m_short_hex = newCheckbox(_("Short hex"), m_options->getBool("short_hex", true)), 2, y, table); addOption(m_int_values = newCheckbox(_("Integer values"), m_options->getBool("int_values", true)), 2, y, table); addOption(m_float_values = newCheckbox(_("Real values"), m_options->getBool("float_values", true)), 2, y, table); g_signal_connect(G_OBJECT(m_single_line_c_comments), "toggled", G_CALLBACK(onChange), this); g_signal_connect(G_OBJECT(m_multi_line_c_comments), "toggled", G_CALLBACK(onChange), this); g_signal_connect(G_OBJECT(m_single_line_hash_comments), "toggled", G_CALLBACK(onChange), this); g_signal_connect(G_OBJECT(m_css_rgb), "toggled", G_CALLBACK(onChange), this); g_signal_connect(G_OBJECT(m_css_rgba), "toggled", G_CALLBACK(onChange), this); g_signal_connect(G_OBJECT(m_full_hex), "toggled", G_CALLBACK(onChange), this); g_signal_connect(G_OBJECT(m_short_hex), "toggled", G_CALLBACK(onChange), this); g_signal_connect(G_OBJECT(m_int_values), "toggled", G_CALLBACK(onChange), this); g_signal_connect(G_OBJECT(m_float_values), "toggled", G_CALLBACK(onChange), this); gtk_widget_show_all(table); gtk_table_attach(GTK_TABLE(table), m_preview_expander = palette_list_preview_new(m_gs, true, m_options->getBool("show_preview", true), m_gs->getColorList(), &m_preview_color_list), 0, 8, y, y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); preview(); gtk_widget_show_all(table); setDialogContent(dialog, table); g_signal_connect(G_OBJECT(dialog), "destroy", G_CALLBACK(onDestroy), this); g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(onResponse), this); } TextParserDialog::~TextParserDialog() { color_list_destroy(m_preview_color_list); } bool TextParserDialog::show() { gtk_widget_show(m_dialog); return true; } void TextParserDialog::onDestroy(GtkWidget *widget, TextParserDialog *dialog) { delete dialog; } bool TextParserDialog::parse(ColorList *color_list) { text_file_parser::Configuration configuration; configuration.single_line_c_comments = isSingleLineCCommentsEnabled(); configuration.multi_line_c_comments = isMultiLineCCommentsEnabled(); configuration.single_line_hash_comments = isSingleLineHashCommentsEnabled(); configuration.css_rgb = isCssRgbEnabled(); configuration.css_rgba = isCssRgbaEnabled(); configuration.full_hex = isFullHexEnabled(); configuration.short_hex = isShortHexEnabled(); configuration.int_values = isIntValuesEnabled(); configuration.float_values = isFloatValuesEnabled(); auto text = getTextViewText(m_textView); TextParser textParser(text); if (!textParser.parse(configuration)) { return false; } if (textParser.failed()) { return false; } if (textParser.colors().size() == 0) { return false; } m_index = 0; for (auto color: textParser.colors()) { auto colorObject = new ColorObject("", color); ToolColorNameAssigner::assign(colorObject, &color); color_list_add_color_object(color_list, colorObject, true); colorObject->release(); m_index++; } return true; } void TextParserDialog::onChange(GtkWidget *widget, TextParserDialog *dialog) { dialog->preview(); } void TextParserDialog::preview() { color_list_remove_all(m_preview_color_list); parse(m_preview_color_list); } void TextParserDialog::apply() { parse(m_gs->getColorList()); } std::string TextParserDialog::getToolSpecificName(ColorObject *colorObject, const Color *color) { return _("Parsed text color") + " #"s + std::to_string(m_index); } void TextParserDialog::onResponse(GtkWidget *widget, gint response_id, TextParserDialog *dialog) { dialog->saveSettings(); switch (response_id) { case GTK_RESPONSE_APPLY: dialog->apply(); break; case GTK_RESPONSE_DELETE_EVENT: break; case GTK_RESPONSE_CLOSE: gtk_widget_destroy(widget); break; } } void TextParserDialog::saveSettings() { auto text = getTextViewText(m_textView); m_options->set("text", text.c_str()); m_options->set("single_line_c_comments", isSingleLineCCommentsEnabled()); m_options->set("multi_line_c_comments", isMultiLineCCommentsEnabled()); m_options->set("single_line_hash_comments", isSingleLineHashCommentsEnabled()); m_options->set("css_rgb", isCssRgbEnabled()); m_options->set("css_rgba", isCssRgbaEnabled()); m_options->set("full_hex", isFullHexEnabled()); m_options->set("short_hex", isShortHexEnabled()); m_options->set("int_values", isIntValuesEnabled()); m_options->set("float_values", isFloatValuesEnabled()); gint width, height; gtk_window_get_size(GTK_WINDOW(m_dialog), &width, &height); m_options->set("window.width", width); m_options->set("window.height", height); m_options->set("show_preview", gtk_expander_get_expanded(GTK_EXPANDER(m_preview_expander))); } bool TextParserDialog::isSingleLineCCommentsEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_single_line_c_comments)); } bool TextParserDialog::isMultiLineCCommentsEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_multi_line_c_comments)); } bool TextParserDialog::isSingleLineHashCommentsEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_single_line_hash_comments)); } bool TextParserDialog::isCssRgbEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_css_rgb)); } bool TextParserDialog::isCssRgbaEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_css_rgba)); } bool TextParserDialog::isFullHexEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_full_hex)); } bool TextParserDialog::isShortHexEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_short_hex)); } bool TextParserDialog::isIntValuesEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_int_values)); } bool TextParserDialog::isFloatValuesEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_float_values)); } void tools_text_parser_show(GtkWindow *parent, GlobalState *gs) { auto *dialog = new TextParserDialog(parent, gs); dialog->show(); } gpick-gpick-0.2.6/source/tools/TextParser.h000066400000000000000000000033501377073231300206300ustar00rootroot00000000000000/* * Copyright (c) 2009-2019, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_TOOLS_TEXT_PARSER_H_ #define GPICK_TOOLS_TEXT_PARSER_H_ #include struct GlobalState; void tools_text_parser_show(GtkWindow* parent, GlobalState* gs); #endif /* GPICK_TOOLS_TEXT_PARSER_H_ */ gpick-gpick-0.2.6/source/transformation/000077500000000000000000000000001377073231300202635ustar00rootroot00000000000000gpick-gpick-0.2.6/source/transformation/Chain.cpp000066400000000000000000000051121377073231300220100ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Chain.h" namespace transformation { Chain::Chain(): m_enabled(true) { } void Chain::apply(const Color *input, Color *output) { if (!m_enabled) { color_copy(input, output); return; } Color tmp[2]; Color *tmp_p[3]; color_copy(input, &tmp[0]); tmp_p[0] = &tmp[0]; tmp_p[1] = &tmp[1]; for (auto &transformation: m_transformationChain) { transformation->apply(tmp_p[0], tmp_p[1]); tmp_p[2] = tmp_p[0]; tmp_p[0] = tmp_p[1]; tmp_p[1] = tmp_p[2]; } color_copy(tmp_p[0], output); } void Chain::add(std::unique_ptr transformation) { m_transformationChain.push_back(std::move(transformation)); } void Chain::remove(const Transformation *transformation) { for (auto i = m_transformationChain.begin(), end = m_transformationChain.end(); i != end; i++) { if (i->get() == transformation) { m_transformationChain.erase(i); return; } } } void Chain::clear() { m_transformationChain.clear(); } Chain::TransformationList &Chain::getAll() { return m_transformationChain; } void Chain::setEnabled(bool enabled) { m_enabled = enabled; } } gpick-gpick-0.2.6/source/transformation/Chain.h000066400000000000000000000056131377073231300214630ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TRANSFORMATION_CHAIN_H_ #define TRANSFORMATION_CHAIN_H_ #include "Transformation.h" #include #include /** \file source/transformation/Chain.h * \brief Struct for transformation object list handling. */ namespace transformation { /** \struct Chain * \brief Transformation object chain management struct. */ struct Chain { using TransformationList = std::list>; /** * Chain constructor. */ Chain(); /** * Apply transformation chain to color. * @param[in] input Source color in RGB color space. * @param[out] output Destination color in RGB color space. */ void apply(const Color *input, Color *output); /** * Add transformation object into the list. * @param[in] transformation Transformation object. */ void add(std::unique_ptr transformation); /** * Remove transformation object from the list. * @param[in] transformation Transformation object. */ void remove(const Transformation *transformation); /** * Clear transformation object list. */ void clear(); /** * Enable/disable transformation chain. * @param[in] enabled Enabled. */ void setEnabled(bool enabled); /** * Get the list of transformation objects. * @return Transformation object list. */ TransformationList &getAll(); private: TransformationList m_transformationChain; bool m_enabled; }; } #endif /* TRANSFORMATION_CHAIN_H_ */ gpick-gpick-0.2.6/source/transformation/ColorVisionDeficiency.cpp000066400000000000000000000421161377073231300252240ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "ColorVisionDeficiency.h" #include "dynv/Map.h" #include "MathUtil.h" #include "uiUtilities.h" #include "I18N.h" #include #include #include #include using namespace std; namespace transformation { static const char *transformationId = "color_vision_deficiency"; const char *ColorVisionDeficiency::getId() { return transformationId; } const char *ColorVisionDeficiency::getName() { return _("Color vision deficiency"); } const char* ColorVisionDeficiency::deficiency_type_string[] = { "protanomaly", "deuteranomaly", "tritanomaly", "protanopia", "deuteranopia", "tritanopia", }; const double protanomaly[11][9] = { {1.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,-0.000000,-0.000000,1.000000}, {0.856167,0.182038,-0.038205,0.029342,0.955115,0.015544,-0.002880,-0.001563,1.004443}, {0.734766,0.334872,-0.069637,0.051840,0.919198,0.028963,-0.004928,-0.004209,1.009137}, {0.630323,0.465641,-0.095964,0.069181,0.890046,0.040773,-0.006308,-0.007724,1.014032}, {0.539009,0.579343,-0.118352,0.082546,0.866121,0.051332,-0.007136,-0.011959,1.019095}, {0.458064,0.679578,-0.137642,0.092785,0.846313,0.060902,-0.007494,-0.016807,1.024301}, {0.385450,0.769005,-0.154455,0.100526,0.829802,0.069673,-0.007442,-0.022190,1.029632}, {0.319627,0.849633,-0.169261,0.106241,0.815969,0.077790,-0.007025,-0.028051,1.035076}, {0.259411,0.923008,-0.182420,0.110296,0.804340,0.085364,-0.006276,-0.034346,1.040622}, {0.203876,0.990338,-0.194214,0.112975,0.794542,0.092483,-0.005222,-0.041043,1.046265}, {0.152286,1.052583,-0.204868,0.114503,0.786281,0.099216,-0.003882,-0.048116,1.051998}, }; const double deuteranomaly[11][9] = { {1.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,-0.000000,-0.000000,1.000000}, {0.866435,0.177704,-0.044139,0.049567,0.939063,0.011370,-0.003453,0.007233,0.996220}, {0.760729,0.319078,-0.079807,0.090568,0.889315,0.020117,-0.006027,0.013325,0.992702}, {0.675425,0.433850,-0.109275,0.125303,0.847755,0.026942,-0.007950,0.018572,0.989378}, {0.605511,0.528560,-0.134071,0.155318,0.812366,0.032316,-0.009376,0.023176,0.986200}, {0.547494,0.607765,-0.155259,0.181692,0.781742,0.036566,-0.010410,0.027275,0.983136}, {0.498864,0.674741,-0.173604,0.205199,0.754872,0.039929,-0.011131,0.030969,0.980162}, {0.457771,0.731899,-0.189670,0.226409,0.731012,0.042579,-0.011595,0.034333,0.977261}, {0.422823,0.781057,-0.203881,0.245752,0.709602,0.044646,-0.011843,0.037423,0.974421}, {0.392952,0.823610,-0.216562,0.263559,0.690210,0.046232,-0.011910,0.040281,0.971630}, {0.367322,0.860646,-0.227968,0.280085,0.672501,0.047413,-0.011820,0.042940,0.968881}, }; const double tritanomaly[11][9] = { {1.000000,0.000000,-0.000000,0.000000,1.000000,0.000000,-0.000000,-0.000000,1.000000}, {0.926670,0.092514,-0.019184,0.021191,0.964503,0.014306,0.008437,0.054813,0.936750}, {0.895720,0.133330,-0.029050,0.029997,0.945400,0.024603,0.013027,0.104707,0.882266}, {0.905871,0.127791,-0.033662,0.026856,0.941251,0.031893,0.013410,0.148296,0.838294}, {0.948035,0.089490,-0.037526,0.014364,0.946792,0.038844,0.010853,0.193991,0.795156}, {1.017277,0.027029,-0.044306,-0.006113,0.958479,0.047634,0.006379,0.248708,0.744913}, {1.104996,-0.046633,-0.058363,-0.032137,0.971635,0.060503,0.001336,0.317922,0.680742}, {1.193214,-0.109812,-0.083402,-0.058496,0.979410,0.079086,-0.002346,0.403492,0.598854}, {1.257728,-0.139648,-0.118081,-0.078003,0.975409,0.102594,-0.003316,0.501214,0.502102}, {1.278864,-0.125333,-0.153531,-0.084748,0.957674,0.127074,-0.000989,0.601151,0.399838}, {1.255528,-0.076749,-0.178779,-0.078411,0.930809,0.147602,0.004733,0.691367,0.303900}, }; const double rgb_to_lms[3][3] = { {0.05059983, 0.08585369, 0.00952420}, {0.01893033, 0.08925308, 0.01370054}, {0.00292202, 0.00975732, 0.07145979}, }; const double lms_to_rgb[3][3] = { {30.830854, -29.832659, 1.610474}, {-6.481468, 17.715578, -2.532642}, {-0.375690, -1.199062, 14.273846}, }; const double anchor[] = { 0.080080, 0.157900, 0.589700, 0.128400, 0.223700, 0.363600, 0.985600, 0.732500, 0.001079, 0.091400, 0.007009, 0.000000, }; const double rgb_anchor[] = { rgb_to_lms[0][0] + rgb_to_lms[0][1] + rgb_to_lms[0][2], rgb_to_lms[1][0] + rgb_to_lms[1][1] + rgb_to_lms[1][2], rgb_to_lms[2][0] + rgb_to_lms[2][1] + rgb_to_lms[2][2], }; const vector3 protanopia_abc[2] = { {{{ static_cast(rgb_anchor[1] * anchor[8] - rgb_anchor[2] * anchor[7]), static_cast(rgb_anchor[2] * anchor[6] - rgb_anchor[0] * anchor[8]), static_cast(rgb_anchor[0] * anchor[7] - rgb_anchor[1] * anchor[6]), }}}, {{{ static_cast(rgb_anchor[1] * anchor[2] - rgb_anchor[2] * anchor[1]), static_cast(rgb_anchor[2] * anchor[0] - rgb_anchor[0] * anchor[2]), static_cast(rgb_anchor[0] * anchor[1] - rgb_anchor[1] * anchor[0]), }}}, }; const vector3 deuteranopia_abc[2] = { {{{ static_cast(rgb_anchor[1] * anchor[8] - rgb_anchor[2] * anchor[7]), static_cast(rgb_anchor[2] * anchor[6] - rgb_anchor[0] * anchor[8]), static_cast(rgb_anchor[0] * anchor[7] - rgb_anchor[1] * anchor[6]), }}}, {{{ static_cast(rgb_anchor[1] * anchor[2] - rgb_anchor[2] * anchor[1]), static_cast(rgb_anchor[2] * anchor[0] - rgb_anchor[0] * anchor[2]), static_cast(rgb_anchor[0] * anchor[1] - rgb_anchor[1] * anchor[0]), }}}, }; const vector3 tritanopia_abc[2] = { {{{ static_cast(rgb_anchor[1] * anchor[11] - rgb_anchor[2] * anchor[10]), static_cast(rgb_anchor[2] * anchor[9] - rgb_anchor[0] * anchor[11]), static_cast(rgb_anchor[0] * anchor[10] - rgb_anchor[1] * anchor[9]), }}}, {{{ static_cast(rgb_anchor[1] * anchor[5] - rgb_anchor[2] * anchor[4]), static_cast(rgb_anchor[2] * anchor[3] - rgb_anchor[0] * anchor[5]), static_cast(rgb_anchor[0] * anchor[4] - rgb_anchor[1] * anchor[3]), }}}, }; static void load_matrix(const double matrix_data[9], matrix3x3 *matrix) { matrix->m[0][0] = matrix_data[0]; matrix->m[1][0] = matrix_data[1]; matrix->m[2][0] = matrix_data[2]; matrix->m[0][1] = matrix_data[3]; matrix->m[1][1] = matrix_data[4]; matrix->m[2][1] = matrix_data[5]; matrix->m[0][2] = matrix_data[6]; matrix->m[1][2] = matrix_data[7]; matrix->m[2][2] = matrix_data[8]; } static void load_matrix(const double matrix_data[3][3], matrix3x3 *matrix) { matrix->m[0][0] = matrix_data[0][0]; matrix->m[1][0] = matrix_data[1][0]; matrix->m[2][0] = matrix_data[2][0]; matrix->m[0][1] = matrix_data[0][1]; matrix->m[1][1] = matrix_data[1][1]; matrix->m[2][1] = matrix_data[2][1]; matrix->m[0][2] = matrix_data[0][2]; matrix->m[1][2] = matrix_data[1][2]; matrix->m[2][2] = matrix_data[2][2]; } static void load_vector(const Color *color, vector3 *vector) { vector->x = color->rgb.red; vector->y = color->rgb.green; vector->z = color->rgb.blue; } void ColorVisionDeficiency::apply(Color *input, Color *output) { Color linear_input, linear_output; color_rgb_get_linear(input, &linear_input); vector3 vi, vo1, vo2; load_vector(&linear_input, &vi); matrix3x3 matrix1, matrix2; int index = floor(strength * 10); int index_secondary = std::min(index + 1, 10); float interpolation_factor = 1 - ((strength * 10) - index); vector3 lms; if ((type == PROTANOPIA) || (type == DEUTERANOPIA) || (type == TRITANOPIA)){ load_matrix(rgb_to_lms, &matrix1); load_matrix(lms_to_rgb, &matrix2); vector3_multiply_matrix3x3(&vi, &matrix1, &lms); } switch (type){ case PROTANOMALY: load_matrix(protanomaly[index], &matrix1); load_matrix(protanomaly[index_secondary], &matrix2); vector3_multiply_matrix3x3(&vi, &matrix1, &vo1); vector3_multiply_matrix3x3(&vi, &matrix2, &vo2); break; case DEUTERANOMALY: load_matrix(deuteranomaly[index], &matrix1); load_matrix(deuteranomaly[index_secondary], &matrix2); vector3_multiply_matrix3x3(&vi, &matrix1, &vo1); vector3_multiply_matrix3x3(&vi, &matrix2, &vo2); break; case TRITANOMALY: load_matrix(tritanomaly[index], &matrix1); load_matrix(tritanomaly[index_secondary], &matrix2); vector3_multiply_matrix3x3(&vi, &matrix1, &vo1); vector3_multiply_matrix3x3(&vi, &matrix2, &vo2); break; case PROTANOPIA: if (lms.z / lms.y < rgb_anchor[2] / rgb_anchor[1]){ lms.x = -(protanopia_abc[0].y * lms.y + protanopia_abc[0].z * lms.z) / protanopia_abc[0].x; }else{ lms.x = -(protanopia_abc[1].y * lms.y + protanopia_abc[1].z * lms.z) / protanopia_abc[1].x; } vector3_multiply_matrix3x3(&lms, &matrix2, &vo1); load_vector(&linear_input, &vo2); interpolation_factor = strength; break; case DEUTERANOPIA: if (lms.z / lms.x < rgb_anchor[2] / rgb_anchor[0]){ lms.y = -(deuteranopia_abc[0].x * lms.x + deuteranopia_abc[0].z * lms.z) / deuteranopia_abc[0].y; }else{ lms.y = -(deuteranopia_abc[1].x * lms.x + deuteranopia_abc[1].z * lms.z) / deuteranopia_abc[1].y; } vector3_multiply_matrix3x3(&lms, &matrix2, &vo1); load_vector(&linear_input, &vo2); interpolation_factor = strength; break; case TRITANOPIA: if (lms.y / lms.x < rgb_anchor[1] / rgb_anchor[0]){ lms.z = -(tritanopia_abc[0].x * lms.x + tritanopia_abc[0].y * lms.y) / tritanopia_abc[0].z; }else{ lms.z = -(tritanopia_abc[1].x * lms.x + tritanopia_abc[1].y * lms.y) / tritanopia_abc[1].z; } vector3_multiply_matrix3x3(&lms, &matrix2, &vo1); load_vector(&linear_input, &vo2); interpolation_factor = strength; break; default: color_copy(input, output); return; } linear_output.rgb.red = vo1.x * interpolation_factor + vo2.x * (1 - interpolation_factor); linear_output.rgb.green = vo1.y * interpolation_factor + vo2.y * (1 - interpolation_factor); linear_output.rgb.blue = vo1.z * interpolation_factor + vo2.z * (1 - interpolation_factor); color_linear_get_rgb(&linear_output, output); color_rgb_normalize(output); } ColorVisionDeficiency::ColorVisionDeficiency():Transformation(transformationId, getName()) { type = PROTANOMALY; strength = 0.5; } ColorVisionDeficiency::ColorVisionDeficiency(DeficiencyType type_, float strength_):Transformation(transformationId, getName()) { type = type_; strength = strength_; } ColorVisionDeficiency::~ColorVisionDeficiency() { } void ColorVisionDeficiency::serialize(dynv::Map &system) { system.set("strength", strength); system.set("type", deficiency_type_string[type]); Transformation::serialize(system); } ColorVisionDeficiency::DeficiencyType ColorVisionDeficiency::typeFromString(const std::string &type_string) { for (int i = 0; i < DEFICIENCY_TYPE_COUNT; i++){ if (type_string == deficiency_type_string[i]) { return (DeficiencyType)i; } } return PROTANOMALY; } void ColorVisionDeficiency::deserialize(const dynv::Map &system) { strength = system.getFloat("strength", 0.5f); type = typeFromString(system.getString("type", "protanomaly")); } static GtkWidget* create_type_list(void){ GtkListStore *store; GtkCellRenderer *renderer; GtkWidget *widget; store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT); widget = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); gtk_combo_box_set_add_tearoffs(GTK_COMBO_BOX(widget), 0); renderer = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(widget), renderer, 0); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(widget), renderer, "text", 0, nullptr); g_object_unref(GTK_TREE_MODEL(store)); GtkTreeIter iter1; struct { const char *name; int type; } types[] = { {_("Protanomaly"), ColorVisionDeficiency::PROTANOMALY}, {_("Deuteranomaly"), ColorVisionDeficiency::DEUTERANOMALY}, {_("Tritanomaly"), ColorVisionDeficiency::TRITANOMALY}, {_("Protanopia"), ColorVisionDeficiency::PROTANOPIA}, {_("Deuteranopia"), ColorVisionDeficiency::DEUTERANOPIA}, {_("Tritanopia"), ColorVisionDeficiency::TRITANOPIA}, }; for (int i = 0; i < ColorVisionDeficiency::DEFICIENCY_TYPE_COUNT; ++i){ gtk_list_store_append(store, &iter1); gtk_list_store_set(store, &iter1, 0, types[i].name, 1, types[i].type, -1); } return widget; } std::unique_ptr ColorVisionDeficiency::getConfiguration() { return std::move(std::make_unique(*this)); } ColorVisionDeficiency::Configuration::Configuration(ColorVisionDeficiency &transformation) { GtkWidget *table = gtk_table_new(2, 2, false); GtkWidget *widget; int table_y = 0; table_y = 0; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Type:"), 0, 0.5, 0, 0), 0, 1, table_y, table_y + 1, GTK_FILL, GTK_FILL, 5, 5); type = widget = create_type_list(); g_signal_connect(G_OBJECT(type), "changed", G_CALLBACK(type_combobox_change_cb), this); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 5, 0); table_y++; info_bar = widget = gtk_info_bar_new(); info_label = gtk_label_new(""); gtk_label_set_line_wrap(GTK_LABEL(info_label), true); gtk_label_set_justify(GTK_LABEL(info_label), GTK_JUSTIFY_LEFT); gtk_label_set_single_line_mode(GTK_LABEL(info_label), false); gtk_misc_set_alignment(GTK_MISC(info_label), 0, 0.5); gtk_widget_set_size_request(info_label, 1, -1); GtkWidget *content_area = gtk_info_bar_get_content_area(GTK_INFO_BAR(info_bar)); gtk_container_add(GTK_CONTAINER(content_area), info_label); gtk_widget_show_all(info_bar); g_signal_connect(G_OBJECT(info_label), "size-allocate", G_CALLBACK(info_label_size_allocate_cb), this); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 5, 0); table_y++; gtk_combo_box_set_active(GTK_COMBO_BOX(type), transformation.type); gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Strength:"), 0, 0.5, 0, 0), 0, 1, table_y, table_y + 1, GTK_FILL, GTK_FILL, 5, 5); strength = widget = gtk_hscale_new_with_range(0, 100, 1); gtk_range_set_value(GTK_RANGE(widget), transformation.strength * 100); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 5, 0); table_y++; main = table; gtk_widget_show_all(main); g_object_ref(main); } ColorVisionDeficiency::Configuration::~Configuration(){ g_object_unref(main); } GtkWidget* ColorVisionDeficiency::Configuration::getWidget(){ return main; } void ColorVisionDeficiency::Configuration::apply(dynv::Map &options) { options.set("strength", static_cast(gtk_range_get_value(GTK_RANGE(strength)) / 100.0f)); GtkTreeIter iter; if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(type), &iter)) { GtkTreeModel* model = gtk_combo_box_get_model(GTK_COMBO_BOX(type)); ColorVisionDeficiency::DeficiencyType type_id; gtk_tree_model_get(model, &iter, 1, &type_id, -1); options.set("type", ColorVisionDeficiency::deficiency_type_string[type_id]); } } void ColorVisionDeficiency::Configuration::type_combobox_change_cb(GtkWidget *widget, ColorVisionDeficiency::Configuration *this_) { const char *descriptions[] = { _("Altered spectral sensitivity of red receptors"), _("Altered spectral sensitivity of green receptors"), _("Altered spectral sensitivity of blue receptors"), _("Absence of red receptors"), _("Absence of green receptors"), _("Absence of blue receptors"), }; GtkTreeIter iter; if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(this_->type), &iter)) { GtkTreeModel* model = gtk_combo_box_get_model(GTK_COMBO_BOX(this_->type)); ColorVisionDeficiency::DeficiencyType type_id; gtk_tree_model_get(model, &iter, 1, &type_id, -1); gtk_label_set_text(GTK_LABEL(this_->info_label), descriptions[type_id]); }else{ gtk_label_set_text(GTK_LABEL(this_->info_label), ""); } gtk_info_bar_set_message_type(GTK_INFO_BAR(this_->info_bar), GTK_MESSAGE_INFO); } void ColorVisionDeficiency::Configuration::info_label_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, ColorVisionDeficiency::Configuration *this_) { gtk_widget_set_size_request(this_->info_label, allocation->width - 16, -1); } } gpick-gpick-0.2.6/source/transformation/ColorVisionDeficiency.h000066400000000000000000000061521377073231300246710ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TRANSFORMATION_COLOR_VISION_DEFICIENCY_H_ #define TRANSFORMATION_COLOR_VISION_DEFICIENCY_H_ #include "Transformation.h" #include namespace transformation { struct ColorVisionDeficiency; struct ColorVisionDeficiency: public Transformation { struct Configuration: public IConfiguration { Configuration(ColorVisionDeficiency &transformation); virtual ~Configuration() override; virtual GtkWidget *getWidget() override; virtual void apply(dynv::Map &options) override; private: GtkWidget *main; GtkWidget *info_bar; GtkWidget *info_label; GtkWidget *type; GtkWidget *strength; static void type_combobox_change_cb(GtkWidget *widget, Configuration *this_); static void info_label_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, Configuration *this_); }; enum DeficiencyType { PROTANOMALY, DEUTERANOMALY, TRITANOMALY, PROTANOPIA, DEUTERANOPIA, TRITANOPIA, DEFICIENCY_TYPE_COUNT, }; static const char *deficiency_type_string[]; static const char *getId(); static const char *getName(); ColorVisionDeficiency(); ColorVisionDeficiency(DeficiencyType type, float strength); virtual ~ColorVisionDeficiency() override; virtual void serialize(dynv::Map &system) override; virtual void deserialize(const dynv::Map &system) override; virtual std::unique_ptr getConfiguration() override; DeficiencyType typeFromString(const std::string &type_string); private: float strength; DeficiencyType type; virtual void apply(Color *input, Color *output); friend struct Configuration; }; } #endif /* TRANSFORMATION_COLOR_VISION_DEFICIENCY_H_ */ gpick-gpick-0.2.6/source/transformation/Configuration.cpp000066400000000000000000000031101377073231300235710ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Configuration.h" namespace transformation { } gpick-gpick-0.2.6/source/transformation/Configuration.h000066400000000000000000000033151377073231300232450ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_TRANSFORMATION_CONFIGURATION_H_ #define GPICK_TRANSFORMATION_CONFIGURATION_H_ #include "dynv/MapFwd.h" #include #endif /* GPICK_TRANSFORMATION_CONFIGURATION_H_ */ gpick-gpick-0.2.6/source/transformation/Factory.cpp000066400000000000000000000047421377073231300224050ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Factory.h" #include "ColorVisionDeficiency.h" #include "GammaModification.h" #include "Quantization.h" #include namespace transformation { std::unique_ptr Factory::create(const std::string &type) { if (type == ColorVisionDeficiency::getId()) return std::make_unique(); if (type == GammaModification::getId()) return std::make_unique(); if (type == Quantization::getId()) return std::make_unique(); return std::unique_ptr(); } std::vector Factory::getAllTypes() { std::vector result; result.emplace_back(ColorVisionDeficiency::getId(), ColorVisionDeficiency::getName()); result.emplace_back(GammaModification::getId(), GammaModification::getName()); result.emplace_back(Quantization::getId(), Quantization::getName()); return result; } Factory::TypeInfo::TypeInfo(const char *id, const char *name): id(id), name(name) { } } gpick-gpick-0.2.6/source/transformation/Factory.h000066400000000000000000000046431377073231300220520ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TRANSFORMATION_FACTORY_H_ #define TRANSFORMATION_FACTORY_H_ #include #include #include /** \file source/transformation/Factory.h * \brief Struct for transformation object creation. */ namespace transformation { struct Transformation; /** \struct Factory * \brief Transformation object creation management struct. */ struct Factory { struct TypeInfo { const char *id; const char *name; TypeInfo(const char *id, const char *name); }; /** * Create new transformation object. * @param[in] type Name of transformation object type. * @return New transformation object. */ static std::unique_ptr create(const std::string &type); /** * Get all transformation object types. * @return Vector of transformation object type information structures. */ static std::vector getAllTypes(); }; } #endif /* TRANSFORMATION_FACTORY_H_ */ gpick-gpick-0.2.6/source/transformation/GammaModification.cpp000066400000000000000000000076251377073231300243510ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "GammaModification.h" #include "dynv/Map.h" #include "../MathUtil.h" #include "../uiUtilities.h" #include "../I18N.h" #include #include #include namespace transformation { static const char *transformationId = "gamma_modification"; const char *GammaModification::getId() { return transformationId; } const char *GammaModification::getName() { return _("Gamma modification"); } void GammaModification::apply(Color *input, Color *output) { Color linear_input, linear_output; color_rgb_get_linear(input, &linear_input); linear_output.rgb.red = pow(linear_input.rgb.red, value); linear_output.rgb.green = pow(linear_input.rgb.green, value); linear_output.rgb.blue = pow(linear_input.rgb.blue, value); color_linear_get_rgb(&linear_output, output); color_rgb_normalize(output); } GammaModification::GammaModification(): Transformation(transformationId, getName()) { value = 1; } GammaModification::GammaModification(float value_): Transformation(transformationId, getName()) { value = value_; } GammaModification::~GammaModification() { } void GammaModification::serialize(dynv::Map &system) { system.set("value", value); Transformation::serialize(system); } void GammaModification::deserialize(const dynv::Map &system) { value = system.getFloat("value", 1); } std::unique_ptr GammaModification::getConfiguration() { return std::move(std::make_unique(*this)); } GammaModification::Configuration::Configuration(GammaModification &transformation) { GtkWidget *table = gtk_table_new(2, 2, false); GtkWidget *widget; int table_y = 0; table_y = 0; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Value:"), 0, 0.5, 0, 0), 0, 1, table_y, table_y + 1, GTK_FILL, GTK_FILL, 5, 5); value = widget = gtk_spin_button_new_with_range(0, 100, 0.01); gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), transformation.value); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 5, 0); table_y++; main = table; gtk_widget_show_all(main); g_object_ref(main); } GammaModification::Configuration::~Configuration() { g_object_unref(main); } GtkWidget *GammaModification::Configuration::getWidget() { return main; } void GammaModification::Configuration::apply(dynv::Map &system) { system.set("value", static_cast(gtk_spin_button_get_value(GTK_SPIN_BUTTON(value)))); } } gpick-gpick-0.2.6/source/transformation/GammaModification.h000066400000000000000000000050021377073231300240010ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TRANSFORMATION_GAMMA_MODIFICATION_H_ #define TRANSFORMATION_GAMMA_MODIFICATION_H_ #include "Transformation.h" namespace transformation { struct GammaModification; struct GammaModification: public Transformation { struct Configuration: public IConfiguration { Configuration(GammaModification &transformation); virtual ~Configuration() override; virtual GtkWidget *getWidget() override; virtual void apply(dynv::Map &options) override; private: GtkWidget *main; GtkWidget *value; }; static const char *getId(); static const char *getName(); GammaModification(); GammaModification(float value); virtual ~GammaModification() override; virtual void serialize(dynv::Map &system) override; virtual void deserialize(const dynv::Map &system) override; virtual std::unique_ptr getConfiguration() override; private: float value; virtual void apply(Color *input, Color *output) override; friend struct Configuration; }; } #endif /* TRANSFORMATION_GAMMA_MODIFICATION_H_ */ gpick-gpick-0.2.6/source/transformation/Invert.cpp000066400000000000000000000034771377073231300222510ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Invert.h" namespace transformation { void Invert::apply(Color *input, Color *output) { output->rgb.red = 1 - input->rgb.red; output->rgb.green= 1 - input->rgb.green; output->rgb.blue = 1 - input->rgb.blue; } Invert::Invert(): Transformation("invert", "Invert") { } Invert::~Invert() { } } gpick-gpick-0.2.6/source/transformation/Invert.h000066400000000000000000000034701377073231300217070ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TRANSFORMATION_INVERT_H_ #define TRANSFORMATION_INVERT_H_ #include "Transformation.h" namespace transformation { struct Invert: public Transformation { Invert(); virtual ~Invert(); protected: virtual void apply(Color *input, Color *output); }; } #endif /* TRANSFORMATION_INVERT_H_ */ gpick-gpick-0.2.6/source/transformation/Quantization.cpp000066400000000000000000000112561377073231300234620ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * Copyright (c) 2012, David Gowers (Portions regarding adaptation of GammaModification.(cpp|h) to quantise colors instead.) * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Quantization.h" #include "dynv/Map.h" #include "../MathUtil.h" #include "../uiUtilities.h" #include "../I18N.h" #include #include #include #include namespace transformation { static const char *transformationId = "quantization"; const char *Quantization::getId() { return transformationId; } const char *Quantization::getName() { return _("Quantization"); } void Quantization::apply(Color *input, Color *output) { if (clip_top) { float max_intensity = (value - 1) / value; output->rgb.red = MIN(max_intensity, boost::math::round(input->rgb.red * value) / value); output->rgb.green = MIN(max_intensity, boost::math::round(input->rgb.green * value) / value); output->rgb.blue = MIN(max_intensity, boost::math::round(input->rgb.blue * value) / value); } else { float actualmax = value - 1; output->rgb.red = boost::math::round(input->rgb.red * actualmax) / actualmax; output->rgb.green = boost::math::round(input->rgb.green * actualmax) / actualmax; output->rgb.blue = boost::math::round(input->rgb.blue * actualmax) / actualmax; } } Quantization::Quantization(): Transformation(transformationId, getName()) { value = 16; } Quantization::Quantization(float value_): Transformation(transformationId, getName()) { value = value_; } Quantization::~Quantization() { } void Quantization::serialize(dynv::Map &system) { system.set("value", value); system.set("clip-top", clip_top); Transformation::serialize(system); } void Quantization::deserialize(const dynv::Map &system) { value = system.getFloat("value", 16); clip_top = system.getBool("clip-top", false); } std::unique_ptr Quantization::getConfiguration() { return std::move(std::make_unique(*this)); } Quantization::Configuration::Configuration(Quantization &transformation) { GtkWidget *table = gtk_table_new(2, 3, false); GtkWidget *widget; int table_y = 0; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Value:"), 0, 0.5, 0, 0), 0, 1, table_y, table_y + 1, GTK_FILL, GTK_FILL, 5, 5); value = widget = gtk_spin_button_new_with_range(2, 256, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), transformation.value); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 5, 0); table_y++; clip_top = widget = gtk_check_button_new_with_label(_("Clip top-end")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), transformation.clip_top); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 5, 0); main = table; gtk_widget_show_all(main); g_object_ref(main); } Quantization::Configuration::~Configuration() { g_object_unref(main); } GtkWidget *Quantization::Configuration::getWidget() { return main; } void Quantization::Configuration::apply(dynv::Map &system) { system.set("value", gtk_spin_button_get_value(GTK_SPIN_BUTTON(value))); system.set("clip-top", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(clip_top))); } } gpick-gpick-0.2.6/source/transformation/Quantization.h000066400000000000000000000047771377073231300231410ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TRANSFORMATION_QUANTIZATION_H_ #define TRANSFORMATION_QUANTIZATION_H_ #include "Transformation.h" namespace transformation { struct Quantization; struct Quantization: public Transformation { struct Configuration: public IConfiguration { Configuration(Quantization &transformation); virtual ~Configuration() override; virtual GtkWidget *getWidget() override; virtual void apply(dynv::Map &options) override; private: GtkWidget *main; GtkWidget *value; GtkWidget *clip_top; }; static const char *getId(); static const char *getName(); Quantization(); Quantization(float value); virtual ~Quantization() override; virtual void serialize(dynv::Map &system) override; virtual void deserialize(const dynv::Map &system) override; virtual std::unique_ptr getConfiguration() override; private: float value; bool clip_top; virtual void apply(Color *input, Color *output) override; friend struct Configuration; }; } #endif /* TRANSFORMATION_GAMMA_MODIFICATION_H_ */ gpick-gpick-0.2.6/source/transformation/Transformation.cpp000066400000000000000000000043601377073231300240000ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Transformation.h" #include "dynv/Map.h" namespace transformation { Transformation::Transformation(const char *name_, const char *readable_name_) { name = name_; readable_name = readable_name_; } Transformation::~Transformation() { } void Transformation::apply(Color *input, Color *output) { color_copy(input, output); } std::string Transformation::getName() const { return name; } std::string Transformation::getReadableName() const { return readable_name; } void Transformation::serialize(dynv::Map &options) { options.set("name", name); } void Transformation::deserialize(const dynv::Map &options) { } std::unique_ptr Transformation::getConfiguration() { return std::unique_ptr(); } } gpick-gpick-0.2.6/source/transformation/Transformation.h000066400000000000000000000071631377073231300234510ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TRANSFORMATION_H_ #define TRANSFORMATION_H_ #include "Color.h" #include "dynv/MapFwd.h" #include #include typedef struct _GtkWidget GtkWidget; /** \file source/transformation/Transformation.h * \brief Color transformation struct. */ namespace transformation { /** \struct IConfiguration * \brief Transformation object configuration management interface. */ struct IConfiguration { virtual ~IConfiguration() = default; virtual GtkWidget* getWidget() = 0; virtual void apply(dynv::Map &options) = 0; }; /** \struct Transformation * \brief Transformation object structure. */ struct Transformation { protected: std::string name; /**< System name */ std::string readable_name; /**< Human readable name */ /** * Apply transformation to color. * @param[in] input Source color in RGB color space. * @param[out] output Destination color in RGB color space. */ virtual void apply(Color *input, Color *output); public: /** * Transformation object constructor. * @param[in] name Transformation object system name. * @param[in] readable_name Transformation object human readable name. */ Transformation(const char *name, const char *readable_name); /** * Transformation object destructor. */ virtual ~Transformation(); /** * Serialize settings into configuration system. * @param[in,out] dynv Configuration system. */ virtual void serialize(dynv::Map &options); /** * Deserialize settings from configuration system. * @param[in] dynv Configuration system. */ virtual void deserialize(const dynv::Map &options); /** * Get configuration for transformation object. * @return Configuration for transformation object. */ virtual std::unique_ptr getConfiguration(); /** * Get transformation object system name. * @return Transformation object system name. */ std::string getName() const; /** * Get transformation object human readable name. * @return Transformation object human readable name. */ std::string getReadableName() const; friend struct Chain; }; } #endif /* TRANSFORMATION_H_ */ gpick-gpick-0.2.6/source/uiAbout.cpp000066400000000000000000000225371377073231300173420ustar00rootroot00000000000000/* * Copyright (c) 2009-2018, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "uiAbout.h" #include "uiUtilities.h" #include "version/Version.h" #include "I18N.h" #include "Paths.h" const gchar* program_name = "Gpick"; static GtkWidget* new_page(const char *text) { GtkWidget *text_view = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text_view), GTK_WRAP_WORD); GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view)); gtk_text_buffer_set_text(buffer, text, -1); gtk_text_view_set_editable(GTK_TEXT_VIEW(text_view), false); GtkWidget *scrolled = gtk_scrolled_window_new(0, 0); gtk_container_add(GTK_CONTAINER(scrolled), text_view); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); return scrolled; } void show_about_box(GtkWidget *widget) { const char *license = { "Copyright \xc2\xa9 2009-2018, Albertas Vyšniauskas\n" "\n" "All rights reserved.\n" "\n" "Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n" "\n" " * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n" " * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n" " * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n" "\n" "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" }; const char *expat_license = { "Copyright \xc2\xa9 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper\n" "Copyright \xc2\xa9 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers.\n" "\n" "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:\n" "\n" "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n" "\n" "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.\n" }; const char *lua_license = { "Copyright \xc2\xa9 1994-2017 Lua.org, PUC-Rio.\n" "\n" "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:\n" "\n" "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n" "\n" "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.\n" }; const char *program_authors = { "Albertas Vyšniauskas \n" /* Add yourself here if you helped Gpick project in any way (patch, translation, etc). * Everything is optional, if you do not want, you do not have to disclose your e-mail * address, real name or any other information. * Please keep this list sorted alphabetically. */ }; GtkWidget* dialog = gtk_dialog_new_with_buttons(_("About Gpick"), GTK_WINDOW(gtk_widget_get_toplevel(widget)), GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL, nullptr); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL); GtkWidget *vbox = gtk_vbox_new(false, 5); GtkWidget *align_box = gtk_hbox_new(false, 5); gtk_box_pack_start(GTK_BOX(vbox), align_box, false, false, 0); gtk_box_pack_start(GTK_BOX(align_box), gtk_vbox_new(false, 0), true, true, 0); gtk_box_pack_end(GTK_BOX(align_box), gtk_vbox_new(false, 0), true, true, 0); GtkWidget *hbox = gtk_hbox_new(false, 5); gtk_box_pack_start(GTK_BOX(align_box), hbox, false, false, 0); auto logoFilename = buildFilename("logo.png"); GtkWidget *image = gtk_image_new_from_file(logoFilename.c_str()); gtk_box_pack_start(GTK_BOX(hbox), image, false, false, 0); GtkWidget *vbox2 = gtk_vbox_new(false, 0); gtk_box_pack_start(GTK_BOX(hbox), vbox2, false, false, 0); gchar *tmp_string = g_markup_printf_escaped("%s %s\n%s: %s", program_name, gpick_build_version, _("Revision"), gpick_build_revision); GtkWidget *name = gtk_label_new(0); gtk_label_set_selectable(GTK_LABEL(name), true); gtk_label_set_justify(GTK_LABEL(name), GTK_JUSTIFY_CENTER); gtk_label_set_markup(GTK_LABEL(name), tmp_string); gtk_box_pack_start(GTK_BOX(vbox2), name, false, false, 0); g_free(tmp_string); tmp_string = g_markup_printf_escaped ("%s", _("Copyright © 2009-2018, Albertas Vyšniauskas and Gpick development team")); GtkWidget *copyright = gtk_label_new(0); gtk_label_set_selectable(GTK_LABEL(copyright), true); gtk_label_set_justify(GTK_LABEL(copyright), GTK_JUSTIFY_CENTER); gtk_label_set_line_wrap(GTK_LABEL(copyright), true); gtk_label_set_markup(GTK_LABEL(copyright), tmp_string); gtk_box_pack_start(GTK_BOX(vbox2), copyright, false, false, 0); g_free(tmp_string); GtkWidget *website = gtk_link_button_new("http://www.gpick.org/"); gtk_box_pack_start(GTK_BOX(vbox2), website, false, false, 0); GtkWidget *notebook = gtk_notebook_new(); gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), true); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), new_page(license), gtk_label_new(_("License"))); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), new_page(program_authors), gtk_label_new(_("Credits"))); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), new_page(expat_license), gtk_label_new(_("Expat License"))); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), new_page(lua_license), gtk_label_new(_("Lua License"))); gtk_box_pack_start(GTK_BOX(vbox), notebook, true, true, 0); setDialogContent(dialog, vbox); gtk_window_set_default_size(GTK_WINDOW(dialog), 400, 300); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return; } gpick-gpick-0.2.6/source/uiAbout.h000066400000000000000000000033311377073231300167760ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_UI_DIALOG_ABOUT_H_ #define GPICK_UI_DIALOG_ABOUT_H_ #include void show_about_box(GtkWidget *widget); extern const gchar* program_name; #endif /* GPICK_UI_DIALOG_ABOUT_H_ */ gpick-gpick-0.2.6/source/uiApp.cpp000066400000000000000000002341711377073231300170070ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "uiApp.h" #include "ColorObject.h" #include "ColorList.h" #include "GlobalState.h" #include "ColorSourceManager.h" #include "ColorSource.h" #include "Paths.h" #include "Converter.h" #include "Converters.h" #include "StandardMenu.h" #include "RegisterSources.h" #include "GenerateScheme.h" #include "ColorPicker.h" #include "LayoutPreview.h" #include "ImportExport.h" #include "uiAbout.h" #include "uiListPalette.h" #include "uiUtilities.h" #include "uiImportExport.h" #include "uiDialogMix.h" #include "uiDialogVariations.h" #include "uiDialogGenerate.h" #include "uiDialogAutonumber.h" #include "uiDialogSort.h" #include "uiColorDictionaries.h" #include "uiTransformations.h" #include "uiDialogOptions.h" #include "uiConverter.h" #include "uiStatusIcon.h" #include "uiColorInput.h" #include "tools/PaletteFromImage.h" #include "tools/ColorSpaceSampler.h" #include "tools/TextParser.h" #include "dbus/Control.h" #include "dynv/Map.h" #include "FileFormat.h" #include "MathUtil.h" #include "Clipboard.h" #include "I18N.h" #include "color_names/ColorNames.h" #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; struct AppArgs { GtkWidget *window; map color_source; vector color_source_index; list recent_files; ColorSourceManager *csm; ColorSource *current_color_source; ColorSource *secondary_color_source; GtkWidget *secondary_source_widget; GtkWidget *secondary_source_scrolled_viewpoint; GtkWidget *secondary_source_container; GtkWidget *color_list; GtkWidget *notebook; GtkWidget *statusbar; GtkWidget *hpaned; GtkWidget *vpaned; GtkWidget *palette; uiStatusIcon* status_icon; FloatingPicker floating_picker; StartupOptions startupOptions; dynv::Ref options; GlobalState *gs; string current_filename; bool current_filename_set; bool imported; GtkWidget *precision_loss_icon; gint x, y; gint width, height; bool initialization; dbus::Control dbus_control; }; static void app_release(AppArgs *args); static void update_recent_file_list(AppArgs *args, const char *filename, bool move_up) { list::iterator i = std::find(args->recent_files.begin(), args->recent_files.end(), string(filename)); if (i == args->recent_files.end()){ args->recent_files.push_front(string(filename)); while (args->recent_files.size() > 10){ args->recent_files.pop_back(); } }else{ if (move_up){ args->recent_files.erase(i); args->recent_files.push_front(string(filename)); } } } static gboolean delete_event(GtkWidget *widget, GdkEvent *event, AppArgs *args) { if (args->options->getBool("close_to_tray", false)){ gtk_widget_hide(args->window); status_icon_set_visible(args->status_icon, true); return true; } return false; } static void detectLatinKeyGroup(GdkKeymap *, AppArgs *args) { GdkKeymapKey *keys; gint keyCount; args->gs->latinKeysGroup.reset(); if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_for_display(gdk_display_get_default()), GDK_KEY_a, &keys, &keyCount)) { if (keyCount > 0) { for (size_t i = 0; i < static_cast(keyCount); i++) { if (!args->gs->latinKeysGroup) args->gs->latinKeysGroup = keys[i].group; else if (keys[i].group >= 0 && static_cast(keys[i].group) < *args->gs->latinKeysGroup) args->gs->latinKeysGroup = keys[i].group; } } g_free(keys); } } static gboolean on_window_state_event(GtkWidget *widget, GdkEventWindowState *event, AppArgs *args) { if (event->new_window_state == GDK_WINDOW_STATE_ICONIFIED || event->new_window_state == GDK_WINDOW_STATE_WITHDRAWN){ if (args->secondary_color_source) color_source_deactivate(args->secondary_color_source); if (args->current_color_source) color_source_deactivate(args->current_color_source); }else{ if (args->secondary_color_source) color_source_activate(args->secondary_color_source); if (args->current_color_source) color_source_activate(args->current_color_source); } if (args->options->getBool("minimize_to_tray", false)){ if (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED){ if (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED){ gtk_widget_hide(args->window); gtk_window_deiconify(GTK_WINDOW(args->window)); status_icon_set_visible(args->status_icon, true); return true; } } } return false; } static gboolean on_window_key_press(GtkWidget *widget, GdkEventKey *event, AppArgs *args) { guint modifiers = gtk_accelerator_get_default_mod_mask(); if (event->keyval == GDK_KEY_space && (event->state & modifiers) == GDK_CONTROL_MASK) { if (args->current_color_source != nullptr && is_color_picker(args->current_color_source)) { color_picker_focus_swatch(args->current_color_source); color_picker_pick(args->current_color_source); return true; } } return false; } static gboolean on_window_configure(GtkWidget *widget, GdkEventConfigure *event, AppArgs *args) { if (gtk_widget_get_visible(widget)){ if (gdk_window_get_state(gtk_widget_get_window(widget)) & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN | GDK_WINDOW_STATE_ICONIFIED)) { return false; } gint x, y; gtk_window_get_position(GTK_WINDOW(widget), &x, &y); args->x = x; args->y = y; args->width = event->width; args->height = event->height; args->options->set("window.x", args->x); args->options->set("window.y", args->y); args->options->set("window.width", args->width); args->options->set("window.height", args->height); } return false; } static gboolean setFocusToColorPicker(ColorSource *colorSource) { color_picker_focus_swatch(colorSource); return false; } static void notebook_switch_cb(GtkNotebook *notebook, GtkWidget *page, guint page_num, AppArgs *args) { if (args->current_color_source) color_source_deactivate(args->current_color_source); args->current_color_source = nullptr; if (page_num >= 0 && page_num <= args->color_source_index.size() && args->color_source_index[page_num]){ if (!args->initialization) { // do not initialize color sources while initializing program color_source_activate(args->color_source_index[page_num]); if (is_color_picker(args->color_source_index[page_num])) { g_idle_add((GSourceFunc)setFocusToColorPicker, args->color_source_index[page_num]); } } args->current_color_source = args->color_source_index[page_num]; args->gs->setCurrentColorSource(args->current_color_source); }else{ args->gs->setCurrentColorSource(nullptr); } } static void destroy_cb(GtkWidget *widget, AppArgs *args) { g_signal_handlers_disconnect_matched(G_OBJECT(args->notebook), G_SIGNAL_MATCH_FUNC, 0, 0, nullptr, (void*)notebook_switch_cb, 0); //disconnect notebook switch callback, because destroying child widgets triggers it args->options->set("color_source", args->color_source_index[gtk_notebook_get_current_page(GTK_NOTEBOOK(args->notebook))]->identificator); args->options->set("paned_position", gtk_paned_get_position(GTK_PANED(args->hpaned))); args->options->set("vertical_paned_position", gtk_paned_get_position(GTK_PANED(args->vpaned))); if (args->secondary_color_source){ args->options->set("secondary_color_source", args->secondary_color_source->identificator); }else{ args->options->set("secondary_color_source", ""); } args->options->set("window.x", args->x); args->options->set("window.y", args->y); args->options->set("window.width", args->width); args->options->set("window.height", args->height); app_release(args); gtk_main_quit(); } static void app_update_program_name(AppArgs *args) { stringstream program_title; if (!args->current_filename_set){ program_title << _("New palette"); if (args->precision_loss_icon) gtk_widget_hide(args->precision_loss_icon); }else{ gchar* filename = g_path_get_basename(args->current_filename.c_str()); if (args->imported){ program_title << filename << " " << _("(Imported)"); if (args->precision_loss_icon) gtk_widget_show(args->precision_loss_icon); }else{ program_title << filename; if (args->precision_loss_icon) gtk_widget_hide(args->precision_loss_icon); } g_free(filename); } program_title << " - " << program_name; string title = program_title.str(); gtk_window_set_title(GTK_WINDOW(args->window), title.c_str()); } static void show_dialog_converter(GtkWidget *widget, AppArgs *args) { dialog_converter_show(GTK_WINDOW(args->window), args->gs); return; } static void show_dialog_transformations(GtkWidget *widget, AppArgs *args) { dialog_transformations_show(GTK_WINDOW(args->window), args->gs); return; } static void show_dialog_options(GtkWidget *widget, AppArgs *args) { dialog_options_show(GTK_WINDOW(args->window), args->gs); return; } static void show_dialog_color_dictionaries(GtkWidget *widget, AppArgs *args) { dialog_color_dictionaries_show(GTK_WINDOW(args->window), args->gs); return; } static void menu_file_new(GtkWidget *widget, AppArgs *args) { args->current_filename_set = false; color_list_remove_all(args->gs->getColorList()); app_update_program_name(args); } int app_save_file(AppArgs *args, const char *filename, const char *filter) { using namespace boost::filesystem; string current_filename; if (filename != nullptr){ current_filename = filename; }else{ if (!args->current_filename_set) return -1; current_filename = args->current_filename; } FileType filetype; ImportExport import_export(args->gs->getColorList(), current_filename.c_str(), args->gs); import_export.fixFileExtension(filter); current_filename = import_export.getFilename(); bool return_value = false; switch (filetype = ImportExport::getFileType(current_filename.c_str())){ case FileType::gpl: return_value = import_export.exportGPL(); break; case FileType::ase: return_value = import_export.exportASE(); break; case FileType::gpa: return_value = import_export.exportGPA(); break; default: return_value = import_export.exportGPA(); } if (return_value){ if (filetype == FileType::gpa || filetype == FileType::unknown){ args->imported = false; }else{ args->imported = true; } args->current_filename = current_filename; args->current_filename_set = true; app_update_program_name(args); update_recent_file_list(args, current_filename.c_str(), true); return 0; }else{ app_update_program_name(args); return -1; } return 0; } int app_load_file(AppArgs *args, const std::string &filename, ColorList *color_list, bool autoload) { bool imported = false; bool return_value = false; ImportExport import_export(color_list, filename.c_str(), args->gs); switch (ImportExport::getFileType(filename.c_str())){ case FileType::gpl: return_value = import_export.importGPL(); imported = true; break; case FileType::ase: return_value = import_export.importASE(); imported = true; break; case FileType::gpa: return_value = import_export.importGPA(); break; default: return_value = import_export.importGPA(); } args->current_filename_set = false; if (return_value){ if (imported){ args->imported = true; }else{ args->imported = false; } if (!autoload){ args->current_filename = filename; args->current_filename_set = true; update_recent_file_list(args, filename.c_str(), false); } app_update_program_name(args); }else{ app_update_program_name(args); return -1; } return 0; } int app_load_file(AppArgs *args, const std::string &filename, bool autoload) { int r = 0; ColorList *color_list = color_list_new(args->gs->getColorList()); if ((r = app_load_file(args, filename, color_list, autoload)) == 0){ color_list_remove_all(args->gs->getColorList()); color_list_add(args->gs->getColorList(), color_list, true); } color_list_destroy(color_list); return r; } int app_parse_geometry(AppArgs *args, const char *geometry) { gtk_window_parse_geometry(GTK_WINDOW(args->window), geometry); return 0; } static void menu_file_revert(GtkWidget *widget, AppArgs *args) { if (!args->current_filename_set) return; if (app_load_file(args, args->current_filename.c_str()) == 0){ }else{ GtkWidget* message; message = gtk_message_dialog_new(GTK_WINDOW(args->window), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("File could not be opened")); gtk_window_set_title(GTK_WINDOW(message), _("Open")); gtk_dialog_run(GTK_DIALOG(message)); gtk_widget_destroy(message); } } static void menu_file_open_last(GtkWidget *widget, AppArgs *args) { const char *filename = args->recent_files.begin()->c_str(); if (app_load_file(args, filename) == 0){ }else{ GtkWidget* message; message = gtk_message_dialog_new(GTK_WINDOW(args->window), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("File could not be opened")); gtk_window_set_title(GTK_WINDOW(message), _("Open")); gtk_dialog_run(GTK_DIALOG(message)); gtk_widget_destroy(message); } } static void menu_file_open_nth(GtkWidget *widget, AppArgs *args) { list::iterator i = args->recent_files.begin(); uintptr_t index = (uintptr_t)g_object_get_data(G_OBJECT(widget), "index"); std::advance(i, index); const char *filename = (*i).c_str(); if (app_load_file(args, filename) == 0){ }else{ GtkWidget* message; message = gtk_message_dialog_new(GTK_WINDOW(args->window), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("File could not be opened")); gtk_window_set_title(GTK_WINDOW(message), _("Open")); gtk_dialog_run(GTK_DIALOG(message)); gtk_widget_destroy(message); } } static void add_file_filters(GtkWidget *dialog, const char *selected_filter) { const struct{ FileType type; const char *label; const char *filter; }filters[] = { {FileType::gpa, _("Gpick Palette (*.gpa)"), "*.gpa"}, {FileType::gpl, _("GIMP/Inkscape Palette (*.gpl)"), "*.gpl"}, {FileType::ase, _("Adobe Swatch Exchange (*.ase)"), "*.ase"}, {FileType::unknown, 0, 0}, }; GtkFileFilter *filter; filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("All files")); gtk_file_filter_add_pattern(filter, "*"); g_object_set_data(G_OBJECT(filter), "identification", (gpointer)"all"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); if (g_strcmp0(selected_filter, "all") == 0){ gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); } filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("All supported formats")); for (gint i = 0; filters[i].type != FileType::unknown; ++i) { gtk_file_filter_add_pattern(filter, filters[i].filter); } if (g_strcmp0(selected_filter, "all_supported") == 0){ gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); } g_object_set_data(G_OBJECT(filter), "identification", (gpointer)"all_supported"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); for (gint i = 0; filters[i].type != FileType::unknown; ++i) { filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, filters[i].label); gtk_file_filter_add_pattern(filter, filters[i].filter); g_object_set_data(G_OBJECT(filter), "identification", (gpointer)filters[i].filter); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); if (g_strcmp0(filters[i].filter, selected_filter) == 0){ gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); } } } static void menu_file_open(GtkWidget *widget, AppArgs *args) { GtkWidget *dialog; dialog = gtk_file_chooser_dialog_new(_("Open File"), GTK_WINDOW(gtk_widget_get_toplevel(widget)), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, nullptr); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); auto default_path = args->options->getString("open.path", ""); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), default_path.c_str()); auto selected_filter = args->options->getString("open.filter", "all_supported"); add_file_filters(dialog, selected_filter.c_str()); gboolean finished = FALSE; while (!finished){ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { gchar *filename; filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gchar *path; path = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog)); args->options->set("open.path", path); g_free(path); const char *identification = (const char*)g_object_get_data(G_OBJECT(gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog))), "identification"); args->options->set("open.filter", identification); if (app_load_file(args, filename) == 0){ finished = TRUE; }else{ GtkWidget* message; message = gtk_message_dialog_new(GTK_WINDOW(dialog), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("File could not be opened")); gtk_window_set_title(GTK_WINDOW(dialog), _("Open")); gtk_dialog_run(GTK_DIALOG(message)); gtk_widget_destroy(message); } g_free(filename); }else break; } gtk_widget_destroy (dialog); } static void menu_file_save_as(GtkWidget *widget, AppArgs *args) { GtkWidget *dialog; dialog = gtk_file_chooser_dialog_new(_("Save As"), GTK_WINDOW(gtk_widget_get_toplevel(widget)), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, nullptr); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE); auto default_path = args->options->getString("save.path", ""); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), default_path.c_str()); auto selected_filter = args->options->getString("save.filter", "all_supported"); add_file_filters(dialog, selected_filter.c_str()); gboolean finished = FALSE; while (!finished){ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { gchar *filename; filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gchar *path; path = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog)); args->options->set("save.path", path); g_free(path); const char *identification = (const char*)g_object_get_data(G_OBJECT(gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog))), "identification"); args->options->set("save.filter", identification); if (app_save_file(args, filename, identification) == 0){ finished = TRUE; }else{ GtkWidget* message; message = gtk_message_dialog_new(GTK_WINDOW(dialog), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("File could not be saved")); gtk_window_set_title(GTK_WINDOW(message), _("Save As")); gtk_dialog_run(GTK_DIALOG(message)); gtk_widget_destroy(message); } g_free(filename); }else break; } gtk_widget_destroy (dialog); } static void menu_file_save(GtkWidget *widget, AppArgs *args) { if (!args->current_filename_set){ menu_file_save_as(widget, args); // if file has no name, "Save As" dialog is shown instead. }else{ if (app_save_file(args, nullptr, nullptr) == 0){ }else{ GtkWidget* message; message = gtk_message_dialog_new(GTK_WINDOW(args->window), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("File could not be saved")); gtk_window_set_title(GTK_WINDOW(message), _("Save")); gtk_dialog_run(GTK_DIALOG(message)); gtk_widget_destroy(message); } } } static PaletteListCallbackReturn color_list_selected(ColorObject* color_object, void *userdata) { color_list_add_color_object((ColorList *)userdata, color_object, 1); return PALETTE_LIST_CALLBACK_NO_UPDATE; } static void menu_file_export_all(GtkWidget *widget, AppArgs *args) { ImportExportDialog import_export_dialog(GTK_WINDOW(args->window), args->gs->getColorList(), args->gs); import_export_dialog.showExport(); } static void menu_file_import(GtkWidget *widget, AppArgs *args) { ImportExportDialog import_export_dialog(GTK_WINDOW(args->window), args->gs->getColorList(), args->gs); import_export_dialog.showImport(); } static void menu_file_import_text_file(GtkWidget *widget, AppArgs *args) { ImportExportDialog import_export_dialog(GTK_WINDOW(args->window), args->gs->getColorList(), args->gs); import_export_dialog.showImportTextFile(); } static void menu_file_export(GtkWidget *widget, gpointer data) { AppArgs* args = (AppArgs*)data; ColorList *color_list = color_list_new(); palette_list_foreach_selected(args->color_list, color_list_selected, color_list); ImportExportDialog import_export_dialog(GTK_WINDOW(args->window), color_list, args->gs); import_export_dialog.showExport(); color_list_destroy(color_list); } typedef struct FileMenuItems{ GtkWidget *export_all; GtkWidget *export_selected; GtkWidget *recent_files; GtkWidget *revert; }FileMenuItems; static void menu_file_activate(GtkWidget *widget, gpointer data) { AppArgs* args = (AppArgs*)data; gint32 selected_count = palette_list_get_selected_count(args->color_list); gint32 total_count = palette_list_get_count(args->color_list); FileMenuItems *items = (FileMenuItems*) g_object_get_data(G_OBJECT(widget), "items"); gtk_widget_set_sensitive(items->export_all, (total_count >= 1)); gtk_widget_set_sensitive(items->export_selected, (selected_count >= 1)); gtk_widget_set_sensitive(items->revert, args->current_filename_set); if (args->recent_files.size() > 0){ GtkMenu *menu2 = GTK_MENU(gtk_menu_new()); GtkWidget *item; item = newMenuItem(_("Open Last File"), GTK_STOCK_OPEN); gtk_menu_shell_append (GTK_MENU_SHELL (menu2), item); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (menu_file_open_last), args); gtk_menu_shell_append (GTK_MENU_SHELL (menu2), gtk_separator_menu_item_new ()); uintptr_t j = 0; for (list::iterator i = args->recent_files.begin(); i != args->recent_files.end(); i++){ item = gtk_menu_item_new_with_label ((*i).c_str()); gtk_menu_shell_append (GTK_MENU_SHELL (menu2), item); g_object_set_data_full(G_OBJECT(item), "index", (void*)j, (GDestroyNotify)nullptr); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (menu_file_open_nth), args); j++; } gtk_widget_show_all(GTK_WIDGET(menu2)); gtk_menu_item_set_submenu (GTK_MENU_ITEM (items->recent_files), GTK_WIDGET(menu2)); gtk_widget_set_sensitive(items->recent_files, true); }else{ gtk_widget_set_sensitive(items->recent_files, false); } } static void floating_picker_show_cb(GtkWidget *widget, AppArgs* args) { floating_picker_activate(args->floating_picker, false, false, nullptr); } static void show_about_box_cb(GtkWidget *widget, AppArgs* args) { show_about_box(args->window); } static void repositionViews(AppArgs* args) { bool palette = args->options->getBool("view.palette", true); bool primary_view = args->options->getBool("view.primary_view", true); bool secondary_view = gtk_widget_get_visible(args->secondary_source_container); string layout = args->options->getString("view.layout", "primary+secondary_palette"); GtkWidget *widgets[4] = { args->palette, args->vpaned, args->secondary_source_container, args->notebook }; for (size_t i = 0; i < sizeof(widgets) / sizeof(GtkWidget*); i++){ g_object_ref(widgets[i]); GtkWidget *parent = gtk_widget_get_parent(widgets[i]); if (parent != nullptr) gtk_container_remove(GTK_CONTAINER(parent), widgets[i]); } struct NamedLayoutWidget{ const char *name; GtkWidget *widget; bool visible; }named_widgets[] = { {"palette", args->palette, palette}, {"primary", args->notebook, primary_view}, {"secondary", args->secondary_source_container, secondary_view}, }; NamedLayoutWidget *left[2], *right[2]; int left_index = 0, right_index = 0; bool left_side = true; size_t previous_position = 0; string name; for (;;){ size_t split_position = layout.find_first_of("_+", previous_position); char type; if (split_position != string::npos){ name = layout.substr(previous_position, split_position - previous_position); type = layout[split_position]; }else{ name = layout.substr(previous_position); type = 0; } for (size_t i = 0; i < sizeof(named_widgets) / sizeof(NamedLayoutWidget); i++){ if (name == named_widgets[i].name){ if (!named_widgets[i].visible) break; if (left_side) left[left_index++] = &named_widgets[i]; else right[right_index++] = &named_widgets[i]; break; } } previous_position = split_position + 1; if (type == '_') left_side = false; else if (type == 0) break; } bool vpaned_unused = false; if (left_index != 0 && right_index != 0){ if (left_index > 1){ gtk_paned_pack1(GTK_PANED(args->hpaned), args->vpaned, false, false); gtk_paned_pack2(GTK_PANED(args->hpaned), right[0]->widget, true, false); gtk_paned_pack1(GTK_PANED(args->vpaned), left[0]->widget, false, false); gtk_paned_pack2(GTK_PANED(args->vpaned), left[1]->widget, true, false); }else if (right_index > 1){ gtk_paned_pack1(GTK_PANED(args->hpaned), left[0]->widget, false, false); gtk_paned_pack2(GTK_PANED(args->hpaned), args->vpaned, true, false); gtk_paned_pack1(GTK_PANED(args->vpaned), right[0]->widget, false, false); gtk_paned_pack2(GTK_PANED(args->vpaned), right[1]->widget, true, false); }else{ gtk_paned_pack1(GTK_PANED(args->hpaned), left[0]->widget, false, false); gtk_paned_pack2(GTK_PANED(args->hpaned), right[0]->widget, true, false); vpaned_unused = true; } gtk_widget_show(GTK_WIDGET(args->hpaned)); }else if (left_index != 0 || right_index != 0){ gtk_widget_hide(GTK_WIDGET(args->hpaned)); GtkWidget *widget = nullptr; if (left_index > 1){ widget = args->vpaned; gtk_paned_pack1(GTK_PANED(args->vpaned), left[0]->widget, false, false); gtk_paned_pack2(GTK_PANED(args->vpaned), left[1]->widget, true, false); }else if (right_index > 1){ widget = args->vpaned; gtk_paned_pack1(GTK_PANED(args->vpaned), right[0]->widget, false, false); gtk_paned_pack2(GTK_PANED(args->vpaned), right[1]->widget, true, false); }else if (left_index == 1){ widget = left[0]->widget; vpaned_unused = true; }else if (right_index == 1){ widget = right[0]->widget; vpaned_unused = true; } if (widget) gtk_box_pack_start(GTK_BOX(gtk_widget_get_parent(args->hpaned)), widget, true, true, 5); }else{ gtk_widget_hide(GTK_WIDGET(args->hpaned)); vpaned_unused = true; } if (vpaned_unused){ gtk_widget_hide(args->vpaned); gtk_box_pack_start(GTK_BOX(gtk_widget_get_parent(args->hpaned)), args->vpaned, true, true, 5); }else{ gtk_widget_show(args->vpaned); } for (size_t i = 0; i < sizeof(named_widgets) / sizeof(NamedLayoutWidget); i++){ bool used = false; for (int j = 0; j < left_index; j++){ if (left[j]->widget == named_widgets[i].widget){ used = true; break; } } for (int j = 0; j < right_index; j++){ if (right[j]->widget == named_widgets[i].widget){ used = true; break; } } if (!used){ gtk_widget_hide(named_widgets[i].widget); gtk_box_pack_start(GTK_BOX(gtk_widget_get_parent(args->hpaned)), named_widgets[i].widget, true, true, 5); }else{ gtk_widget_show(named_widgets[i].widget); } } for (size_t i = 0; i < sizeof(widgets) / sizeof(GtkWidget*); i++){ g_object_unref(widgets[i]); } } static void view_palette_cb(GtkWidget *widget, AppArgs* args) { bool view = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)); args->options->set("view.palette", view); repositionViews(args); } static void view_primary_view_cb(GtkWidget *widget, AppArgs* args) { bool view = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)); args->options->set("view.primary_view", view); repositionViews(args); } static void view_layout_cb(GtkWidget *widget, AppArgs* args) { if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))){ args->options->set("view.layout", static_cast(g_object_get_data(G_OBJECT(widget), "source"))); repositionViews(args); } } static void palette_from_image_cb(GtkWidget *widget, AppArgs* args) { tools_palette_from_image_show(GTK_WINDOW(args->window), args->gs); } static void color_space_sampler_cb(GtkWidget *widget, AppArgs* args) { tools_color_space_sampler_show(GTK_WINDOW(args->window), args->gs); } static void text_parser_cb(GtkWidget *widget, AppArgs* args) { tools_text_parser_show(GTK_WINDOW(args->window), args->gs); } static void destroy_file_menu_items(FileMenuItems *items) { delete items; } static void activate_secondary_source(AppArgs *args, ColorSource *source) { if (args->secondary_color_source){ color_source_deactivate(args->secondary_color_source); color_source_destroy(args->secondary_color_source); args->secondary_color_source = 0; args->secondary_source_widget = 0; if (args->secondary_source_scrolled_viewpoint) gtk_container_remove(GTK_CONTAINER(args->secondary_source_container), args->secondary_source_scrolled_viewpoint); args->secondary_source_scrolled_viewpoint= 0; if (!source) gtk_widget_hide(args->secondary_source_container); } if (source){ string namespace_str = "gpick.secondary_view."; namespace_str += source->identificator; auto options = args->gs->settings().getOrCreateMap(namespace_str); source = color_source_implement(source, args->gs, options); GtkWidget *new_widget = color_source_get_widget(source); args->secondary_color_source = source; args->secondary_source_widget = new_widget; if (source->needs_viewport){ GtkWidget *scrolled_window = gtk_scrolled_window_new(0,0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_NONE); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), new_widget); args->secondary_source_scrolled_viewpoint = scrolled_window; gtk_box_pack_start(GTK_BOX(args->secondary_source_container), args->secondary_source_scrolled_viewpoint, true, true, 0); gtk_widget_show(args->secondary_source_scrolled_viewpoint); }else{ gtk_box_pack_start(GTK_BOX(args->secondary_source_container), new_widget, true, true, 0); gtk_widget_show(new_widget); } gtk_widget_show(args->secondary_source_container); color_source_activate(source); } } static void secondary_view_cb(GtkWidget *widget, AppArgs *args) { if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))){ ColorSource *source = static_cast(g_object_get_data(G_OBJECT(widget), "source")); activate_secondary_source(args, source); repositionViews(args); } } static void addLayoutMenuItem(const string &layout, GtkMenu *menu, GSList *&group, AppArgs *args) { const char *components[] = { _("Primary"), _("Palette"), _("Secondary"), }; string label; size_t previous_position = 0; for (;;){ size_t split_position = layout.find_first_of("_+", previous_position); char type; string name; if (split_position != string::npos){ name = layout.substr(previous_position, split_position - previous_position); type = layout[split_position]; }else{ name = layout.substr(previous_position); type = 0; } if (name == "primary"){ label += components[0]; }else if (name == "palette"){ label += components[1]; }else if (name == "secondary"){ label += components[2]; } if (type == '_'){ label += ", "; }else if (type == '+'){ label += "/"; }else if (type == 0){ break; } previous_position = split_position + 1; } GtkWidget *item = gtk_radio_menu_item_new_with_label(group, label.c_str()); group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item)); g_object_set_data_full(G_OBJECT(item), "source", const_cast(layout.c_str()), (GDestroyNotify)nullptr); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(view_layout_cb), args); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); string current_layout = args->options->getString("view.layout", "primary+secondary_palette"); if (current_layout == layout) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), true); } static void create_menu(GtkMenuBar *menu_bar, AppArgs *args, GtkAccelGroup *accel_group) { GtkMenu *menu; GtkWidget *item; GtkWidget* file_item; GtkStockItem stock_item; menu = GTK_MENU(gtk_menu_new()); FileMenuItems *items = new FileMenuItems(); if (gtk_stock_lookup(GTK_STOCK_NEW, &stock_item)){ item = newMenuItem(stock_item.label, stock_item.stock_id); gtk_menu_shell_append(GTK_MENU_SHELL (menu), item); if (stock_item.keyval) gtk_widget_add_accelerator(item, "activate", accel_group, stock_item.keyval, stock_item.modifier, GTK_ACCEL_VISIBLE); g_signal_connect(G_OBJECT (item), "activate", G_CALLBACK(menu_file_new), args); } if (gtk_stock_lookup(GTK_STOCK_OPEN, &stock_item)){ item = newMenuItem(stock_item.label, stock_item.stock_id); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); if (stock_item.keyval) gtk_widget_add_accelerator(item, "activate", accel_group, stock_item.keyval, stock_item.modifier, GTK_ACCEL_VISIBLE); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(menu_file_open), args); } item = gtk_menu_item_new_with_mnemonic(_("Recent _Files")); items->recent_files = item; gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); if (gtk_stock_lookup(GTK_STOCK_REVERT_TO_SAVED, &stock_item)){ item = newMenuItem(stock_item.label, stock_item.stock_id); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_r, GdkModifierType(GDK_CONTROL_MASK), GTK_ACCEL_VISIBLE); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_F5, GdkModifierType(0), GTK_ACCEL_VISIBLE); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(menu_file_revert), args); items->revert = item; } gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new ()); if (gtk_stock_lookup(GTK_STOCK_SAVE, &stock_item)){ item = newMenuItem(stock_item.label, stock_item.stock_id); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); if (stock_item.keyval) gtk_widget_add_accelerator (item, "activate", accel_group, stock_item.keyval, stock_item.modifier, GTK_ACCEL_VISIBLE); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK(menu_file_save), args); } if (gtk_stock_lookup(GTK_STOCK_SAVE_AS, &stock_item)){ item = newMenuItem(stock_item.label, stock_item.stock_id); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); if (stock_item.keyval) gtk_widget_add_accelerator (item, "activate", accel_group, stock_item.keyval, stock_item.modifier, GTK_ACCEL_VISIBLE); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK(menu_file_save_as), args); } gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new ()); item = gtk_image_menu_item_new_with_mnemonic(_("Ex_port...")); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_e, GdkModifierType(GDK_CONTROL_MASK), GTK_ACCEL_VISIBLE); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect(G_OBJECT (item), "activate", G_CALLBACK (menu_file_export_all), args); items->export_all = item; item = gtk_image_menu_item_new_with_mnemonic(_("Expo_rt Selected...")); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_e, GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK), GTK_ACCEL_VISIBLE); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect(G_OBJECT (item), "activate", G_CALLBACK (menu_file_export), args); items->export_selected = item; item = gtk_image_menu_item_new_with_mnemonic(_("_Import...")); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_i, GdkModifierType(GDK_CONTROL_MASK), GTK_ACCEL_VISIBLE); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect(G_OBJECT (item), "activate", G_CALLBACK (menu_file_import), args); item = gtk_image_menu_item_new_with_mnemonic(_("Import _Text File...")); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_i, GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK), GTK_ACCEL_VISIBLE); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(menu_file_import_text_file), args); gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new ()); if (gtk_stock_lookup(GTK_STOCK_QUIT, &stock_item)){ item = newMenuItem(stock_item.label, stock_item.stock_id); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); if (stock_item.keyval) gtk_widget_add_accelerator (item, "activate", accel_group, stock_item.keyval, stock_item.modifier, GTK_ACCEL_VISIBLE); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK(destroy_cb), args); } file_item = gtk_menu_item_new_with_mnemonic(_("_File")); g_signal_connect (G_OBJECT (file_item), "activate", G_CALLBACK (menu_file_activate), args); g_object_set_data_full(G_OBJECT(file_item), "items", items, (GDestroyNotify)destroy_file_menu_items); gtk_menu_item_set_submenu (GTK_MENU_ITEM (file_item),GTK_WIDGET( menu)); gtk_menu_shell_append (GTK_MENU_SHELL (menu_bar), file_item); menu = GTK_MENU(gtk_menu_new()); item = newMenuItem(_("Edit _Converters..."), GTK_STOCK_PROPERTIES); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (show_dialog_converter), args); item = newMenuItem(_("Display _Filters..."), GTK_STOCK_PROPERTIES); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (show_dialog_transformations), args); item = newMenuItem(_("Color _Dictionaries..."), GTK_STOCK_PROPERTIES); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(show_dialog_color_dictionaries), args); if (gtk_stock_lookup(GTK_STOCK_PREFERENCES, &stock_item)){ item = newMenuItem(stock_item.label, stock_item.stock_id); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); if (stock_item.keyval) gtk_widget_add_accelerator (item, "activate", accel_group, stock_item.keyval, stock_item.modifier, GTK_ACCEL_VISIBLE); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK(show_dialog_options), args); } file_item = gtk_menu_item_new_with_mnemonic(_("_Edit")); gtk_menu_item_set_submenu (GTK_MENU_ITEM (file_item),GTK_WIDGET( menu)); gtk_menu_shell_append (GTK_MENU_SHELL (menu_bar), file_item); menu = GTK_MENU(gtk_menu_new()); GtkMenu *menu2 = GTK_MENU(gtk_menu_new()); GSList *group = nullptr; addLayoutMenuItem("primary+secondary_palette", menu2, group, args); addLayoutMenuItem("primary+palette_secondary", menu2, group, args); addLayoutMenuItem("primary_palette+secondary", menu2, group, args); addLayoutMenuItem("palette+secondary_primary", menu2, group, args); addLayoutMenuItem("palette+primary_secondary", menu2, group, args); addLayoutMenuItem("palette_primary+secondary", menu2, group, args); addLayoutMenuItem("secondary+primary_palette", menu2, group, args); addLayoutMenuItem("secondary+palette_primary", menu2, group, args); addLayoutMenuItem("secondary_primary+palette", menu2, group, args); item = gtk_menu_item_new_with_mnemonic(_("_Layout")); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), GTK_WIDGET(menu2)); menu2 = GTK_MENU(gtk_menu_new()); group = nullptr; ColorSource *source = color_source_manager_get(args->csm, args->options->getString("secondary_color_source", "")); item = gtk_radio_menu_item_new_with_label(group, _("None")); group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item)); if (source == nullptr) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), true); g_object_set_data_full(G_OBJECT(item), "source", 0, (GDestroyNotify)nullptr); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(secondary_view_cb), args); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_N, GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK), GTK_ACCEL_VISIBLE); gtk_menu_shell_append(GTK_MENU_SHELL(menu2), item); vector sources = color_source_manager_get_all(args->csm); for (uint32_t i = 0; i < sources.size(); i++){ if (!(sources[i]->single_instance_only)){ item = gtk_radio_menu_item_new_with_label(group, sources[i]->hr_name); group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item)); if (source == sources[i]) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), true); g_object_set_data_full(G_OBJECT(item), "source", sources[i], (GDestroyNotify)nullptr); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(secondary_view_cb), args); if (color_source_get_default_accelerator(sources[i])) gtk_widget_add_accelerator(item, "activate", accel_group, color_source_get_default_accelerator(sources[i]), GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK), GTK_ACCEL_VISIBLE); gtk_menu_shell_append(GTK_MENU_SHELL(menu2), item); } } item = gtk_menu_item_new_with_mnemonic(_("_Secondary View")); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), GTK_WIDGET(menu2)); gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); item = gtk_check_menu_item_new_with_mnemonic(_("_Primary View")); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), args->options->getBool("view.primary_view", true)); g_signal_connect(G_OBJECT(item), "toggled", G_CALLBACK(view_primary_view_cb), args); item = gtk_check_menu_item_new_with_mnemonic(_("Palette")); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), args->options->getBool("view.palette", true)); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_p, GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK), GTK_ACCEL_VISIBLE); g_signal_connect(G_OBJECT(item), "toggled", G_CALLBACK(view_palette_cb), args); file_item = gtk_menu_item_new_with_mnemonic (_("_View")); gtk_menu_item_set_submenu (GTK_MENU_ITEM (file_item),GTK_WIDGET( menu)); gtk_menu_shell_append (GTK_MENU_SHELL (menu_bar), file_item); menu = GTK_MENU(gtk_menu_new()); item = gtk_menu_item_new_with_mnemonic(_("_Pick colors...")); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_p, GdkModifierType(GDK_CONTROL_MASK), GTK_ACCEL_VISIBLE); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(floating_picker_show_cb), args); gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); item = gtk_menu_item_new_with_mnemonic(_("Palette From _Image...")); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(palette_from_image_cb), args); item = gtk_menu_item_new_with_mnemonic(_("Color Space _Sampler...")); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(color_space_sampler_cb), args); item = gtk_menu_item_new_with_mnemonic(_("_Text Parser...")); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(text_parser_cb), args); file_item = gtk_menu_item_new_with_mnemonic(_("_Tools")); gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_item), GTK_WIDGET(menu)); gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), file_item); menu = GTK_MENU(gtk_menu_new()); if (gtk_stock_lookup(GTK_STOCK_ABOUT, &stock_item)){ item = newMenuItem(stock_item.label, stock_item.stock_id); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); if (stock_item.keyval) gtk_widget_add_accelerator (item, "activate", accel_group, stock_item.keyval, stock_item.modifier, GTK_ACCEL_VISIBLE); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK(show_about_box_cb), args); } file_item = gtk_menu_item_new_with_mnemonic (_("_Help")); gtk_menu_item_set_submenu (GTK_MENU_ITEM (file_item),GTK_WIDGET( menu)); gtk_menu_shell_append (GTK_MENU_SHELL (menu_bar), file_item); } static PaletteListCallbackReturn color_list_mark_selected(ColorObject* color_object, void *userdata) { color_object->setSelected(true); return PALETTE_LIST_CALLBACK_NO_UPDATE; } static void palette_popup_menu_remove_all(GtkWidget *widget, AppArgs* args) { color_list_remove_all(args->gs->getColorList()); } static void palette_popup_menu_remove_selected(GtkWidget *widget, AppArgs* args) { palette_list_foreach_selected(args->color_list, color_list_mark_selected, 0); color_list_remove_selected(args->gs->getColorList()); } static PaletteListCallbackReturn color_list_clear_names(ColorObject* color_object, void *userdata) { color_object->setName(""); return PALETTE_LIST_CALLBACK_UPDATE_NAME; } static void palette_popup_menu_clear_names(GtkWidget *widget, AppArgs* args) { palette_list_foreach_selected(args->color_list, color_list_clear_names, nullptr); } typedef struct AutonameState{ ColorNames *color_names; bool imprecision_postfix; }AutonameState; static PaletteListCallbackReturn color_list_autoname(ColorObject* color_object, void *userdata) { AutonameState *state = (AutonameState *)(userdata); Color color = color_object->getColor(); color_object->setName(color_names_get(state->color_names, &color, state->imprecision_postfix)); return PALETTE_LIST_CALLBACK_UPDATE_NAME; } static void palette_popup_menu_autoname(GtkWidget *widget, AppArgs* args) { AutonameState state; state.color_names = args->gs->getColorNames(); state.imprecision_postfix = args->gs->settings().getBool("gpick.color_names.imprecision_postfix", false); palette_list_foreach_selected(args->color_list, color_list_autoname, &state); } typedef struct AutonumberState{ std::string name; uint32_t index; uint32_t nplaces; bool decreasing; bool append; }AutonumberState; static PaletteListCallbackReturn color_list_autonumber(ColorObject* color_object, void *userdata) { AutonumberState *state = (AutonumberState*)userdata; stringstream ss; if (state->append == true){ ss << color_object->getName() << " "; } ss << state->name << "-"; ss.width(state->nplaces); ss.fill('0'); if (state->decreasing){ ss << right << state->index; state->index--; } else{ ss << right << state->index++; } color_object->setName(ss.str()); return PALETTE_LIST_CALLBACK_UPDATE_NAME; } static PaletteListCallbackReturn color_list_set_color(ColorObject* color_object, void *userdata) { Color *source_color = (Color *)(userdata); color_object->setColor(*source_color); return PALETTE_LIST_CALLBACK_UPDATE_ROW; } static void palette_popup_menu_autonumber(GtkWidget *widget, AppArgs* args) { AutonumberState state; int response; uint32_t selected_count = palette_list_get_selected_count(args->color_list); response = dialog_autonumber_show(GTK_WINDOW(args->window), selected_count, args->gs); if (response == GTK_RESPONSE_OK){ auto autonumberOptions = args->gs->settings().getOrCreateMap("gpick.autonumber"); state.name = autonumberOptions->getString("name", "autonum"); state.nplaces = autonumberOptions->getInt32("nplaces", 1); state.index = autonumberOptions->getInt32("startindex", 1); state.decreasing = autonumberOptions->getBool("decreasing", true); state.append = autonumberOptions->getBool("append", true); palette_list_foreach_selected(args->color_list, color_list_autonumber, &state); } } typedef struct ReplaceState{ std::list::reverse_iterator iter; } ReplaceState; static PaletteListCallbackReturn color_list_reverse_replace(ColorObject** color_object, void *userdata) { ReplaceState *state = reinterpret_cast(userdata); *color_object = (*(state->iter))->reference(); state->iter++; return PALETTE_LIST_CALLBACK_UPDATE_ROW; } static void palette_popup_menu_reverse(GtkWidget *widget, AppArgs* args) { ColorList *color_list = color_list_new(); ReplaceState state; palette_list_foreach_selected(args->color_list, color_list_selected, color_list); state.iter = color_list->colors.rbegin(); palette_list_foreach_selected(args->color_list, color_list_reverse_replace, &state); } static void palette_popup_menu_add(GtkWidget *widget, AppArgs* args) { ColorObject *new_color_object = nullptr; if (dialog_color_input_show(GTK_WINDOW(gtk_widget_get_toplevel(widget)), args->gs, nullptr, &new_color_object) == 0){ color_list_add_color_object(args->gs->getColorList(), new_color_object, 1); new_color_object->release(); } } static void palette_popup_menu_edit(GtkWidget *widget, AppArgs* args) { ColorObject *color_object = palette_list_get_first_selected(args->color_list)->reference(), *new_color_object = nullptr; if (dialog_color_input_show(GTK_WINDOW(gtk_widget_get_toplevel(widget)), args->gs, color_object, &new_color_object) == 0){ color_object->setColor(new_color_object->getColor()); new_color_object->release(); palette_list_update_first_selected(args->color_list, false); } color_object->release(); } static void palette_popup_menu_paste(GtkWidget *, AppArgs *args) { auto newColorList = clipboard::getColors(args->gs); if (!newColorList) return; auto ourColorList = args->gs->getColorList(); for (auto &colorObject: newColorList->colors) { color_list_add_color_object(ourColorList, colorObject, true); } color_list_destroy(newColorList); } gint32 palette_popup_menu_mix_list(Color* color, void *userdata) { *((GList**)userdata) = g_list_append(*((GList**)userdata), color); return 0; } static void palette_popup_menu_mix(GtkWidget *widget, AppArgs* args) { ColorList *color_list = color_list_new(); palette_list_foreach_selected(args->color_list, color_list_selected, color_list); dialog_mix_show(GTK_WINDOW(args->window), color_list, args->gs); color_list_destroy(color_list); } static void palette_popup_menu_variations(GtkWidget *widget, AppArgs* args) { ColorList *color_list = color_list_new(); palette_list_foreach_selected(args->color_list, color_list_selected, color_list); dialog_variations_show(GTK_WINDOW(args->window), color_list, args->gs); color_list_destroy(color_list); } static void palette_popup_menu_generate(GtkWidget *widget, AppArgs* args) { ColorList *color_list = color_list_new(); palette_list_foreach_selected(args->color_list, color_list_selected, color_list); dialog_generate_show(GTK_WINDOW(args->window), color_list, args->gs); color_list_destroy(color_list); } typedef struct GroupAndSortState{ std::list::iterator iter; } GroupAndSortState; static PaletteListCallbackReturn color_list_group_and_sort_replace(ColorObject** color_object, void *userdata) { GroupAndSortState *state = reinterpret_cast(userdata); *color_object = (*(state->iter))->reference(); state->iter++; return PALETTE_LIST_CALLBACK_UPDATE_ROW; } static void palette_popup_menu_group_and_sort(GtkWidget *widget, AppArgs* args) { ColorList *color_list = color_list_new(); ColorList *sorted_color_list = color_list_new(); palette_list_foreach_selected(args->color_list, color_list_selected, color_list); if (dialog_sort_show(GTK_WINDOW(args->window), color_list, sorted_color_list, args->gs)){ GroupAndSortState state; state.iter = sorted_color_list->colors.begin(); palette_list_foreach_selected(args->color_list, color_list_group_and_sort_replace, &state); } color_list_destroy(color_list); color_list_destroy(sorted_color_list); } static gboolean palette_popup_menu_show(GtkWidget *widget, GdkEventButton* event, AppArgs *args) { auto menu = gtk_menu_new(); GtkAccelGroup *accel_group = gtk_accel_group_new(); gtk_menu_set_accel_group(GTK_MENU(menu), accel_group); gint32 selected_count = palette_list_get_selected_count(args->color_list); gint32 total_count = palette_list_get_count(args->color_list); if (total_count > 0 && selected_count >= 1){ palette_list_append_copy_menu(args->color_list, menu); }else{ StandardMenu::appendMenu(menu); } gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); auto item = newMenuItem(_("A_dd..."), GTK_STOCK_NEW); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(palette_popup_menu_add), args); item = newMenuItem(_("_Edit..."), GTK_STOCK_EDIT); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(palette_popup_menu_edit), args); gtk_widget_set_sensitive(item, (selected_count == 1)); item = newMenuItem(_("_Paste"), GTK_STOCK_PASTE); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_V, GdkModifierType(GDK_CONTROL_MASK), GTK_ACCEL_VISIBLE); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(palette_popup_menu_paste), args); gtk_widget_set_sensitive(item, clipboard::colorObjectAvailable()); gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); item = newMenuItem (_("_Mix Colors..."), GTK_STOCK_CONVERT); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect(G_OBJECT (item), "activate", G_CALLBACK(palette_popup_menu_mix), args); gtk_widget_set_sensitive(item, (selected_count >= 2)); item = newMenuItem (_("_Variations..."), GTK_STOCK_CONVERT); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect(G_OBJECT (item), "activate", G_CALLBACK(palette_popup_menu_variations), args); gtk_widget_set_sensitive(item, (selected_count >= 1)); item = newMenuItem (_("_Generate..."), GTK_STOCK_CONVERT); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect(G_OBJECT (item), "activate", G_CALLBACK(palette_popup_menu_generate), args); gtk_widget_set_sensitive(item, (selected_count >= 1)); gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new ()); item = gtk_menu_item_new_with_mnemonic (_("C_lear names")); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect(G_OBJECT (item), "activate", G_CALLBACK(palette_popup_menu_clear_names), args); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_E, GdkModifierType(0), GTK_ACCEL_VISIBLE); gtk_widget_set_sensitive(item, (selected_count >= 1)); item = gtk_menu_item_new_with_mnemonic (_("Autona_me")); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect(G_OBJECT (item), "activate", G_CALLBACK(palette_popup_menu_autoname), args); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_N, GdkModifierType(0), GTK_ACCEL_VISIBLE); gtk_widget_set_sensitive(item, (selected_count >= 1)); item = gtk_menu_item_new_with_mnemonic (_("Auto_number...")); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect(G_OBJECT (item), "activate", G_CALLBACK(palette_popup_menu_autonumber), args); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_a, GdkModifierType(0), GTK_ACCEL_VISIBLE); gtk_widget_set_sensitive(item, (selected_count >= 1)); gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new ()); item = gtk_menu_item_new_with_mnemonic(_("R_everse")); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect(G_OBJECT (item), "activate", G_CALLBACK(palette_popup_menu_reverse), args); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_v, GdkModifierType(0), GTK_ACCEL_VISIBLE); gtk_widget_set_sensitive(item, (selected_count >= 2)); item = gtk_menu_item_new_with_mnemonic(_("Group and _sort...")); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(palette_popup_menu_group_and_sort), args); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_g, GdkModifierType(0), GTK_ACCEL_VISIBLE); gtk_widget_set_sensitive(item, (selected_count >= 2)); gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new ()); item = newMenuItem(_("_Remove"), GTK_STOCK_REMOVE); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect(G_OBJECT (item), "activate", G_CALLBACK(palette_popup_menu_remove_selected), args); gtk_widget_add_accelerator(item, "activate", accel_group, GDK_KEY_Delete, GdkModifierType(0), GTK_ACCEL_VISIBLE); gtk_widget_set_sensitive(item, (selected_count >= 1)); item = newMenuItem(_("Remove _All"), GTK_STOCK_REMOVE); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); g_signal_connect(G_OBJECT (item), "activate", G_CALLBACK(palette_popup_menu_remove_all), args); gtk_widget_set_sensitive(item, (total_count >= 1)); showContextMenu(menu, event); g_object_ref_sink(G_OBJECT(accel_group)); g_object_unref(G_OBJECT(accel_group)); return TRUE; } static void on_palette_popup_menu(GtkWidget *widget, AppArgs *args) { palette_popup_menu_show(widget, 0, args); } static gboolean on_palette_button_press(GtkWidget *widget, GdkEventButton *event, AppArgs *args) { if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { return palette_popup_menu_show(widget, event, args); } return FALSE; } static gboolean on_palette_list_key_press(GtkWidget *widget, GdkEventKey *event, AppArgs *args) { guint modifiers = gtk_accelerator_get_default_mod_mask(); guint keyval; switch((keyval = getKeyval(*event, args->gs->latinKeysGroup))) { case GDK_KEY_1: case GDK_KEY_KP_1: case GDK_KEY_2: case GDK_KEY_KP_2: case GDK_KEY_3: case GDK_KEY_KP_3: case GDK_KEY_4: case GDK_KEY_KP_4: case GDK_KEY_5: case GDK_KEY_KP_5: case GDK_KEY_6: case GDK_KEY_KP_6: { ColorList *color_list = color_list_new(); palette_list_forfirst_selected(args->color_list, color_list_selected, color_list); if (color_list_get_count(color_list) > 0){ ColorSource *color_source = args->gs->getCurrentColorSource(); uint32_t color_index = 0; switch(keyval) { case GDK_KEY_KP_1: case GDK_KEY_1: color_index = 0; break; case GDK_KEY_KP_2: case GDK_KEY_2: color_index = 1; break; case GDK_KEY_KP_3: case GDK_KEY_3: color_index = 2; break; case GDK_KEY_KP_4: case GDK_KEY_4: color_index = 3; break; case GDK_KEY_KP_5: case GDK_KEY_5: color_index = 4; break; case GDK_KEY_KP_6: case GDK_KEY_6: color_index = 5; break; } if ((event->state&modifiers) == GDK_CONTROL_MASK){ ColorObject *source_color_object; Color source_color; color_source_get_nth_color(color_source, color_index, &source_color_object); source_color = source_color_object->getColor(); palette_list_forfirst_selected (args->color_list, color_list_set_color, &source_color); } else{ color_source_set_nth_color(color_source, color_index, *color_list->colors.begin()); } } color_list_destroy(color_list); return true; } return false; case GDK_KEY_c: if ((event->state & modifiers) == GDK_CONTROL_MASK) { clipboard::set(args->color_list, args->gs, Converters::Type::copy); return true; } return false; case GDK_KEY_v: if ((event->state & modifiers) == GDK_CONTROL_MASK) { palette_popup_menu_paste(nullptr, args); return true; } else { palette_popup_menu_reverse(widget, args); return true; } return false; case GDK_KEY_g: palette_popup_menu_group_and_sort(widget, args); return true; case GDK_KEY_Delete: palette_popup_menu_remove_selected(widget, args); break; case GDK_KEY_a: if ((event->state & GDK_CONTROL_MASK) == 0){ palette_popup_menu_autonumber(widget, args); return true; } break; case GDK_KEY_e: if ((event->state & GDK_CONTROL_MASK) == 0){ palette_popup_menu_clear_names(widget, args); return true; } break; case GDK_KEY_n: if ((event->state & GDK_CONTROL_MASK) == 0){ palette_popup_menu_autoname(widget, args); return true; } break; default: return false; } return false; } static int color_list_on_insert(ColorList* color_list, ColorObject* color_object) { palette_list_add_entry(((AppArgs*)color_list->userdata)->color_list, color_object); return 0; } static int color_list_on_delete_selected(ColorList* color_list) { palette_list_remove_selected_entries(((AppArgs*)color_list->userdata)->color_list); return 0; } static int color_list_on_delete(ColorList* color_list, ColorObject* color_object) { palette_list_remove_entry(((AppArgs*)color_list->userdata)->color_list, color_object); return 0; } static int color_list_on_clear(ColorList* color_list) { palette_list_remove_all_entries(((AppArgs*)color_list->userdata)->color_list); return 0; } static PaletteListCallbackReturn callback_color_list_on_get_positions(ColorObject* color_object, size_t *position) { color_object->setPosition(*position); (*position)++; return PALETTE_LIST_CALLBACK_NO_UPDATE; } static int color_list_on_get_positions(ColorList* color_list) { size_t position = 0; palette_list_foreach(((AppArgs*)color_list->userdata)->color_list, (PaletteListCallback)callback_color_list_on_get_positions, &position); return 0; } int main_show_window(GtkWidget* window, const dynv::Ref &options) { if (gtk_widget_get_visible(window)){ gtk_window_deiconify(GTK_WINDOW(window)); return -1; //already visible } gint x, y; gint width, height; x = options->getInt32("window.x", -1); y = options->getInt32("window.y", -1); width = options->getInt32("window.width", 640); height = options->getInt32("window.height", 400); if (x < 0 || y < 0 || x > gdk_screen_width() || y > gdk_screen_height()){ gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); }else{ gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_NONE); gtk_window_move(GTK_WINDOW(window), x, y); } if (width > 0 && height > 0) gtk_window_resize(GTK_WINDOW(window), width, height); gtk_widget_show(window); return 0; } static gboolean on_window_focus_change(GtkWidget *widget, GdkEventFocus *event, AppArgs* args) { if (event->in){ if (args->secondary_color_source) color_source_activate(args->secondary_color_source); if (args->current_color_source) color_source_activate(args->current_color_source); }else{ if (args->secondary_color_source) color_source_deactivate(args->secondary_color_source); if (args->current_color_source) color_source_deactivate(args->current_color_source); } return FALSE; } static void set_main_window_icon() { GList *icons = 0; GtkIconTheme *icon_theme; GError *error = nullptr; icon_theme = gtk_icon_theme_get_default(); gint sizes[] = {16, 32, 48, 128}; for (guint32 i = 0; i < sizeof(sizes) / sizeof(gint); ++i) { GdkPixbuf* pixbuf = gtk_icon_theme_load_icon(icon_theme, "gpick", sizes[i], GtkIconLookupFlags(0), &error); if (pixbuf && (error == nullptr)){ icons = g_list_append(icons, pixbuf); } if (error){ cerr << error->message << endl; g_error_free(error); error = nullptr; } } if (icons){ gtk_window_set_default_icon_list(icons); g_list_foreach(icons, (GFunc)g_object_unref, nullptr); g_list_free(icons); } } bool app_is_autoload_enabled(AppArgs *args) { return args->options->getBool("main.save_restore_palette", true); } static void app_initialize_variables(AppArgs *args) { args->current_filename_set = false; args->imported = false; args->precision_loss_icon = 0; args->current_color_source = 0; args->secondary_color_source = 0; args->secondary_source_widget = 0; args->secondary_source_scrolled_viewpoint = 0; args->gs->loadAll(); dialog_options_update(args->gs); args->options = args->gs->settings().getOrCreateMap("gpick.main"); args->csm = color_source_manager_create(); register_sources(args->csm); } static void app_initialize_color_list(AppArgs *args) { args->gs->getColorList()->on_insert = color_list_on_insert; args->gs->getColorList()->on_clear = color_list_on_clear; args->gs->getColorList()->on_delete_selected = color_list_on_delete_selected; args->gs->getColorList()->on_get_positions = color_list_on_get_positions; args->gs->getColorList()->on_delete = color_list_on_delete; args->gs->getColorList()->userdata = args; } static void app_initialize_floating_picker(AppArgs *args) { args->floating_picker = floating_picker_new(args->gs); } static void app_initialize_picker(AppArgs *args, GtkWidget *notebook) { auto colorPickerOptions = args->gs->settings().getOrCreateMap("gpick.picker"); auto source = color_source_implement(color_source_manager_get(args->csm, "color_picker"), args->gs, colorPickerOptions); GtkWidget *widget = color_source_get_widget(source); args->color_source[source->identificator] = source; args->color_source_index.push_back(source); floating_picker_set_picker_source(args->floating_picker, source); color_picker_set_floating_picker(source, args->floating_picker); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), widget, gtk_label_new_with_mnemonic(_("Color pic_ker"))); gtk_widget_show(widget); } void app_initialize() { GtkIconTheme *icon_theme = gtk_icon_theme_get_default(); auto dataPath = buildFilename(); gtk_icon_theme_append_search_path(icon_theme, dataPath.c_str()); } AppArgs* app_create_main(const StartupOptions &startupOptions, int &return_value) { AppArgs* args = new AppArgs; args->initialization = true; args->startupOptions = startupOptions; color_init(); args->gs = new GlobalState(); args->gs->loadSettings(); if (args->startupOptions.single_color_pick_mode){ app_initialize_variables(args); app_initialize_floating_picker(args); args->initialization = false; return args; // No main UI initialization needed }else{ args->dbus_control.onActivateFloatingPicker = [args](const char *converter_name){ if (converter_name != nullptr && string(converter_name).length() > 0){ floating_picker_activate(args->floating_picker, false, false, converter_name); }else{ floating_picker_activate(args->floating_picker, false, false, nullptr); } return true; }; args->dbus_control.onSingleInstanceActivate = [args]{ status_icon_set_visible(args->status_icon, false); main_show_window(args->window, args->options); return true; }; args->dbus_control.ownName(); bool cancel_startup = false; if (!cancel_startup && startupOptions.floating_picker_mode){ if (args->dbus_control.activateFloatingPicker(startupOptions.converter_name)){ cancel_startup = true; }else if (startupOptions.do_not_start){ return_value = 1; cancel_startup = true; } } if (startupOptions.do_not_start){ if (args->dbus_control.checkIfRunning()){ return_value = 1; cancel_startup = true; } } if (!cancel_startup && args->gs->settings().getBool("gpick.main.single_instance", false)){ if (args->dbus_control.singleInstanceActivate()){ cancel_startup = true; } } if (cancel_startup){ delete args; return 0; } app_initialize_variables(args); app_initialize_color_list(args); } g_signal_connect(G_OBJECT(gdk_keymap_get_for_display(gdk_display_get_default())), "keys-changed", G_CALLBACK(detectLatinKeyGroup), args); detectLatinKeyGroup(nullptr, args); #if GTK_MAJOR_VERSION >= 3 auto cssProvider = gtk_css_provider_new(); GError *error = nullptr; auto style = "button.small-statusbar-button{padding:1px;margin:0;min-height:0;min-width:0;}"s; gtk_css_provider_load_from_data(cssProvider, style.c_str(), style.length(), &error); gtk_style_context_add_provider_for_screen(gdk_screen_get_default(), GTK_STYLE_PROVIDER(cssProvider), GTK_STYLE_PROVIDER_PRIORITY_USER); #endif args->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); set_main_window_icon(); app_update_program_name(args); g_signal_connect(G_OBJECT(args->window), "delete_event", G_CALLBACK(delete_event), args); g_signal_connect(G_OBJECT(args->window), "destroy", G_CALLBACK(destroy_cb), args); g_signal_connect(G_OBJECT(args->window), "configure-event", G_CALLBACK(on_window_configure), args); g_signal_connect(G_OBJECT(args->window), "window-state-event", G_CALLBACK(on_window_state_event), args); g_signal_connect(G_OBJECT(args->window), "focus-in-event", G_CALLBACK(on_window_focus_change), args); g_signal_connect(G_OBJECT(args->window), "focus-out-event", G_CALLBACK(on_window_focus_change), args); g_signal_connect(G_OBJECT(args->window), "key-press-event", G_CALLBACK(on_window_key_press), args); GtkAccelGroup *accel_group = gtk_accel_group_new(); gtk_window_add_accel_group(GTK_WINDOW(args->window), accel_group); g_object_unref(G_OBJECT (accel_group)); GtkWidget *widget, *statusbar, *notebook, *vpaned, *hpaned; GtkWidget* vbox_main = gtk_vbox_new(false, 0); gtk_container_add (GTK_CONTAINER(args->window), vbox_main); GtkWidget* menu_bar; menu_bar = gtk_menu_bar_new (); gtk_box_pack_start (GTK_BOX(vbox_main), menu_bar, FALSE, FALSE, 0); hpaned = gtk_hpaned_new(); vpaned = gtk_vpaned_new(); args->vpaned = vpaned; notebook = gtk_notebook_new(); g_signal_connect(G_OBJECT(notebook), "switch-page", G_CALLBACK(notebook_switch_cb), args); gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), true); statusbar = gtk_statusbar_new(); args->gs->setStatusBar(statusbar); gtk_widget_show_all(notebook); gtk_widget_show_all(vpaned); gtk_box_pack_start(GTK_BOX(vbox_main), hpaned, true, true, 5); gtk_widget_show_all(vbox_main); ColorSource *source; app_initialize_floating_picker(args); app_initialize_picker(args, notebook); auto generateSchemeOptions = args->gs->settings().getOrCreateMap("gpick.generate_scheme"); source = color_source_implement(color_source_manager_get(args->csm, "generate_scheme"), args->gs, generateSchemeOptions); widget = color_source_get_widget(source); args->color_source[source->identificator] = source; args->color_source_index.push_back(source); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), widget, gtk_label_new_with_mnemonic(_("Scheme _generation"))); gtk_widget_show(widget); { widget = gtk_vbox_new(false, 0); args->secondary_source_container = widget; source = color_source_manager_get(args->csm, args->options->getString("secondary_color_source", "")); if (source) activate_secondary_source(args, source); } auto layoutPreviewOptions = args->gs->settings().getOrCreateMap("gpick.layout_preview"); source = color_source_implement(color_source_manager_get(args->csm, "layout_preview"), args->gs, layoutPreviewOptions); widget = color_source_get_widget(source); args->color_source[source->identificator] = source; args->color_source_index.push_back(source); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), widget, gtk_label_new_with_mnemonic(_("Lay_out preview"))); gtk_widget_show(widget); GtkWidget *count_label = gtk_label_new(""); widget = palette_list_new(args->gs, count_label); args->color_list = widget; gtk_widget_show(widget); g_signal_connect(G_OBJECT(widget), "popup-menu", G_CALLBACK (on_palette_popup_menu), args); g_signal_connect(G_OBJECT(widget), "button-press-event",G_CALLBACK (on_palette_button_press), args); g_signal_connect(G_OBJECT(widget), "key_press_event", G_CALLBACK (on_palette_list_key_press), args); GtkWidget *scrolled_window; scrolled_window = gtk_scrolled_window_new (0,0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(scrolled_window), args->color_list ); gtk_widget_show(scrolled_window); args->palette = scrolled_window; args->hpaned = hpaned; args->notebook = notebook; repositionViews(args); { auto tab = args->options->getString("color_source", ""); std::map::iterator i = args->color_source.find(tab); if (i != args->color_source.end()) { size_t tabIndex = 0; for (auto &colorSource: args->color_source_index) { if (colorSource == (*i).second) { gtk_notebook_set_current_page(GTK_NOTEBOOK(args->notebook), tabIndex); if (is_color_picker(colorSource)) color_picker_focus_swatch(colorSource); break; } tabIndex++; } } } gtk_box_pack_end (GTK_BOX(vbox_main), statusbar, 0, 0, 0); args->statusbar = statusbar; GtkWidget *button = gtk_button_new(); #if GTK_MAJOR_VERSION >= 3 auto context = gtk_widget_get_style_context(button); gtk_style_context_add_class(context, "small-statusbar-button"); #endif gtk_button_set_focus_on_click(GTK_BUTTON(button), false); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(floating_picker_show_cb), args); gtk_widget_add_accelerator(button, "clicked", accel_group, GDK_KEY_p, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); gtk_widget_set_tooltip_text(button, _("Pick colors (Ctrl+P)")); gtk_container_add(GTK_CONTAINER(button), newIcon("gpick", 16)); gtk_box_pack_end(GTK_BOX(statusbar), button, false, false, 0); gtk_widget_show_all(button); gtk_box_pack_end(GTK_BOX(statusbar), count_label, false, false, 0); gtk_widget_show_all(count_label); widget = newIcon(GTK_STOCK_DIALOG_WARNING, 16); gtk_widget_set_tooltip_text(widget, _("File is currently in a non-native format, possible loss of precision and/or metadata.")); args->precision_loss_icon = widget; if (args->imported) gtk_widget_show(widget); gtk_box_pack_end(GTK_BOX(statusbar), widget, false, false, 0); gtk_widget_show(statusbar); { //Load recent file list auto recentFiles = args->gs->settings().getStrings("gpick.recent.files"); args->recent_files = std::list(recentFiles.begin(), recentFiles.end()); } create_menu(GTK_MENU_BAR(menu_bar), args, accel_group); gtk_widget_show_all(menu_bar); args->status_icon = status_icon_new(args->window, args->gs, args->floating_picker); args->initialization = false; return args; } static void app_release(AppArgs *args) { if (args->current_color_source){ color_source_deactivate(args->current_color_source); args->current_color_source = 0; } if (args->secondary_color_source){ color_source_deactivate(args->secondary_color_source); color_source_destroy(args->secondary_color_source); args->secondary_color_source = 0; args->secondary_source_widget = 0; } for (map::iterator i = args->color_source.begin(); i != args->color_source.end(); ++i){ color_source_destroy((*i).second); } args->color_source.clear(); args->color_source_index.clear(); floating_picker_free(args->floating_picker); if (!args->startupOptions.single_color_pick_mode){ if (app_is_autoload_enabled(args)){ using namespace boost::interprocess; using namespace boost::filesystem; try { named_mutex mutex(open_or_create, "gpick.autosave"); scoped_lock lock(mutex); auto autoSaveFile = buildConfigPath("autosave.gpa"); auto autoSaveFileTmp = buildConfigPath("autosave.gpa.tmp"); auto result = paletteFileSave(autoSaveFileTmp.c_str(), args->gs->getColorList()); if (!result) { std::cerr << "failed to save palette to \"" << autoSaveFileTmp << "\": " << result.error() << std::endl; } else { boost::system::error_code error; rename(path(autoSaveFileTmp), path(autoSaveFile), error); if (error) { std::cerr << "failed to move palette file \"" << autoSaveFileTmp << "\" to \"" << autoSaveFile << "\": " << error << std::endl; } } } catch (const interprocess_exception &e) { std::cerr << "failed acquire interprocess lock: " << e.what() << std::endl; } } } color_list_remove_all(args->gs->getColorList()); } static void app_save_recent_file_list(AppArgs *args) { std::vector recentFiles(args->recent_files.begin(), args->recent_files.end()); args->gs->settings().set("gpick.recent.files", recentFiles); } struct FloatingPickerAction { public: AppArgs *args; bool clipboard_touched; FloatingPickerAction(AppArgs *args) { this->args = args; clipboard_touched = false; } void colorPicked(FloatingPicker fp, const Color &color) { string text; if (args->startupOptions.converter_name.length() > 0){ auto converter = args->gs->converters().byName(args->startupOptions.converter_name); if (converter != nullptr){ auto color_object = color_list_new_color_object(args->gs->getColorList(), &color); text = converter->serialize(color_object); color_object->release(); } }else{ auto converter = args->gs->converters().firstCopy(); if (converter != nullptr){ text = converter->serialize(color); } } if (text.length() > 0) { if (args->startupOptions.output_picked_color) { if (args->startupOptions.output_without_newline) { cout << text; }else{ cout << text << endl; } }else{ clipboard::set(text); clipboard_touched = true; } } } static gboolean close_application(gpointer user_data) { gtk_main_quit(); return FALSE; } void done(FloatingPicker fp) { if (clipboard_touched) g_timeout_add(100, close_application, args); // quiting main gtk loop early will not give enough time for clipboard manager to retrieve the clipboard contents else gtk_main_quit(); } }; int app_run(AppArgs *args) { if (args->startupOptions.single_color_pick_mode) { FloatingPickerAction pick_action(args); floating_picker_set_custom_pick_action(args->floating_picker, [&pick_action](FloatingPicker fp, const Color &color){ pick_action.colorPicked(fp, color); }); floating_picker_set_custom_done_action(args->floating_picker, [&pick_action](FloatingPicker fp){ pick_action.done(fp); }); floating_picker_enable_custom_pick_action(args->floating_picker); floating_picker_activate(args->floating_picker, false, true, args->startupOptions.converter_name.c_str()); gtk_main(); app_release(args); }else{ gtk_widget_realize(args->window); if (args->startupOptions.floating_picker_mode || args->options->getBool("start_in_tray", false)){ status_icon_set_visible(args->status_icon, true); }else{ gtk_paned_set_position(GTK_PANED(args->hpaned), args->options->getInt32("paned_position", 0)); gtk_paned_set_position(GTK_PANED(args->vpaned), args->options->getInt32("vertical_paned_position", 0)); main_show_window(args->window, args->options); } if (args->startupOptions.floating_picker_mode) floating_picker_activate(args->floating_picker, false, false, args->startupOptions.converter_name.c_str()); gtk_main(); app_save_recent_file_list(args); args->dbus_control.unownName(); status_icon_destroy(args->status_icon); } args->gs->writeSettings(); delete args->gs; color_source_manager_destroy(args->csm); delete args; return 0; } gpick-gpick-0.2.6/source/uiApp.h000066400000000000000000000044641377073231300164540ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_UI_APP_H_ #define GPICK_UI_APP_H_ #include "dynv/Map.h" #include #include struct GlobalState; struct ColorObject; struct Converters; struct Color; int main_show_window(GtkWidget* window, const dynv::Ref &options); struct AppArgs; struct StartupOptions { bool floating_picker_mode; std::string converter_name; bool output_picked_color; bool output_without_newline; bool single_color_pick_mode; bool do_not_start; }; void app_initialize(); AppArgs* app_create_main(const StartupOptions &options, int &return_value); int app_load_file(AppArgs *args, const std::string &filename, bool autoload = false); int app_run(AppArgs *args); int app_parse_geometry(AppArgs *args, const char *geometry); bool app_is_autoload_enabled(AppArgs *args); #endif /* GPICK_UI_APP_H_ */ gpick-gpick-0.2.6/source/uiColorDictionaries.cpp000066400000000000000000000303751377073231300217030ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "uiColorDictionaries.h" #include "uiUtilities.h" #include "dynv/Map.h" #include "GlobalState.h" #include "color_names/ColorNames.h" #include "I18N.h" #include #include #include #include #include using namespace std; enum class ColorDictionaryList: int { path = 0, built_in, enable, pointer, n_columns }; struct ColorDictionary { ColorDictionary(): built_in(false), enable(false) { } ColorDictionary(const char *path, bool built_in, bool enable): path(path), built_in(built_in), enable(enable) { } string path; bool built_in, enable; size_t index; bool operator==(const ColorDictionary &color_dictionary) const { if (this == &color_dictionary) return true; if (path == color_dictionary.path && built_in == color_dictionary.built_in && enable == color_dictionary.enable) return true; return false; } }; struct ColorDictionarySort { bool operator()(const ColorDictionary &a, const ColorDictionary &b) { return a.index < b.index; } }; struct ColorDictionariesArgs { GtkWidget *dictionary_list, *file_browser; list color_dictionaries; dynv::Ref options; GlobalState *gs; }; static void color_dictionaries_update_row(GtkTreeModel *model, GtkTreeIter *iter1, ColorDictionary *color_dictionary, ColorDictionariesArgs *args) { gtk_list_store_set(GTK_LIST_STORE(model), iter1, ColorDictionaryList::path, color_dictionary->path.c_str(), ColorDictionaryList::enable, color_dictionary->enable, ColorDictionaryList::built_in, color_dictionary->built_in, ColorDictionaryList::pointer, color_dictionary, -1); } static void enable_toggled_cb(GtkCellRendererText *cell, gchar *path, ColorDictionariesArgs *args) { GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(args->dictionary_list))); GtkTreeIter iter1; gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter1, path); ColorDictionary *color_dictionary; gtk_tree_model_get(GTK_TREE_MODEL(store), &iter1, ColorDictionaryList::pointer, &color_dictionary, -1); color_dictionary->enable = !color_dictionary->enable; gtk_list_store_set(store, &iter1, ColorDictionaryList::enable, color_dictionary->enable, -1); } static GtkWidget* color_dictionaries_list_new(ColorDictionariesArgs *args) { GtkCellRenderer *renderer; GtkTreeViewColumn *col; GtkWidget *view = args->dictionary_list = gtk_tree_view_new(); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), true); GtkListStore *store = gtk_list_store_new(static_cast(ColorDictionaryList::n_columns), G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_POINTER); col = gtk_tree_view_column_new(); gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_resizable(col, true); gtk_tree_view_column_set_title(col, _("Path")); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(col, renderer, true); gtk_tree_view_append_column(GTK_TREE_VIEW(view), col); gtk_tree_view_column_add_attribute(col, renderer, "text", static_cast(ColorDictionaryList::path)); col = gtk_tree_view_column_new(); gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_GROW_ONLY); gtk_tree_view_column_set_title(col, _("Enable")); renderer = gtk_cell_renderer_toggle_new(); gtk_tree_view_column_pack_start(col, renderer, false); gtk_tree_view_append_column(GTK_TREE_VIEW(view), col); g_signal_connect(renderer, "toggled", reinterpret_cast(enable_toggled_cb), args); gtk_tree_view_column_set_attributes(col, renderer, "active", ColorDictionaryList::enable, nullptr); gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store)); g_object_unref(GTK_TREE_MODEL(store)); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); gtk_tree_view_set_reorderable(GTK_TREE_VIEW(view), true); return view; } static void add_file(GtkWidget *widget, ColorDictionariesArgs *args) { gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(args->file_browser)); if (filename){ args->color_dictionaries.push_back(ColorDictionary(filename, false, true)); g_free(filename); GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(args->dictionary_list)); GtkTreeIter iter1; gtk_list_store_append(GTK_LIST_STORE(model), &iter1); color_dictionaries_update_row(model, &iter1, &args->color_dictionaries.back(), args); } gchar *current_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(args->file_browser)); if (current_folder){ args->options->set("current_folder", current_folder); g_free(current_folder); } } static void remove_selected(ColorDictionariesArgs *args) { GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(args->dictionary_list))); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(args->dictionary_list)); GtkTreeIter iter1; GList *selected_list = gtk_tree_selection_get_selected_rows(selection, nullptr); list remove_items; { GList *i = selected_list; while (i){ GtkTreeRowReference *row_reference; GtkTreePath *path; bool reference_inserted = false; if ((row_reference = gtk_tree_row_reference_new(GTK_TREE_MODEL(store), (GtkTreePath*) (i->data)))){ if ((path = gtk_tree_row_reference_get_path(row_reference))){ if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter1, path)){ ColorDictionary *dictionary = nullptr; gtk_tree_model_get(GTK_TREE_MODEL(store), &iter1, static_cast(ColorDictionaryList::pointer), &dictionary, -1); if (!dictionary->built_in){ remove_items.push_back(row_reference); reference_inserted = true; args->color_dictionaries.remove(*dictionary); } } gtk_tree_path_free(path); } if (!reference_inserted) gtk_tree_row_reference_free(row_reference); } i = g_list_next(i); } } for (auto i = remove_items.begin(); i != remove_items.end(); i++){ GtkTreePath *path = gtk_tree_row_reference_get_path(*i); if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter1, path)){ gtk_list_store_remove(GTK_LIST_STORE(store), &iter1); } gtk_tree_row_reference_free(*i); } g_list_foreach(selected_list, (GFunc)gtk_tree_path_free, nullptr); g_list_free(selected_list); } static gboolean key_press_event(GtkWidget *widget, GdkEventKey *event, ColorDictionariesArgs *args) { switch (getKeyval(*event, args->gs->latinKeysGroup)) { case GDK_KEY_Delete: remove_selected(args); break; default: return false; break; } return false; } static void reorder(ColorDictionariesArgs *args) { GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(args->dictionary_list)); GtkTreeIter iter1; bool valid = gtk_tree_model_get_iter_first(model, &iter1); size_t index = 0; while (valid){ ColorDictionary *color_dictionary; gtk_tree_model_get(GTK_TREE_MODEL(model), &iter1, ColorDictionaryList::pointer, &color_dictionary, -1); color_dictionary->index = index++; valid = gtk_tree_model_iter_next(model, &iter1); } args->color_dictionaries.sort(ColorDictionarySort()); } void dialog_color_dictionaries_show(GtkWindow* parent, GlobalState* gs) { ColorDictionariesArgs *args = new ColorDictionariesArgs; args->gs = gs; args->options = args->gs->settings().getOrCreateMap("gpick"); GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Color dictionaries"), parent, GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, nullptr); gtk_window_set_default_size(GTK_WINDOW(dialog), args->options->getInt32("color_dictionaries.window.width", -1), args->options->getInt32("color_dictionaries.window.height", -1)); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); GtkWidget* vbox = gtk_vbox_new(false, 5); GtkWidget *list = color_dictionaries_list_new(args); g_signal_connect(G_OBJECT(list), "key_press_event", G_CALLBACK(key_press_event), args); GtkWidget *scrolled = gtk_scrolled_window_new(0, 0); gtk_container_add(GTK_CONTAINER(scrolled), list); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start(GTK_BOX(vbox), scrolled, true, true, 0); gint table_y; GtkWidget* table = gtk_table_new(3, 1, false); gtk_box_pack_start(GTK_BOX(vbox), table, false, false, 0); table_y = 0; GtkWidget *frame = gtk_frame_new(_("Add color dictionary file")); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); gtk_table_attach(GTK_TABLE(table), frame, 0, 1, table_y, table_y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); GtkWidget *widget = args->file_browser = gtk_file_chooser_button_new(_("Color dictionary file"), GTK_FILE_CHOOSER_ACTION_OPEN); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(widget), args->options->getString("current_folder", "").c_str()); gtk_container_add(GTK_CONTAINER(frame), widget); g_signal_connect(G_OBJECT(args->file_browser), "file-set", G_CALLBACK(add_file), args); table_y++; bool built_in_found = false; auto items = args->options->getMaps("color_dictionaries.items"); for (auto item: items) { ColorDictionary dictionary; dictionary.path = item->getString("path", ""); dictionary.enable = item->getBool("enable", false); dictionary.built_in = item->getBool("built_in", false); if (dictionary.built_in) { if (dictionary.path == "built_in_0"){ built_in_found = true; dictionary.path = _("Built in"); }else{ continue; } } args->color_dictionaries.push_back(dictionary); } if (!built_in_found) args->color_dictionaries.push_back(ColorDictionary(_("Built in"), true, true)); GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list)); for (auto &dictionary: args->color_dictionaries){ GtkTreeIter iter1; gtk_list_store_append(GTK_LIST_STORE(model), &iter1); color_dictionaries_update_row(model, &iter1, &dictionary, args); } setDialogContent(dialog, vbox); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { std::vector items; reorder(args); for (auto &dictionary: args->color_dictionaries) { auto item = dynv::Map::create(); if (dictionary.built_in) { item->set("path", "built_in_0"); } else { item->set("path", dictionary.path); } item->set("enable", dictionary.enable); item->set("built_in", dictionary.built_in); items.push_back(item); } args->options->set("color_dictionaries.items", items); color_names_clear(args->gs->getColorNames()); color_names_load(args->gs->getColorNames(), *args->options); } gint width, height; gtk_window_get_size(GTK_WINDOW(dialog), &width, &height); args->options->set("color_dictionaries.window.width", width); args->options->set("color_dictionaries.window.height", height); gtk_widget_destroy(dialog); delete args; } gpick-gpick-0.2.6/source/uiColorDictionaries.h000066400000000000000000000033741377073231300213470ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_UI_COLOR_DICTIONARIES_H_ #define GPICK_UI_COLOR_DICTIONARIES_H_ #include struct GlobalState; void dialog_color_dictionaries_show(GtkWindow* parent, GlobalState* gs); #endif /* GPICK_UI_COLOR_DICTIONARIES_H_ */ gpick-gpick-0.2.6/source/uiColorInput.cpp000066400000000000000000000330531377073231300203610ustar00rootroot00000000000000/* * Copyright (c) 2009-2017, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "uiColorInput.h" #include "Converters.h" #include "Converter.h" #include "dynv/Map.h" #include "uiUtilities.h" #include "GlobalState.h" #include "gtk/ColorWheel.h" #include "I18N.h" #include "gtk/ColorComponent.h" #include "gtk/ColorWidget.h" #include "ColorObject.h" #include "ColorSpaceType.h" #include "color_names/ColorNames.h" #include #include #include using namespace std; struct DialogInputArgs { ColorObject *color_object; GtkWidget *color_widget; GtkWidget *text_input; GtkWidget *rgb_expander, *hsv_expander, *hsl_expander, *cmyk_expander, *xyz_expander, *lab_expander, *lch_expander; GtkWidget *rgb_control, *hsv_control, *hsl_control, *cmyk_control, *xyz_control, *lab_control, *lch_control; dynv::Ref options; GlobalState* gs; }; static void updateComponentText(DialogInputArgs *args, GtkColorComponent *component, const char *type) { Color transformed_color; gtk_color_component_get_transformed_color(component, &transformed_color); lua::Script &script = args->gs->script(); list values = color_space_color_to_text(type, &transformed_color, script, args->gs); const char *text[4] = {0}; int j = 0; for (auto &value: values){ text[j++] = value.c_str(); if (j > 3) break; } gtk_color_component_set_text(component, text); } static void update(DialogInputArgs *args, GtkWidget *except_widget) { auto color = args->color_object->getColor(); gtk_color_set_color(GTK_COLOR(args->color_widget), &color, ""); if (except_widget != args->text_input){ string text = args->gs->converters().serialize(args->color_object, Converters::Type::display); gtk_entry_set_text(GTK_ENTRY(args->text_input), text.c_str()); } if (except_widget != args->hsl_control) gtk_color_component_set_color(GTK_COLOR_COMPONENT(args->hsl_control), &color); if (except_widget != args->hsv_control) gtk_color_component_set_color(GTK_COLOR_COMPONENT(args->hsv_control), &color); if (except_widget != args->rgb_control) gtk_color_component_set_color(GTK_COLOR_COMPONENT(args->rgb_control), &color); if (except_widget != args->cmyk_control) gtk_color_component_set_color(GTK_COLOR_COMPONENT(args->cmyk_control), &color); if (except_widget != args->lab_control) gtk_color_component_set_color(GTK_COLOR_COMPONENT(args->lab_control), &color); if (except_widget != args->lch_control) gtk_color_component_set_color(GTK_COLOR_COMPONENT(args->lch_control), &color); updateComponentText(args, GTK_COLOR_COMPONENT(args->hsl_control), "hsl"); updateComponentText(args, GTK_COLOR_COMPONENT(args->hsv_control), "hsv"); updateComponentText(args, GTK_COLOR_COMPONENT(args->rgb_control), "rgb"); updateComponentText(args, GTK_COLOR_COMPONENT(args->cmyk_control), "cmyk"); updateComponentText(args, GTK_COLOR_COMPONENT(args->lab_control), "lab"); updateComponentText(args, GTK_COLOR_COMPONENT(args->lch_control), "lch"); } static void onComponentChangeValue(GtkWidget *widget, Color *color, DialogInputArgs *args) { args->color_object->setColor(*color); update(args, widget); } static void onComponentInputClicked(GtkWidget *widget, int component_id, DialogInputArgs *args) { dialog_color_component_input_show(GTK_WINDOW(gtk_widget_get_toplevel(widget)), GTK_COLOR_COMPONENT(widget), component_id, args->options->getOrCreateMap("component_edit")); } static void setComponentHandlers(GtkWidget *widget, DialogInputArgs *args) { g_signal_connect(G_OBJECT(widget), "color-changed", G_CALLBACK(onComponentChangeValue), args); g_signal_connect(G_OBJECT(widget), "input-clicked", G_CALLBACK(onComponentInputClicked), args); } static void addComponentEditor(GtkWidget *vbox, const char *label, const char *expand_option, GtkColorComponentComp type, const char **labels, DialogInputArgs *args, GtkWidget *&expander, GtkWidget *&control) { expander = gtk_expander_new(label); gtk_expander_set_expanded(GTK_EXPANDER(expander), args->options->getBool(expand_option, false)); gtk_box_pack_start(GTK_BOX(vbox), expander, false, false, 0); control = gtk_color_component_new(type); gtk_color_component_set_label(GTK_COLOR_COMPONENT(control), labels); setComponentHandlers(control, args); gtk_container_add(GTK_CONTAINER(expander), control); } static void onTextChanged(GtkWidget *entry, DialogInputArgs *args) { ColorObject *color_object; if (args->gs->converters().deserialize((char*)gtk_entry_get_text(GTK_ENTRY(entry)), &color_object)){ args->color_object->setColor(color_object->getColor()); color_object->release(); update(args, entry); } } int dialog_color_input_show(GtkWindow *parent, GlobalState *gs, ColorObject *color_object, ColorObject **new_color_object) { auto args = new DialogInputArgs(); args->gs = gs; args->options = gs->settings().getOrCreateMap("gpick.color_input"); bool new_item = false; if (color_object) { args->color_object = color_object->copy(); } else { new_item = true; args->color_object = new ColorObject(); } GtkWidget *dialog = gtk_dialog_new_with_buttons(new_item ? _("Add color") : _("Edit color"), parent, GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, nullptr); gtk_window_set_default_size(GTK_WINDOW(dialog), args->options->getInt32("window.width", -1), args->options->getInt32("window.height", -1)); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); GtkWidget *vbox = gtk_vbox_new(false, 5); GtkWidget *widget = args->color_widget = gtk_color_new(); gtk_color_set_rounded(GTK_COLOR(widget), true); gtk_color_set_hcenter(GTK_COLOR(widget), true); gtk_color_set_roundness(GTK_COLOR(widget), 5); gtk_widget_set_size_request(widget, 30, 30); if (!new_item) { gtk_color_enable_split(GTK_COLOR(widget), true); gtk_color_set_split_color(GTK_COLOR(widget), &color_object->getColor()); } gtk_box_pack_start(GTK_BOX(vbox), widget, true, true, 0); GtkWidget *hbox = gtk_hbox_new(false, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox, false, false, 0); gtk_box_pack_start(GTK_BOX(hbox), gtk_label_aligned_new(_("Color:"), 0, 0.5, 0, 0), false, false, 0); GtkWidget* entry = args->text_input = gtk_entry_new(); gtk_entry_set_activates_default(GTK_ENTRY(entry), true); gtk_box_pack_start(GTK_BOX(hbox), entry, true, true, 0); gtk_widget_grab_focus(entry); g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(onTextChanged), args); const char *hsv_labels[] = {"H", _("Hue"), "S", _("Saturation"), "V", _("Value"), nullptr}; addComponentEditor(vbox, "HSV", "expander.hsv", GtkColorComponentComp::hsv, hsv_labels, args, args->hsv_expander, args->hsv_control); const char *hsl_labels[] = {"H", _("Hue"), "S", _("Saturation"), "L", _("Lightness"), nullptr}; addComponentEditor(vbox, "HSL", "expander.hsl", GtkColorComponentComp::hsl, hsl_labels, args, args->hsl_expander, args->hsl_control); const char *rgb_labels[] = {"R", _("Red"), "G", _("Green"), "B", _("Blue"), nullptr}; addComponentEditor(vbox, "RGB", "expander.rgb", GtkColorComponentComp::rgb, rgb_labels, args, args->rgb_expander, args->rgb_control); const char *cmyk_labels[] = {"C", _("Cyan"), "M", _("Magenta"), "Y", _("Yellow"), "K", _("Key"), nullptr}; addComponentEditor(vbox, "CMYK", "expander.cmyk", GtkColorComponentComp::cmyk, cmyk_labels, args, args->cmyk_expander, args->cmyk_control); const char *lab_labels[] = {"L", _("Lightness"), "a", "a", "b", "b", nullptr}; addComponentEditor(vbox, "Lab", "expander.lab", GtkColorComponentComp::lab, lab_labels, args, args->lab_expander, args->lab_control); const char *lch_labels[] = {"L", _("Lightness"), "C", "Chroma", "H", "Hue", nullptr}; addComponentEditor(vbox, "LCH", "expander.lch", GtkColorComponentComp::lch, lch_labels, args, args->lch_expander, args->lch_control); if (new_item) { auto text = args->options->getString("text", ""); gtk_entry_set_text(GTK_ENTRY(args->text_input), text.c_str()); } else { update(args, nullptr); } gtk_widget_show_all(vbox); setDialogContent(dialog, vbox); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); int result = -1; if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK){ if (new_item) { string name = color_names_get(args->gs->getColorNames(), &args->color_object->getColor(), args->gs->settings().getBool("gpick.color_names.imprecision_postfix", false)); args->color_object->setName(name); } *new_color_object = args->color_object->reference(); result = 0; } if (new_item) args->options->set("text", gtk_entry_get_text(GTK_ENTRY(entry))); args->options->set("expander.rgb", gtk_expander_get_expanded(GTK_EXPANDER(args->rgb_expander))); args->options->set("expander.hsv", gtk_expander_get_expanded(GTK_EXPANDER(args->hsv_expander))); args->options->set("expander.hsl", gtk_expander_get_expanded(GTK_EXPANDER(args->hsl_expander))); args->options->set("expander.lab", gtk_expander_get_expanded(GTK_EXPANDER(args->lab_expander))); args->options->set("expander.lch", gtk_expander_get_expanded(GTK_EXPANDER(args->lch_expander))); args->options->set("expander.cmyk", gtk_expander_get_expanded(GTK_EXPANDER(args->cmyk_expander))); gint width, height; gtk_window_get_size(GTK_WINDOW(dialog), &width, &height); args->options->set("window.width", width); args->options->set("window.height", height); gtk_widget_destroy(dialog); args->color_object->release(); delete args; return result; } struct ColorPickerComponentEditArgs { GtkWidget* value[4]; GtkColorComponentComp component; int component_id; dynv::Ref options; }; void dialog_color_component_input_show(GtkWindow *parent, GtkColorComponent *color_component, int component_id, dynv::Ref options) { GtkColorComponentComp component = gtk_color_component_get_component(GTK_COLOR_COMPONENT(color_component)); ColorPickerComponentEditArgs *args = new ColorPickerComponentEditArgs; args->options = options; args->component = component; args->component_id = component_id; memset(args->value, 0, sizeof(args->value)); GtkWidget *table; GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Edit"), parent, GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, nullptr); gtk_window_set_default_size(GTK_WINDOW(dialog), args->options->getInt32("window.width", -1), args->options->getInt32("window.height", -1)); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); table = gtk_table_new(2, 2, FALSE); Color raw_color; gtk_color_component_get_raw_color(color_component, &raw_color); const ColorSpaceType *color_space_type = 0; for (uint32_t i = 0; i < color_space_count_types(); i++){ if (color_space_get_types()[i].comp_type == component){ color_space_type = &color_space_get_types()[i]; break; } } if (color_space_type){ for (int i = 0; i < color_space_type->n_items; i++){ gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(color_space_type->items[i].name,0,0,0,0),0,1,i,i+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); args->value[i] = gtk_spin_button_new_with_range(color_space_type->items[i].min_value, color_space_type->items[i].max_value, color_space_type->items[i].step); gtk_entry_set_activates_default(GTK_ENTRY(args->value[i]), true); gtk_spin_button_set_value(GTK_SPIN_BUTTON(args->value[i]), raw_color.ma[i] * color_space_type->items[i].raw_scale); gtk_table_attach(GTK_TABLE(table), args->value[i],1,2,i,i+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); if (i == component_id) gtk_widget_grab_focus(args->value[i]); } } gtk_widget_show_all(table); setDialogContent(dialog, table); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK){ if (color_space_type){ for (int i = 0; i < color_space_type->n_items; i++){ raw_color.ma[i] = gtk_spin_button_get_value(GTK_SPIN_BUTTON(args->value[i])) / color_space_type->items[i].raw_scale; } gtk_color_component_set_raw_color(color_component, &raw_color); } } gint width, height; gtk_window_get_size(GTK_WINDOW(dialog), &width, &height); options->set("window.width", width); options->set("window.height", height); gtk_widget_destroy(dialog); delete args; } gpick-gpick-0.2.6/source/uiColorInput.h000066400000000000000000000037421377073231300200300ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_UI_COLOR_INPUT_H_ #define GPICK_UI_COLOR_INPUT_H_ #include "dynv/Map.h" struct GlobalState; struct ColorObject; struct GtkColorComponent; #include int dialog_color_input_show(GtkWindow *parent, GlobalState *gs, ColorObject *color_object, ColorObject **new_color_object); void dialog_color_component_input_show(GtkWindow *parent, GtkColorComponent *color_component, int component_id, dynv::Ref options); #endif /* GPICK_UI_COLOR_INPUT_H_ */ gpick-gpick-0.2.6/source/uiConverter.cpp000066400000000000000000000304771377073231300202410ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "uiConverter.h" #include "Converters.h" #include "Converter.h" #include "uiUtilities.h" #include "dynv/Map.h" #include "GlobalState.h" #include "I18N.h" #include "ColorObject.h" #include "ColorList.h" #include using namespace std; typedef enum { CONVERTERLIST_LABEL = 0, CONVERTERLIST_EXAMPLE, CONVERTERLIST_CONVERTER_PTR, CONVERTERLIST_COPY, CONVERTERLIST_COPY_ENABLED, CONVERTERLIST_PASTE, CONVERTERLIST_PASTE_ENABLED, CONVERTERLIST_N_COLUMNS }ConverterListColumns; struct ConverterArgs { GtkWidget *list; dynv::Ref options; GlobalState *gs; }; static void converter_update_row(GtkTreeModel *model, GtkTreeIter *iter1, Converter *converter, ConverterArgs *args) { ConverterSerializePosition position(1); Color c; c.rgb.red = 0.75; c.rgb.green = 0.50; c.rgb.blue = 0.25; ColorObject *color_object = color_list_new_color_object(args->gs->getColorList(), &c); color_object->setName(_("Test color")); string text_line = converter->serialize(color_object, position); gtk_list_store_set(GTK_LIST_STORE(model), iter1, CONVERTERLIST_LABEL, converter->label().c_str(), CONVERTERLIST_EXAMPLE, text_line.c_str(), CONVERTERLIST_CONVERTER_PTR, converter, CONVERTERLIST_COPY, converter->copy(), CONVERTERLIST_COPY_ENABLED, converter->hasSerialize(), CONVERTERLIST_PASTE, converter->paste(), CONVERTERLIST_PASTE_ENABLED, converter->hasDeserialize(), -1); color_object->release(); } static void copy_toggled_cb(GtkCellRendererText *cell, gchar *path, ConverterArgs *args) { GtkTreeIter iter1; GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(args->list))); gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter1, path ); gboolean value; gtk_tree_model_get(GTK_TREE_MODEL(store), &iter1, CONVERTERLIST_COPY, &value, -1); gtk_list_store_set(store, &iter1, CONVERTERLIST_COPY, !value, -1); } static void paste_toggled_cb(GtkCellRendererText *cell, gchar *path, ConverterArgs *args) { GtkTreeIter iter1; GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(args->list))); gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter1, path ); gboolean value; gtk_tree_model_get(GTK_TREE_MODEL(store), &iter1, CONVERTERLIST_PASTE, &value, -1); gtk_list_store_set(store, &iter1, CONVERTERLIST_PASTE, !value, -1); } static GtkWidget* converter_dropdown_new(ConverterArgs *args, GtkTreeModel *model) { GtkListStore *store = 0; GtkCellRenderer *renderer; GtkWidget *combo; if (model){ combo = gtk_combo_box_new_with_model(model); }else{ store = gtk_list_store_new (CONVERTERLIST_N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN); combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); } renderer = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, true); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", CONVERTERLIST_LABEL, nullptr); if (store) g_object_unref (store); return combo; } static GtkWidget* converter_list_new(ConverterArgs *args) { GtkListStore *store; GtkCellRenderer *renderer; GtkTreeViewColumn *col; GtkWidget *view = gtk_tree_view_new(); args->list = view; gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view),1); store = gtk_list_store_new (CONVERTERLIST_N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN); col = gtk_tree_view_column_new(); gtk_tree_view_column_set_sizing(col,GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_resizable(col,1); gtk_tree_view_column_set_title(col, _("Function name")); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(col, renderer, TRUE); gtk_tree_view_column_add_attribute(col, renderer, "text", CONVERTERLIST_LABEL); gtk_tree_view_append_column(GTK_TREE_VIEW(view), col); col = gtk_tree_view_column_new(); gtk_tree_view_column_set_sizing(col,GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_resizable(col,1); gtk_tree_view_column_set_title(col, _("Example")); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(col, renderer, TRUE); gtk_tree_view_column_add_attribute(col, renderer, "text", CONVERTERLIST_EXAMPLE); gtk_tree_view_append_column(GTK_TREE_VIEW(view), col); col = gtk_tree_view_column_new(); gtk_tree_view_column_set_sizing(col,GTK_TREE_VIEW_COLUMN_GROW_ONLY); gtk_tree_view_column_set_title(col, _("Copy")); renderer = gtk_cell_renderer_toggle_new(); gtk_tree_view_column_pack_start(col, renderer, false); gtk_tree_view_append_column(GTK_TREE_VIEW(view), col); g_signal_connect(renderer, "toggled", (GCallback) copy_toggled_cb, args); gtk_tree_view_column_set_attributes(col, renderer, "active", CONVERTERLIST_COPY, "activatable", CONVERTERLIST_COPY_ENABLED, (void*)0); col = gtk_tree_view_column_new(); gtk_tree_view_column_set_sizing(col,GTK_TREE_VIEW_COLUMN_GROW_ONLY); gtk_tree_view_column_set_title(col, _("Paste / Edit")); renderer = gtk_cell_renderer_toggle_new(); gtk_tree_view_column_pack_start(col, renderer, false); gtk_tree_view_append_column(GTK_TREE_VIEW(view), col); g_signal_connect(renderer, "toggled", (GCallback) paste_toggled_cb, args); gtk_tree_view_column_set_attributes(col, renderer, "active", CONVERTERLIST_PASTE, "activatable", CONVERTERLIST_PASTE_ENABLED, (void*)0); gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL(store)); g_object_unref (GTK_TREE_MODEL(store)); GtkTreeSelection *selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(view) ); gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); gtk_tree_view_set_reorderable(GTK_TREE_VIEW (view), TRUE); return view; } void dialog_converter_show(GtkWindow *parent, GlobalState *gs) { ConverterArgs *args = new ConverterArgs; args->gs = gs; args->options = args->gs->settings().getOrCreateMap("gpick"); GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Converters"), parent, GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, nullptr); gtk_window_set_default_size(GTK_WINDOW(dialog), args->options->getInt32("converters.window.width", 640), args->options->getInt32("converters.window.height", 400)); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); GtkWidget *vbox = gtk_vbox_new(false, 5); GtkWidget *list = converter_list_new(args); GtkWidget *scrolled = gtk_scrolled_window_new(0, 0); gtk_container_add(GTK_CONTAINER(scrolled), list); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start (GTK_BOX(vbox), scrolled, true, true, 0); gint table_y; GtkWidget* table = gtk_table_new(5, 2, false); gtk_box_pack_start(GTK_BOX(vbox), table, false, false, 0); table_y=0; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Displays:"),0,0.5,0,0), 0, 1, table_y, table_y+1, GtkAttachOptions(GTK_FILL), GTK_FILL, 0, 0); GtkWidget *display = converter_dropdown_new(args, 0); GtkTreeModel *model2=gtk_combo_box_get_model(GTK_COMBO_BOX(display)); gtk_table_attach(GTK_TABLE(table), display, 1, 2, table_y, table_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 0, 0); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Color list:"),0,0.5,0,0), 0, 1, table_y, table_y+1, GtkAttachOptions(GTK_FILL), GTK_FILL, 0, 0); GtkWidget *color_list = converter_dropdown_new(args, model2); gtk_table_attach(GTK_TABLE(table), color_list, 1, 2, table_y, table_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 0, 0); table_y++; GtkTreeIter iter1, iter2; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list)); Converter *display_converter = args->gs->converters().display(); Converter *color_list_converter = args->gs->converters().colorList(); bool display_converter_found = false, color_list_converter_found = false; for (auto &converter: args->gs->converters().all()){ gtk_list_store_append(GTK_LIST_STORE(model), &iter1); converter_update_row(model, &iter1, converter, args); gtk_list_store_append(GTK_LIST_STORE(model2), &iter2); converter_update_row(model2, &iter2, converter, args); if (display_converter == converter){ gtk_combo_box_set_active_iter(GTK_COMBO_BOX(display), &iter2); display_converter_found = true; } if (color_list_converter == converter){ gtk_combo_box_set_active_iter(GTK_COMBO_BOX(color_list), &iter2); color_list_converter_found = true; } } if (!display_converter_found){ gtk_combo_box_set_active(GTK_COMBO_BOX(display), 0); } if (!color_list_converter_found){ gtk_combo_box_set_active(GTK_COMBO_BOX(color_list), 0); } gtk_widget_show_all(vbox); setDialogContent(dialog, vbox); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { GtkTreeIter iter; GtkListStore *store; gboolean valid; Converter *converter; if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(display), &iter2)){ gtk_tree_model_get(GTK_TREE_MODEL(model2), &iter2, CONVERTERLIST_CONVERTER_PTR, &converter, -1); args->gs->converters().display(converter); args->options->set("converters.display", converter->name()); } if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(color_list), &iter2)){ gtk_tree_model_get(GTK_TREE_MODEL(model2), &iter2, CONVERTERLIST_CONVERTER_PTR, &converter, -1); args->gs->converters().colorList(converter); args->options->set("converters.color_list", converter->name()); } store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list))); valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter); size_t count = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), nullptr); if (count > 0) { std::vector names(count); std::vector copyArray(count); std::vector pasteArray(count); size_t i = 0; while (valid) { Converter* converter; gboolean copy, paste; gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, CONVERTERLIST_CONVERTER_PTR, &converter, CONVERTERLIST_COPY, ©, CONVERTERLIST_PASTE, &paste, -1); names[i] = converter->name(); copyArray[i] = copy; pasteArray[i] = paste; converter->copy(copy); converter->paste(paste); valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter); ++i; } args->gs->converters().reorder(names); args->options->set("converters.names", names); args->options->set("converters.copy", copyArray); args->options->set("converters.paste", pasteArray); }else{ args->options->remove("converters.names"); args->options->remove("converters.copy"); args->options->remove("converters.paste"); } args->gs->converters().rebuildCopyPasteArrays(); } gint width, height; gtk_window_get_size(GTK_WINDOW(dialog), &width, &height); args->options->set("converters.window.width", width); args->options->set("converters.window.height", height); gtk_widget_destroy(dialog); delete args; } gpick-gpick-0.2.6/source/uiConverter.h000066400000000000000000000033301377073231300176720ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_UI_CONVERTER_H_ #define GPICK_UI_CONVERTER_H_ #include struct GlobalState; void dialog_converter_show(GtkWindow *parent, GlobalState *gs); #endif /* GPICK_UI_CONVERTER_H_ */ gpick-gpick-0.2.6/source/uiDialogAutonumber.cpp000066400000000000000000000201401377073231300215150ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "uiDialogAutonumber.h" #include "uiListPalette.h" #include "uiUtilities.h" #include "MathUtil.h" #include "dynv/Map.h" #include "GlobalState.h" #include "ColorRYB.h" #include "Noise.h" #include "GenerateScheme.h" #include "I18N.h" #include #include #include using namespace std; typedef struct DialogAutonumberArgs{ GtkWidget *name; GtkWidget *nplaces; GtkWidget *startindex; GtkWidget *toggle_decreasing; GtkWidget *toggle_append; uint32_t selected_count; GtkWidget *sample; dynv::Ref options; GlobalState* gs; }DialogAutonumberArgs; static int default_nplaces(uint32_t selected_count) { uint32_t places = 1; uint32_t ncolors = selected_count; // technically this can be implemented as `places = 1 + (int) (trunc(log (ncolors,10)));` // however I don't know the exact function names, and this has minimal dependencies and acceptable speed. while (ncolors > 10) { ncolors = ncolors / 10; places += 1; } return places; } static void update(GtkWidget *widget, DialogAutonumberArgs *args) { int nplaces = gtk_spin_button_get_value (GTK_SPIN_BUTTON(args->nplaces)); int startindex = gtk_spin_button_get_value (GTK_SPIN_BUTTON(args->startindex)); const char *name = gtk_entry_get_text(GTK_ENTRY(args->name)); stringstream ss; ss << name << "-"; ss.fill('0'); ss.width(nplaces); ss << right << startindex; auto text = ss.str(); gtk_entry_set_text(GTK_ENTRY(args->sample), text.c_str()); args->options->set("name", name); args->options->set("append", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->toggle_append))); args->options->set("decreasing", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->toggle_decreasing))); args->options->set("nplaces", nplaces); args->options->set("startindex", startindex); } static void update_startindex(GtkWidget *widget, DialogAutonumberArgs *args) { int startindex = gtk_spin_button_get_value (GTK_SPIN_BUTTON(args->startindex)); int newindex; gdouble min, max; gtk_spin_button_get_range(GTK_SPIN_BUTTON(args->startindex), &min, &max); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))){ if (startindex == 0){ newindex = args->selected_count; }else{ newindex = args->selected_count + (startindex - 1); } min = args->selected_count; }else{ newindex = (startindex + 1) - args->selected_count; min = 1; } gtk_spin_button_set_range(GTK_SPIN_BUTTON(args->startindex), min, max); gtk_spin_button_set_value(GTK_SPIN_BUTTON(args->startindex), newindex); update(widget, args); } int dialog_autonumber_show(GtkWindow* parent, size_t selected_count, GlobalState* gs) { DialogAutonumberArgs *args = new DialogAutonumberArgs; int return_val; args->gs = gs; args->options = args->gs->settings().getOrCreateMap("gpick.autonumber"); args->selected_count = selected_count; GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Autonumber colors"), parent, GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, nullptr); gtk_window_set_default_size(GTK_WINDOW(dialog), args->options->getInt32("window.width", -1), args->options->getInt32("window.height", -1)); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); gint table_y; GtkWidget *table; table = gtk_table_new(4, 4, FALSE); table_y=0; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Name:"),0,0.5,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); args->name = gtk_entry_new(); auto name = args->options->getString("name", "autonum"); gtk_entry_set_text(GTK_ENTRY(args->name), name.c_str()); g_signal_connect (G_OBJECT (args->name), "changed", G_CALLBACK(update), args); gtk_table_attach(GTK_TABLE(table), args->name,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Decimal places:"),0,0,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); args->nplaces = gtk_spin_button_new_with_range (1, 6, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(args->nplaces), args->options->getInt32("nplaces", default_nplaces (selected_count))); gtk_table_attach(GTK_TABLE(table), args->nplaces,1,4,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); g_signal_connect(G_OBJECT (args->nplaces), "value-changed", G_CALLBACK (update), args); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Starting number:"),0,0,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); args->startindex = gtk_spin_button_new_with_range (1, 0x7fffffff, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(args->startindex), args->options->getInt32("startindex", 1)); gtk_table_attach(GTK_TABLE(table), args->startindex,1,4,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); g_signal_connect(G_OBJECT (args->startindex), "value-changed", G_CALLBACK (update), args); table_y++; args->toggle_decreasing = gtk_check_button_new_with_mnemonic (_("_Decreasing")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(args->toggle_decreasing), args->options->getBool("decreasing", false)); gtk_table_attach(GTK_TABLE(table), args->toggle_decreasing,1,4,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); g_signal_connect (G_OBJECT(args->toggle_decreasing), "toggled", G_CALLBACK (update_startindex), args); table_y++; args->toggle_append = gtk_check_button_new_with_mnemonic (_("_Append")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(args->toggle_append), args->options->getBool("append", false)); gtk_table_attach(GTK_TABLE(table), args->toggle_append,1,4,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); g_signal_connect (G_OBJECT(args->toggle_append), "toggled", G_CALLBACK (update), args); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Sample:"),0,0.5,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GtkAttachOptions(GTK_FILL | GTK_EXPAND),5,5); args->sample = gtk_entry_new(); gtk_editable_set_editable(GTK_EDITABLE(args->sample), false); gtk_widget_set_sensitive(args->sample, false); gtk_table_attach(GTK_TABLE(table), args->sample,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); update(0, args); gtk_widget_show_all(table); setDialogContent(dialog, table); return_val = gtk_dialog_run(GTK_DIALOG(dialog)); gint width, height; gtk_window_get_size(GTK_WINDOW(dialog), &width, &height); args->options->set("window.width", width); args->options->set("window.height", height); gtk_widget_destroy(dialog); delete args; return return_val; } gpick-gpick-0.2.6/source/uiDialogAutonumber.h000066400000000000000000000034071377073231300211710ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_UI_DIALOG_AUTONUMBER_H_ #define GPICK_UI_DIALOG_AUTONUMBER_H_ #include struct GlobalState; int dialog_autonumber_show(GtkWindow* parent, size_t selected_count, GlobalState* gs); #endif /* GPICK_UI_DIALOG_AUTONUMBER_H_ */ gpick-gpick-0.2.6/source/uiDialogGenerate.cpp000066400000000000000000000316231377073231300211360ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "uiDialogGenerate.h" #include "uiListPalette.h" #include "uiUtilities.h" #include "ColorList.h" #include "ColorObject.h" #include "MathUtil.h" #include "dynv/Map.h" #include "GlobalState.h" #include "ToolColorNaming.h" #include "color_names/ColorNames.h" #include "ColorRYB.h" #include "Noise.h" #include "GenerateScheme.h" #include "I18N.h" #include "Random.h" #include #include #include using namespace std; typedef struct DialogGenerateArgs { GtkWidget *gen_type; GtkWidget *wheel_type; GtkWidget *range_colors; GtkWidget *range_chaos; GtkWidget *range_additional_rotation; GtkWidget *range_chaos_seed; GtkWidget *toggle_reverse; ColorList *color_list; ColorList *selected_color_list; ColorList *preview_color_list; dynv::Ref options; GlobalState* gs; }DialogGenerateArgs; typedef struct ColorWheelType { const char *name; void (*hue_to_hsl)(double hue, Color* hsl); void (*rgbhue_to_hue)(double rgbhue, double *hue); }ColorWheelType; struct GenerateColorNameAssigner: public ToolColorNameAssigner { protected: stringstream m_stream; string m_scheme_name; int32_t m_ident; public: GenerateColorNameAssigner(GlobalState *gs): ToolColorNameAssigner(gs) { } void assign(ColorObject *color_object, const Color *color, const int32_t ident, const char *scheme_name) { m_ident = ident; m_scheme_name = scheme_name; ToolColorNameAssigner::assign(color_object, color); } virtual std::string getToolSpecificName(ColorObject *color_object, const Color *color) { m_stream.str(""); m_stream << _("scheme") << " " << m_scheme_name << " #" << m_ident << "[" << color_names_get(m_gs->getColorNames(), color, false) << "]"; return m_stream.str(); } }; static void rgb_hue2hue(double hue, Color* hsl) { hsl->hsl.hue = hue; hsl->hsl.saturation = 1; hsl->hsl.lightness = 0.5; } static void rgb_rgbhue2hue(double rgbhue, double *hue) { *hue = rgbhue; } static void ryb1_hue2hue(double hue, Color* hsl) { Color c; color_rybhue_to_rgb(hue, &c); color_rgb_to_hsl(&c, hsl); } static void ryb1_rgbhue2hue(double rgbhue, double *hue) { color_rgbhue_to_rybhue(rgbhue, hue); } static void ryb2_hue2hue(double hue, Color* hsl) { hsl->hsl.hue = color_rybhue_to_rgbhue_f(hue); hsl->hsl.saturation = 1; hsl->hsl.lightness = 0.5; } static void ryb2_rgbhue2hue(double rgbhue, double *hue) { color_rgbhue_to_rybhue_f(rgbhue, hue); } const ColorWheelType color_wheel_types[] = { {"RGB", rgb_hue2hue, rgb_rgbhue2hue}, {"RYB v1", ryb1_hue2hue, ryb1_rgbhue2hue}, {"RYB v2", ryb2_hue2hue, ryb2_rgbhue2hue}, }; static void calc(DialogGenerateArgs *args, bool preview, int limit) { int32_t type = gtk_combo_box_get_active(GTK_COMBO_BOX(args->gen_type)); int32_t wheel_type = gtk_combo_box_get_active(GTK_COMBO_BOX(args->wheel_type)); int32_t color_count = static_cast(gtk_spin_button_get_value(GTK_SPIN_BUTTON(args->range_colors))); float chaos = gtk_spin_button_get_value(GTK_SPIN_BUTTON(args->range_chaos)); int32_t chaos_seed = static_cast(gtk_spin_button_get_value(GTK_SPIN_BUTTON(args->range_chaos_seed))); bool reverse = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->toggle_reverse)); float additional_rotation = gtk_spin_button_get_value(GTK_SPIN_BUTTON(args->range_additional_rotation)); if (!preview){ args->options->set("type", type); args->options->set("wheel_type", wheel_type); args->options->set("colors", color_count); args->options->set("chaos", chaos); args->options->set("chaos_seed", chaos_seed); args->options->set("reverse", reverse); args->options->set("additional_rotation", additional_rotation); } GenerateColorNameAssigner name_assigner(args->gs); Color r, hsl, hsl_results; double hue; double hue_step; ColorList *color_list; if (preview) color_list = args->preview_color_list; else color_list = args->gs->getColorList(); const ColorWheelType *wheel = &color_wheel_types[wheel_type]; struct Random* random = random_new("SHR3", chaos_seed); const SchemeType *scheme_type; SchemeType static_scheme_type = {_("Static"), 1, 1, {0}}; if (type >= generate_scheme_get_n_scheme_types()){ scheme_type = &static_scheme_type; }else{ scheme_type = generate_scheme_get_scheme_type(type); } for (ColorList::iter i = args->selected_color_list->colors.begin(); i != args->selected_color_list->colors.end(); ++i){ Color in = (*i)->getColor(); color_rgb_to_hsl(&in, &hsl); wheel->rgbhue_to_hue(hsl.hsl.hue, &hue); wheel->hue_to_hsl(hue, &hsl_results); double saturation = hsl.hsl.saturation * 1 / hsl_results.hsl.saturation; double lightness = hsl.hsl.lightness - hsl_results.hsl.lightness; for (int32_t i = 0; i < color_count; i++){ if (preview){ if (limit <= 0){ random_destroy(random); return; } limit--; } wheel->hue_to_hsl(hue, &hsl); hsl.hsl.lightness = clamp_float(hsl.hsl.lightness + lightness, 0, 1); hsl.hsl.saturation = clamp_float(hsl.hsl.saturation * saturation, 0, 1); color_hsl_to_rgb(&hsl, &r); ColorObject *color_object = color_list_new_color_object(color_list, &r); name_assigner.assign(color_object, &r, i, scheme_type->name); color_list_add_color_object(color_list, color_object, 1); color_object->release(); hue_step = (scheme_type->turn[i % scheme_type->turn_types]) / (360.0) + chaos * (random_get_double(random) - 0.5) + additional_rotation / 360.0; if (reverse){ hue = wrap_float(hue - hue_step); }else{ hue = wrap_float(hue + hue_step); } } } random_destroy(random); } static void update(GtkWidget *widget, DialogGenerateArgs *args ){ color_list_remove_all(args->preview_color_list); calc(args, true, 100); } void dialog_generate_show(GtkWindow* parent, ColorList *selected_color_list, GlobalState* gs) { DialogGenerateArgs *args = new DialogGenerateArgs; args->gs = gs; args->options = args->gs->settings().getOrCreateMap("gpick.generate"); GtkWidget *table; GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Generate colors"), parent, GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, nullptr); gtk_window_set_default_size(GTK_WINDOW(dialog), args->options->getInt32("window.width", -1), args->options->getInt32("window.height", -1)); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); gint table_y; table = gtk_table_new(4, 4, FALSE); table_y = 0; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Colors:"),0,0,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); args->range_colors = gtk_spin_button_new_with_range(1, 72, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(args->range_colors), args->options->getInt32("colors", 1)); gtk_table_attach(GTK_TABLE(table), args->range_colors,1,4,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); g_signal_connect(G_OBJECT(args->range_colors), "value-changed", G_CALLBACK(update), args); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Type:"),0,0.5,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); args->gen_type = gtk_combo_box_text_new(); for (uint32_t i = 0; i < generate_scheme_get_n_scheme_types(); i++){ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(args->gen_type), _(generate_scheme_get_scheme_type(i)->name)); } gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(args->gen_type), _("Static")); gtk_combo_box_set_active(GTK_COMBO_BOX(args->gen_type), args->options->getInt32("type", 0)); g_signal_connect(G_OBJECT(args->gen_type), "changed", G_CALLBACK(update), args); gtk_table_attach(GTK_TABLE(table), args->gen_type,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Color wheel:"),0,0.5,0,0),2,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); args->wheel_type = gtk_combo_box_text_new(); for (uint32_t i = 0; i < sizeof(color_wheel_types) / sizeof(ColorWheelType); i++){ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(args->wheel_type), color_wheel_types[i].name); } gtk_combo_box_set_active(GTK_COMBO_BOX(args->wheel_type), args->options->getInt32("wheel_type", 0)); g_signal_connect(G_OBJECT(args->wheel_type), "changed", G_CALLBACK(update), args); gtk_table_attach(GTK_TABLE(table), args->wheel_type,3,4,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,0); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Chaos:"),0,0,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); args->range_chaos = gtk_spin_button_new_with_range(0,1,0.001); gtk_spin_button_set_value(GTK_SPIN_BUTTON(args->range_chaos), args->options->getFloat("chaos", 0)); gtk_table_attach(GTK_TABLE(table), args->range_chaos,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); g_signal_connect(G_OBJECT(args->range_chaos), "value-changed", G_CALLBACK(update), args); gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Seed:"),0,0,0,0),2,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); args->range_chaos_seed = gtk_spin_button_new_with_range(0, 0xFFFF, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(args->range_chaos_seed), args->options->getInt32("chaos_seed", 0)); gtk_table_attach(GTK_TABLE(table), args->range_chaos_seed,3,4,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); g_signal_connect(G_OBJECT(args->range_chaos_seed), "value-changed", G_CALLBACK(update), args); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Rotation:"),0,0,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); args->range_additional_rotation = gtk_spin_button_new_with_range(-360, 360, 0.1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(args->range_additional_rotation), args->options->getFloat("range_additional_rotation", 0)); gtk_table_attach(GTK_TABLE(table), args->range_additional_rotation,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); g_signal_connect(G_OBJECT(args->range_additional_rotation), "value-changed", G_CALLBACK(update), args); table_y++; args->toggle_reverse = gtk_check_button_new_with_mnemonic(_("_Reverse")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(args->toggle_reverse), args->options->getBool("reverse", false)); gtk_table_attach(GTK_TABLE(table), args->toggle_reverse,1,4,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); g_signal_connect(G_OBJECT(args->toggle_reverse), "toggled", G_CALLBACK(update), args); table_y++; GtkWidget* preview_expander; ColorList* preview_color_list = nullptr; gtk_table_attach(GTK_TABLE(table), preview_expander = palette_list_preview_new(gs, true, args->options->getBool("show_preview", true), gs->getColorList(), &preview_color_list), 0, 4, table_y, table_y+1 , GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL | GTK_EXPAND), 5, 5); table_y++; args->selected_color_list = selected_color_list; args->preview_color_list = preview_color_list; update(0, args); gtk_widget_show_all(table); setDialogContent(dialog, table); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) calc(args, false, 0); gint width, height; gtk_window_get_size(GTK_WINDOW(dialog), &width, &height); args->options->set("window.width", width); args->options->set("window.height", height); args->options->set("show_preview", gtk_expander_get_expanded(GTK_EXPANDER(preview_expander))); gtk_widget_destroy(dialog); color_list_destroy(args->preview_color_list); delete args; } gpick-gpick-0.2.6/source/uiDialogGenerate.h000066400000000000000000000034331377073231300206010ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_UI_DIALOG_GENERATE_H_ #define GPICK_UI_DIALOG_GENERATE_H_ #include struct GlobalState; struct ColorList; void dialog_generate_show(GtkWindow* parent, ColorList *selected_color_list, GlobalState* gs); #endif /* GPICK_UI_DIALOG_GENERATE_H_ */ gpick-gpick-0.2.6/source/uiDialogMix.cpp000066400000000000000000000266741377073231300201530ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "uiDialogMix.h" #include "uiListPalette.h" #include "uiUtilities.h" #include "ColorList.h" #include "ColorObject.h" #include "ColorUtils.h" #include "MathUtil.h" #include "dynv/Map.h" #include "GlobalState.h" #include "ToolColorNaming.h" #include "I18N.h" #ifndef _MSC_VER #include #endif #include using namespace std; typedef struct DialogMixArgs{ GtkWidget *mix_type; GtkWidget *mix_steps; GtkWidget *toggle_endpoints; ColorList *selected_color_list; ColorList *preview_color_list; dynv::Ref options; GlobalState* gs; }DialogMixArgs; struct MixColorNameAssigner: public ToolColorNameAssigner { protected: stringstream m_stream; const char *m_color_start; const char *m_color_end; int m_start_percent; int m_end_percent; int m_steps; int m_stage; int m_is_node; public: MixColorNameAssigner(GlobalState *gs): ToolColorNameAssigner(gs) { m_is_node = false; } void setStartName(const char *start_color_name) { m_color_start = start_color_name; } void setEndName(const char *end_color_name) { m_color_end = end_color_name; } void setStepsAndStage(int steps, int stage) { m_steps = steps; m_stage = stage; } void assign(ColorObject *color_object, const Color *color, int step) { m_start_percent = step * 100 / (m_steps - 1); m_end_percent = 100 - (step * 100 / (m_steps - 1)); m_is_node = (((step == 0 || step == m_steps - 1) && m_stage == 0) || (m_stage == 1 && step == m_steps - 1)); ToolColorNameAssigner::assign(color_object, color); } void assign(ColorObject *color_object, const Color *color, const char *item_name) { m_color_start = item_name; m_is_node = false; ToolColorNameAssigner::assign(color_object, color); } virtual std::string getToolSpecificName(ColorObject *color_object, const Color *color) { m_stream.str(""); if (m_is_node){ if (m_end_percent == 100){ m_stream << m_color_end << " " << _("mix node"); }else{ m_stream << m_color_start << " " << _("mix node"); } }else{ m_stream << m_color_start << " " << m_start_percent << " " << _("mix") << " " << m_end_percent << " " << m_color_end; } return m_stream.str(); } }; #define STORE_COLOR() ColorObject *color_object=color_list_new_color_object(color_list, &r); \ float mixfactor = step_i/(float)(steps-1); \ name_assigner.assign(color_object, &r, name_a, name_b, (int)((1.0 - mixfactor)*100), (int)(mixfactor*100), with_endpoints && (step_i == 0 || step_i == (max_step - 1))); \ color_list_add_color_object(color_list, color_object, 1); \ color_object->release() #define STORE_LINEARCOLOR() color_linear_get_rgb(&r, &r); \ STORE_COLOR() static void store(ColorList *color_list, const Color *color, int step, MixColorNameAssigner &name_assigner) { ColorObject *color_object = color_list_new_color_object(color_list, color); name_assigner.assign(color_object, color, step); color_list_add_color_object(color_list, color_object, 1); color_object->release(); } static void calc( DialogMixArgs *args, bool preview, int limit) { gint steps=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(args->mix_steps)); gint type=gtk_combo_box_get_active(GTK_COMBO_BOX(args->mix_type)); bool with_endpoints=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->toggle_endpoints)); gint start_step = 0; gint max_step = steps; MixColorNameAssigner name_assigner(args->gs); if (!preview){ args->options->set("type", type); args->options->set("steps", steps); args->options->set("includeendpoints", with_endpoints); } if (with_endpoints == false){ start_step = 1; max_step = steps - 1; } Color r; gint step_i; stringstream s; s.precision(0); s.setf(ios::fixed,ios::floatfield); Color a ,b; ColorList *color_list; if (preview) color_list = args->preview_color_list; else color_list = args->gs->getColorList(); ColorList::iter j; for (ColorList::iter i=args->selected_color_list->colors.begin(); i != args->selected_color_list->colors.end(); ++i){ a = (*i)->getColor(); if (type == 0) color_rgb_get_linear(&a, &a); name_assigner.setStartName((*i)->getName().c_str()); j = i; ++j; for (; j != args->selected_color_list->colors.end(); ++j){ if (preview){ if (limit <= 0) return; limit--; } b = (*j)->getColor(); if (type == 0) color_rgb_get_linear(&b, &b); name_assigner.setEndName((*j)->getName().c_str()); name_assigner.setStepsAndStage(steps, 0); switch (type){ case 0: for (step_i = start_step; step_i < max_step; ++step_i) { color_utils::mix(a, b, step_i / (float)(steps - 1), r); color_linear_get_rgb(&r, &r); store(color_list, &r, step_i, name_assigner); } break; case 1: { Color a_hsv, b_hsv, r_hsv; color_rgb_to_hsv(&a, &a_hsv); color_rgb_to_hsv(&b, &b_hsv); if (a_hsv.hsv.hue>b_hsv.hsv.hue){ if (a_hsv.hsv.hue-b_hsv.hsv.hue>0.5) a_hsv.hsv.hue-=1; }else{ if (b_hsv.hsv.hue-a_hsv.hsv.hue>0.5) b_hsv.hsv.hue-=1; } for (step_i = start_step; step_i < max_step; ++step_i) { color_utils::mix(a_hsv, b_hsv, step_i / (float)(steps - 1), r_hsv); if (r_hsv.hsv.hue < 0) r_hsv.hsv.hue += 1; color_hsv_to_rgb(&r_hsv, &r); store(color_list, &r, step_i, name_assigner); } } break; case 2: { Color a_lab, b_lab, r_lab; color_rgb_to_lab_d50(&a, &a_lab); color_rgb_to_lab_d50(&b, &b_lab); for (step_i = start_step; step_i < max_step; ++step_i) { color_utils::mix(a_lab, b_lab, step_i / (float)(steps - 1), r_lab); color_lab_to_rgb_d50(&r_lab, &r); color_rgb_normalize(&r); store(color_list, &r, step_i, name_assigner); } } break; case 3: { Color a_lch, b_lch, r_lch; color_rgb_to_lch_d50(&a, &a_lch); color_rgb_to_lch_d50(&b, &b_lch); if (a_lch.lch.h>b_lch.lch.h){ if (a_lch.lch.h-b_lch.lch.h>180) a_lch.lch.h-=360; }else{ if (b_lch.lch.h-a_lch.lch.h>180) b_lch.lch.h-=360; } for (step_i = start_step; step_i < max_step; ++step_i) { color_utils::mix(a_lch, b_lch, step_i / (float)(steps - 1), r_lch); if (r_lch.lch.h < 0) r_lch.lch.h += 360; color_lch_to_rgb_d50(&r_lch, &r); color_rgb_normalize(&r); store(color_list, &r, step_i, name_assigner); } } break; } } } } static void update(GtkWidget *widget, DialogMixArgs *args ){ color_list_remove_all(args->preview_color_list); calc(args, true, 100); } void dialog_mix_show(GtkWindow* parent, ColorList *selected_color_list, GlobalState* gs) { DialogMixArgs *args = new DialogMixArgs; args->gs = gs; args->options = args->gs->settings().getOrCreateMap("gpick.mix"); GtkWidget *table; GtkWidget *mix_type, *mix_steps; GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Mix colors"), parent, GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, nullptr); gtk_window_set_default_size(GTK_WINDOW(dialog), args->options->getInt32("window.width", -1), args->options->getInt32("window.height", -1)); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); gint table_y; table = gtk_table_new(3, 2, FALSE); table_y=0; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Type:"),0,0,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); mix_type = gtk_combo_box_text_new(); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(mix_type), _("RGB")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(mix_type), _("HSV")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(mix_type), _("LAB")); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(mix_type), _("LCH")); gtk_combo_box_set_active(GTK_COMBO_BOX(mix_type), args->options->getInt32("type", 0)); gtk_table_attach(GTK_TABLE(table), mix_type,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); table_y++; args->mix_type = mix_type; g_signal_connect(G_OBJECT(mix_type), "changed", G_CALLBACK (update), args); gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Steps:"),0,0,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); mix_steps = gtk_spin_button_new_with_range (3,255,1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(mix_steps), args->options->getInt32("steps", 3)); gtk_table_attach(GTK_TABLE(table), mix_steps,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); table_y++; args->mix_steps = mix_steps; g_signal_connect (G_OBJECT (mix_steps), "value-changed", G_CALLBACK (update), args); args->toggle_endpoints = gtk_check_button_new_with_mnemonic (_("_Include Endpoints")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(args->toggle_endpoints), args->options->getBool("includeendpoints", true)); gtk_table_attach(GTK_TABLE(table), args->toggle_endpoints,1,4,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); g_signal_connect (G_OBJECT(args->toggle_endpoints), "toggled", G_CALLBACK (update), args); table_y++; GtkWidget* preview_expander; ColorList* preview_color_list=nullptr; gtk_table_attach(GTK_TABLE(table), preview_expander = palette_list_preview_new(gs, true, args->options->getBool("show_preview", true), gs->getColorList(), &preview_color_list), 0, 2, table_y, table_y+1 , GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL | GTK_EXPAND), 5, 5); table_y++; args->selected_color_list = selected_color_list; args->preview_color_list = preview_color_list; update(0, args); gtk_widget_show_all(table); setDialogContent(dialog, table); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) calc(args, false, 0); gint width, height; gtk_window_get_size(GTK_WINDOW(dialog), &width, &height); args->options->set("window.width", width); args->options->set("window.height", height); args->options->set("show_preview", gtk_expander_get_expanded(GTK_EXPANDER(preview_expander))); gtk_widget_destroy(dialog); color_list_destroy(args->preview_color_list); delete args; } gpick-gpick-0.2.6/source/uiDialogMix.h000066400000000000000000000034111377073231300176000ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_UI_DIALOG_MIX_H_ #define GPICK_UI_DIALOG_MIX_H_ struct GlobalState; struct ColorList; #include void dialog_mix_show(GtkWindow* parent, ColorList *selected_color_list, GlobalState* gs); #endif /* GPICK_UI_DIALOG_MIX_H_ */ gpick-gpick-0.2.6/source/uiDialogOptions.cpp000066400000000000000000000602261377073231300210400ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "uiDialogOptions.h" #include "uiUtilities.h" #include "ToolColorNaming.h" #include "GlobalState.h" #include "I18N.h" #include "dynv/Map.h" #include "lua/Script.h" #include "lua/DynvSystem.h" #include "lua/Callbacks.h" #include #include using namespace std; extern "C"{ #include #include } static const struct{ const char *label; const char *setting; }available_color_spaces[] = { {"CMYK", "picker.color_space.cmyk"}, {"HSL", "picker.color_space.hsl"}, {"HSV", "picker.color_space.hsv"}, {"LAB", "picker.color_space.lab"}, {"LCH", "picker.color_space.lch"}, {"RGB", "picker.color_space.rgb"}, {0, 0}, }; typedef struct DialogOptionsArgs{ GtkWidget *minimize_to_tray; GtkWidget *close_to_tray; GtkWidget *start_in_tray; GtkWidget *refresh_rate; GtkWidget *single_instance; GtkWidget *default_drag_action[2]; GtkWidget *hex_case[2]; GtkWidget *save_restore_palette; GtkWidget *always_use_floating_picker; GtkWidget *hide_cursor; GtkWidget *add_on_release; GtkWidget *add_to_palette; GtkWidget *copy_to_clipboard; GtkWidget *rotate_swatch; GtkWidget *copy_on_release; GtkWidget *zoom_size; GtkWidget *imprecision_postfix; GtkWidget *tool_color_naming[3]; GtkWidget *color_spaces[6]; GtkWidget *out_of_gamut_mask; GtkWidget *lab_illuminant; GtkWidget *lab_observer; GtkWidget *add_to_swatch_on_release; GtkWidget *rotate_swatch_on_release; dynv::Ref options; GlobalState* gs; }DialogOptionsArgs; bool dialog_options_update(GlobalState *gs) { if (!gs->callbacks().optionChange().valid()) return false; lua_State* L = gs->script(); int stack_top = lua_gettop(L); gs->callbacks().optionChange().get(); lua::pushDynvSystem(L, &gs->settings()); int status = lua_pcall(L, 1, 0, 0); if (status == 0){ lua_settop(L, stack_top); return true; }else{ cerr << "optionsUpdate: " << lua_tostring(L, -1) << endl; } lua_settop(L, stack_top); return false; } static void calc( DialogOptionsArgs *args, bool preview, int limit) { if (preview) return; auto &options = args->options; options->set("main.minimize_to_tray", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->minimize_to_tray))); options->set("main.close_to_tray", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->close_to_tray))); options->set("main.start_in_tray", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->start_in_tray))); options->set("main.single_instance", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->single_instance))); options->set("main.save_restore_palette", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->save_restore_palette))); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->default_drag_action[0]))) options->set("main.dragging_moves", true); else options->set("main.dragging_moves", false); if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->hex_case[0]))) options->set("options.hex_case", "lower"); else options->set("options.hex_case", "upper"); options->set("picker.refresh_rate", gtk_spin_button_get_value(GTK_SPIN_BUTTON(args->refresh_rate))); options->set("picker.zoom_size", gtk_spin_button_get_value(GTK_SPIN_BUTTON(args->zoom_size))); options->set("picker.always_use_floating_picker", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->always_use_floating_picker))); options->set("picker.hide_cursor", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->hide_cursor))); options->set("picker.sampler.add_on_release", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->add_on_release))); options->set("picker.sampler.copy_on_release", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->copy_on_release))); options->set("picker.sampler.add_to_swatch_on_release", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->add_to_swatch_on_release))); options->set("picker.sampler.rotate_swatch_on_release", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->rotate_swatch_on_release))); options->set("picker.sampler.add_to_palette", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->add_to_palette))); options->set("picker.sampler.copy_to_clipboard", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->copy_to_clipboard))); options->set("picker.sampler.rotate_swatch_after_sample", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->rotate_swatch))); options->set("picker.out_of_gamut_mask", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->out_of_gamut_mask))); options->set("color_names.imprecision_postfix", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->imprecision_postfix))); const ToolColorNamingOption *color_naming_options = tool_color_naming_get_options(); int i = 0; while (color_naming_options[i].name){ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->tool_color_naming[i]))){ options->set("color_names.tool_color_naming", color_naming_options[i].name); break; } i++; } for (int i = 0; available_color_spaces[i].label; i++){ options->set(available_color_spaces[i].setting, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->color_spaces[i]))); } options->set("picker.lab.illuminant", gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(args->lab_illuminant))); options->set("picker.lab.observer", gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(args->lab_observer))); } void dialog_options_show(GtkWindow* parent, GlobalState* gs) { DialogOptionsArgs *args = new DialogOptionsArgs; args->gs = gs; args->options = args->gs->settings().getOrCreateMap("gpick"); GtkWidget *table, *table_m, *widget; GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Options"), parent, GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, nullptr); gtk_window_set_default_size(GTK_WINDOW(dialog), args->options->getInt32("options.window.width", -1), args->options->getInt32("options.window.height", -1)); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); GtkWidget *frame; GtkWidget* notebook = gtk_notebook_new(); gint table_y, table_m_y; table_m = gtk_table_new(3, 1, FALSE); table_m_y = 0; frame = gtk_frame_new(_("System")); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); gtk_table_attach(GTK_TABLE(table_m), frame, 0, 1, table_m_y, table_m_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); table_m_y++; table = gtk_table_new(5, 3, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(frame), table); args->single_instance = widget = gtk_check_button_new_with_mnemonic (_("_Single instance")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool("main.single_instance", false)); gtk_table_attach(GTK_TABLE(table), widget,0,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; args->save_restore_palette = widget = gtk_check_button_new_with_mnemonic (_("Save/_Restore palette")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool("main.save_restore_palette", true)); gtk_table_attach(GTK_TABLE(table), widget,0,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; frame = gtk_frame_new(_("System tray")); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); gtk_table_attach(GTK_TABLE(table_m), frame, 0, 1, table_m_y, table_m_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); table_m_y++; table = gtk_table_new(5, 3, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(frame), table); args->minimize_to_tray = widget = gtk_check_button_new_with_mnemonic (_("_Minimize to system tray")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool("main.minimize_to_tray", false)); gtk_table_attach(GTK_TABLE(table), widget,0,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; args->close_to_tray = widget = gtk_check_button_new_with_mnemonic (_("_Close to system tray")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool("main.close_to_tray", false)); gtk_table_attach(GTK_TABLE(table), widget,0,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; args->start_in_tray = widget = gtk_check_button_new_with_mnemonic (_("_Start in system tray")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool("main.start_in_tray", false)); gtk_table_attach(GTK_TABLE(table), widget,0,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; frame = gtk_frame_new(_("Default drag action")); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); gtk_table_attach(GTK_TABLE(table_m), frame, 0, 1, table_m_y, table_m_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); table_m_y++; table = gtk_table_new(5, 3, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(frame), table); GSList *group = nullptr; bool dragging_moves = args->options->getBool("main.dragging_moves", true); args->default_drag_action[0] = widget = gtk_radio_button_new_with_mnemonic(group, _("M_ove")); group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(widget)); if (dragging_moves) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), true); gtk_table_attach(GTK_TABLE(table), widget,0,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; args->default_drag_action[1] = widget = gtk_radio_button_new_with_mnemonic(group, _("Cop_y")); group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(widget)); if (dragging_moves == false) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), true); gtk_table_attach(GTK_TABLE(table), widget,0,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; table_m_y = 0; frame = gtk_frame_new(_("Hex format")); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); gtk_table_attach(GTK_TABLE(table_m), frame, 1, 2, table_m_y, table_m_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); table_m_y++; table = gtk_table_new(1, 1, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(frame), table); group = nullptr; string hex_format = args->options->getString("options.hex_case", "upper"); args->hex_case[0] = widget = gtk_radio_button_new_with_mnemonic(group, _("Lower case")); group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(widget)); if (hex_format == "lower") gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), true); gtk_table_attach(GTK_TABLE(table), widget,0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; args->hex_case[1] = widget = gtk_radio_button_new_with_mnemonic(group, _("Upper case")); group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(widget)); if (hex_format == "upper") gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), true); gtk_table_attach(GTK_TABLE(table), widget,0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table_m, gtk_label_new_with_mnemonic(_("_Main"))); table_m = gtk_table_new(3, 2, FALSE); table_m_y = 0; frame = gtk_frame_new(_("Display")); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); gtk_table_attach(GTK_TABLE(table_m), frame, 0, 1, table_m_y, table_m_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); table_m_y++; table = gtk_table_new(5, 3, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(frame), table); gtk_table_attach(GTK_TABLE(table), gtk_label_mnemonic_aligned_new(_("_Refresh rate:"),0,0.5,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); args->refresh_rate = widget = gtk_spin_button_new_with_range(1, 60, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(args->refresh_rate), args->options->getInt32("picker.refresh_rate", 30)); gtk_table_attach(GTK_TABLE(table), widget,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,5); gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new("Hz",0,0.5,0,0),2,3,table_y,table_y+1,GTK_FILL,GTK_FILL,5,5); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_mnemonic_aligned_new(_("_Magnified area size:"),0,0.5,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); args->zoom_size = widget = gtk_spin_button_new_with_range(75, 300, 15); gtk_spin_button_set_value(GTK_SPIN_BUTTON(args->zoom_size), args->options->getInt32("picker.zoom_size", 150)); gtk_table_attach(GTK_TABLE(table), widget,1,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,5); table_y++; frame = gtk_frame_new(_("Picker")); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); gtk_table_attach(GTK_TABLE(table_m), frame, 0, 1, table_m_y, table_m_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); table_m_y++; table = gtk_table_new(5, 3, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(frame), table); args->always_use_floating_picker = widget = gtk_check_button_new_with_mnemonic(_("_Always use floating picker")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool("picker.always_use_floating_picker", true)); gtk_table_attach(GTK_TABLE(table), widget,0,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; args->hide_cursor = widget = gtk_check_button_new_with_mnemonic(_("_Hide cursor")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool("picker.hide_cursor", false)); gtk_table_attach(GTK_TABLE(table), widget,0,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; frame = gtk_frame_new(_("Floating picker click behaviour")); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); gtk_table_attach(GTK_TABLE(table_m), frame, 0, 1, table_m_y, table_m_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); table_m_y++; table = gtk_table_new(5, 3, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(frame), table); args->add_on_release = widget = gtk_check_button_new_with_mnemonic(_("_Add to palette")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool("picker.sampler.add_on_release", true)); gtk_table_attach(GTK_TABLE(table), widget,0,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; args->copy_on_release = widget = gtk_check_button_new_with_mnemonic(_("_Copy to clipboard")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool("picker.sampler.copy_on_release", true)); gtk_table_attach(GTK_TABLE(table), widget,0,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; args->add_to_swatch_on_release = widget = gtk_check_button_new_with_mnemonic(_("A_dd to swatch")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool("picker.sampler.add_to_swatch_on_release", true)); gtk_table_attach(GTK_TABLE(table), widget,0,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; args->rotate_swatch_on_release = widget = gtk_check_button_new_with_mnemonic(_("R_otate swatch")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool("picker.sampler.rotate_swatch_on_release", true)); gtk_table_attach(GTK_TABLE(table), widget,0,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; frame = gtk_frame_new(_("'Spacebar' button behaviour")); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); gtk_table_attach(GTK_TABLE(table_m), frame, 0, 1, table_m_y, table_m_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); table_m_y++; table = gtk_table_new(5, 3, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(frame), table); args->add_to_palette = widget = gtk_check_button_new_with_mnemonic(_("_Add to palette")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool("picker.sampler.add_to_palette", true)); gtk_table_attach(GTK_TABLE(table), widget,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; args->copy_to_clipboard = widget = gtk_check_button_new_with_mnemonic(_("_Copy to clipboard")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool("picker.sampler.copy_to_clipboard", true)); gtk_table_attach(GTK_TABLE(table), widget,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; args->rotate_swatch = widget = gtk_check_button_new_with_mnemonic(_("_Rotate swatch")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool("picker.sampler.rotate_swatch_after_sample", true)); gtk_table_attach(GTK_TABLE(table), widget,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; table_m_y = 0; frame = gtk_frame_new(_("Enabled color spaces")); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); gtk_table_attach(GTK_TABLE(table_m), frame, 1, 2, table_m_y, table_m_y+2, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); table_m_y+=2; table = gtk_table_new(5, 3, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(frame), table); for (int i = 0; available_color_spaces[i].label; i++){ args->color_spaces[i] = widget = gtk_check_button_new_with_label(available_color_spaces[i].label); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool(available_color_spaces[i].setting, true)); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 3, 3); table_y++; } frame = gtk_frame_new(_("Lab settings")); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); gtk_table_attach(GTK_TABLE(table_m), frame, 1, 2, table_m_y, table_m_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); table_m_y++; table = gtk_table_new(5, 3, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(frame), table); { int selected; gtk_table_attach(GTK_TABLE(table), gtk_label_mnemonic_aligned_new(_("_Illuminant:"),0,0.5,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); args->lab_illuminant = widget = gtk_combo_box_text_new(); const char *illuminants[] = { "A", "C", "D50", "D55", "D65", "D75", "F2", "F7", "F11", 0, }; selected = 0; auto option = args->options->getString("picker.lab.illuminant", "D50"); for (int i = 0; illuminants[i]; i++){ if (illuminants[i] == option) selected = i; gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), illuminants[i]); } gtk_combo_box_set_active(GTK_COMBO_BOX(widget), selected); gtk_table_attach(GTK_TABLE(table), widget,1,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,5); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_mnemonic_aligned_new(_("_Observer:"),0,0.5,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); args->lab_observer = widget = gtk_combo_box_text_new(); const char *observers[] = { "2", "10", 0, }; selected = 0; option = args->options->getString("picker.lab.observer", "2"); for (int i = 0; observers[i]; i++){ if (observers[i] == option) selected = i; gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), observers[i]); } gtk_combo_box_set_active(GTK_COMBO_BOX(widget), selected); gtk_table_attach(GTK_TABLE(table), widget,1,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,5); table_y++; } frame = gtk_frame_new(_("Other settings")); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); gtk_table_attach(GTK_TABLE(table_m), frame, 1, 2, table_m_y, table_m_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); table_m_y++; table = gtk_table_new(5, 3, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(frame), table); args->out_of_gamut_mask = widget = gtk_check_button_new_with_mnemonic(_("_Mask out of gamut colors")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool("picker.out_of_gamut_mask", true)); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, table_y, table_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GTK_FILL, 3, 3); table_y++; gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table_m, gtk_label_new_with_mnemonic(_("_Picker"))); table_m = gtk_table_new(3, 1, FALSE); table_m_y = 0; frame = gtk_frame_new(_("Color name generation")); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); gtk_table_attach(GTK_TABLE(table_m), frame, 0, 1, table_m_y, table_m_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); table_m_y++; table = gtk_table_new(5, 3, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(frame), table); args->imprecision_postfix = widget = gtk_check_button_new_with_mnemonic(_("_Imprecision postfix")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool("color_names.imprecision_postfix", false)); gtk_table_attach(GTK_TABLE(table), widget,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; frame = gtk_frame_new(_("Tool color naming")); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); gtk_table_attach(GTK_TABLE(table_m), frame, 0, 1, table_m_y, table_m_y+1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 5, 5); table_m_y++; table = gtk_table_new(5, 3, FALSE); table_y=0; gtk_container_add(GTK_CONTAINER(frame), table); group = nullptr; ToolColorNamingType color_naming_type = tool_color_naming_name_to_type(args->options->getString("color_names.tool_color_naming", "automatic_name")); const ToolColorNamingOption *color_naming_options = tool_color_naming_get_options(); int i = 0; while (color_naming_options[i].name){ args->tool_color_naming[i] = widget = gtk_radio_button_new_with_mnemonic(group, _(color_naming_options[i].label)); group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(widget)); if (color_naming_type == color_naming_options[i].type) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), true); gtk_table_attach(GTK_TABLE(table), widget,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,3,3); table_y++; i++; } gtk_notebook_append_page(GTK_NOTEBOOK(notebook), table_m, gtk_label_new_with_mnemonic(_("_Color names"))); gtk_widget_show_all(notebook); setDialogContent(dialog, notebook); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { calc(args, false, 0); dialog_options_update(args->gs); } gint width, height; gtk_window_get_size(GTK_WINDOW(dialog), &width, &height); args->options->set("options.window.width", width); args->options->set("options.window.height", height); gtk_widget_destroy(dialog); delete args; } gpick-gpick-0.2.6/source/uiDialogOptions.h000066400000000000000000000034221377073231300205000ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_UI_DIALOG_OPTIONS_H_ #define GPICK_UI_DIALOG_OPTIONS_H_ #include struct GlobalState; void dialog_options_show(GtkWindow* parent, GlobalState* gs); bool dialog_options_update(GlobalState* gs); #endif /* GPICK_UI_DIALOG_OPTIONS_H_ */ gpick-gpick-0.2.6/source/uiDialogSort.cpp000066400000000000000000000472751377073231300203450ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "uiDialogSort.h" #include "uiListPalette.h" #include "uiUtilities.h" #include "ColorList.h" #include "ColorObject.h" #include "MathUtil.h" #include "dynv/Map.h" #include "GlobalState.h" #include "ColorRYB.h" #include "Noise.h" #include "GenerateScheme.h" #include "I18N.h" #include #include #include #include #include #include using namespace std; typedef struct DialogSortArgs{ GtkWidget *group_type; GtkWidget *group_sensitivity; GtkWidget *max_groups; GtkWidget *sort_type; GtkWidget *toggle_reverse; GtkWidget *toggle_reverse_groups; ColorList *sorted_color_list; ColorList *selected_color_list; ColorList *preview_color_list; dynv::Ref options; GlobalState* gs; }DialogSortArgs; typedef struct SortType{ const char *name; double (*get_value)(Color *color); }SortType; typedef struct GroupType{ const char *name; double (*get_group)(Color *color); }GroupType; static double sort_rgb_red(Color *color) { return color->rgb.red; } static double sort_rgb_green(Color *color) { return color->rgb.green; } static double sort_rgb_blue(Color *color) { return color->rgb.blue; } static double sort_rgb_grayscale(Color *color) { return (color->rgb.red + color->rgb.green + color->rgb.blue) / 3.0; } static double sort_hsl_hue(Color *color) { Color hsl; color_rgb_to_hsl(color, &hsl); return hsl.hsl.hue; } static double sort_hsl_saturation(Color *color) { Color hsl; color_rgb_to_hsl(color, &hsl); return hsl.hsl.saturation; } static double sort_hsl_lightness(Color *color) { Color hsl; color_rgb_to_hsl(color, &hsl); return hsl.hsl.lightness; } static double sort_lab_lightness(Color *color) { Color lab; color_rgb_to_lab_d50(color, &lab); return lab.lab.L; } static double sort_lab_a(Color *color) { Color lab; color_rgb_to_lab_d50(color, &lab); return lab.lab.a; } static double sort_lab_b(Color *color) { Color lab; color_rgb_to_lab_d50(color, &lab); return lab.lab.b; } static double sort_lch_lightness(Color *color) { Color lch; color_rgb_to_lch_d50(color, &lch); return lch.lch.L; } static double sort_lch_chroma(Color *color) { Color lch; color_rgb_to_lch_d50(color, &lch); return lch.lch.C; } static double sort_lch_hue(Color *color) { Color lch; color_rgb_to_lch_d50(color, &lch); return lch.lch.h; } const SortType sort_types[] = { {N_("RGB Red"), sort_rgb_red}, {N_("RGB Green"), sort_rgb_green}, {N_("RGB Blue"), sort_rgb_blue}, {N_("RGB Grayscale"), sort_rgb_grayscale}, {N_("HSL Hue"), sort_hsl_hue}, {N_("HSL Saturation"), sort_hsl_saturation}, {N_("HSL Lightness"), sort_hsl_lightness}, {N_("Lab Lightness"), sort_lab_lightness}, {N_("Lab A"), sort_lab_a}, {N_("Lab B"), sort_lab_b}, {N_("LCh Lightness"), sort_lch_lightness}, {N_("LCh Chroma"), sort_lch_chroma}, {N_("LCh Hue"), sort_lch_hue}, }; static double group_rgb_red(Color *color) { return color->rgb.red; } static double group_rgb_green(Color *color) { return color->rgb.green; } static double group_rgb_blue(Color *color) { return color->rgb.blue; } static double group_rgb_grayscale(Color *color) { return (color->rgb.red + color->rgb.green + color->rgb.blue) / 3.0; } static double group_hsl_hue(Color *color) { Color hsl; color_rgb_to_hsl(color, &hsl); return hsl.hsl.hue; } static double group_hsl_saturation(Color *color) { Color hsl; color_rgb_to_hsl(color, &hsl); return hsl.hsl.saturation; } static double group_hsl_lightness(Color *color) { Color hsl; color_rgb_to_hsl(color, &hsl); return hsl.hsl.lightness; } static double group_lab_lightness(Color *color) { Color lab; color_rgb_to_lab_d50(color, &lab); return lab.lab.L / 100.0; } static double group_lab_a(Color *color) { Color lab; color_rgb_to_lab_d50(color, &lab); return (lab.lab.a + 145) / 290.0; } static double group_lab_b(Color *color) { Color lab; color_rgb_to_lab_d50(color, &lab); return (lab.lab.b + 145) / 290.0; } static double group_lch_lightness(Color *color) { Color lch; color_rgb_to_lch_d50(color, &lch); return lch.lch.L / 100.0; } static double group_lch_chroma(Color *color) { Color lch; color_rgb_to_lch_d50(color, &lch); return lch.lch.C / 136.0; } static double group_lch_hue(Color *color) { Color lch; color_rgb_to_lch_d50(color, &lch); return lch.lch.h / 360.0; } const GroupType group_types[] = { {N_("None"), nullptr}, {N_("RGB Red"), group_rgb_red}, {N_("RGB Green"), group_rgb_green}, {N_("RGB Blue"), group_rgb_blue}, {N_("RGB Grayscale"), group_rgb_grayscale}, {N_("HSL Hue"), group_hsl_hue}, {N_("HSL Saturation"), group_hsl_saturation}, {N_("HSL Lightness"), group_hsl_lightness}, {N_("Lab Lightness"), group_lab_lightness}, {N_("Lab A"), group_lab_a}, {N_("Lab B"), group_lab_b}, {N_("LCh Lightness"), group_lch_lightness}, {N_("LCh Chroma"), group_lch_chroma}, {N_("LCh Hue"), group_lch_hue}, }; typedef struct Node{ uint32_t n_values; uint32_t n_values_in; double value_sum; double distance; Node *child[2]; Node *parent; }Node; typedef struct Range{ double x; double w; }Range; static Node* node_new(Node *parent){ Node *n = new Node; n->value_sum = 0; n->distance = 0; n->n_values = 0; n->n_values_in = 0; n->parent = parent; for (int i = 0; i < 2; i++){ n->child[i] = 0; } return n; } static void node_delete(Node *node){ for (int i = 0; i < 2; i++){ if (node->child[i]){ node_delete(node->child[i]); } } delete node; } static Node* node_copy(Node *node, Node *parent){ Node *n = node_new(0); memcpy(n, node, sizeof(Node)); n->parent = parent; for (int i = 0; i < 2; i++){ if (node->child[i]){ n->child[i] = node_copy(node->child[i], n); }else{ n->child[i] = 0; } } return n; } static uint32_t node_count_leafs(Node *node){ uint32_t r = 0; if (node->n_values_in) r++; for (int i = 0; i < 2; i++){ if (node->child[i]) r += node_count_leafs(node->child[i]); } return r; } static void node_leaf_callback(Node *node, void (*leaf_cb)(Node* node, void* userdata), void* userdata){ if (node->n_values_in > 0) leaf_cb(node, userdata); for (int i = 0; i < 2; i++){ if (node->child[i]) node_leaf_callback(node->child[i], leaf_cb, userdata); } } static void node_prune(Node *node){ for (int i = 0; i < 2; i++){ if (node->child[i]){ node_prune(node->child[i]); node->child[i] = 0; } } if (node->parent){ node->parent->n_values_in += node->n_values_in; node->parent->value_sum += node->value_sum; } node_delete(node); } typedef struct PruneData{ double threshold; double min_distance; uint32_t n_values; uint32_t n_values_target; Node *prune_node; uint32_t distant_nodes; }PruneData; static bool node_prune_threshold(Node *node, PruneData *prune_data, bool leave_node){ if (node->distance <= prune_data->threshold){ uint32_t values_removed; if (leave_node){ values_removed = 0; for (int i = 0; i < 2; i++){ if (node->child[i]){ values_removed += node_count_leafs(node->child[i]); node_prune(node->child[i]); node->child[i] = 0; } } }else{ values_removed = node_count_leafs(node); node_prune(node); } prune_data->n_values -= values_removed; return true; } if (node->distance < prune_data->min_distance){ prune_data->min_distance = node->distance; } uint32_t n = node->n_values_in; for (int i = 0; i < 2; i++){ if (node->child[i]){ if (node_prune_threshold(node->child[i], prune_data, false)){ node->child[i] = 0; } } } if (node->n_values_in > 0 && n == 0) prune_data->n_values++; return false; } static void node_reduce(Node *node, double threshold, uintptr_t max_values){ PruneData prune_data; prune_data.n_values = node_count_leafs(node); prune_data.n_values_target = max_values; prune_data.threshold = threshold; prune_data.min_distance = node->distance; node_prune_threshold(node, &prune_data, true); prune_data.threshold = prune_data.min_distance; while (prune_data.n_values > max_values){ prune_data.min_distance = node->distance; if (node_prune_threshold(node, &prune_data, true)) break; prune_data.threshold = prune_data.min_distance; } } static Node* node_find(Node *node, Range *range, double value) { Range new_range; new_range.w = range->w / 2; int x; if (value - range->x < new_range.w) x = 0; else x = 1; new_range.x = range->x + new_range.w * x; if (node->child[x]){ return node_find(node->child[x], &new_range, value); }else return node; } static void node_update(Node *node, Range *range, double value, uint32_t max_depth){ Range new_range; new_range.w = range->w / 2; node->n_values++; node->distance += (value - (range->x + new_range.w)) * (value - (range->x + new_range.w)); if (!max_depth){ node->n_values_in++; node->value_sum += value; }else{ int x; if (value - range->x < new_range.w) x = 0; else x = 1; new_range.x = range->x + new_range.w * x; if (!node->child[x]) node->child[x] = node_new(node); node->n_values++; node_update(node->child[x], &new_range, value, max_depth - 1); } } static void calc(DialogSortArgs *args, bool preview, int limit){ int32_t group_type = gtk_combo_box_get_active(GTK_COMBO_BOX(args->group_type)); float group_sensitivity = gtk_spin_button_get_value(GTK_SPIN_BUTTON(args->group_sensitivity)); int max_groups = gtk_spin_button_get_value(GTK_SPIN_BUTTON(args->max_groups)); int32_t sort_type = gtk_combo_box_get_active(GTK_COMBO_BOX(args->sort_type)); bool reverse = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->toggle_reverse)); bool reverse_groups = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->toggle_reverse_groups)); if (!preview){ args->options->set("group_type", group_type); args->options->set("group_sensitivity", group_sensitivity); args->options->set("max_groups", max_groups); args->options->set("sort_type", sort_type); args->options->set("reverse", reverse); args->options->set("reverse_groups", reverse_groups); } ColorList *color_list; if (preview) color_list = args->preview_color_list; else color_list = args->sorted_color_list; typedef std::multimap SortedColors; typedef std::map GroupedSortedColors; GroupedSortedColors grouped_sorted_colors; typedef std::multimap SortedGroups; SortedGroups sorted_groups; const GroupType *group = &group_types[group_type]; const SortType *sort = &sort_types[sort_type]; Color in; Node *group_nodes = node_new(0); Range range; range.x = 0; range.w = 1; int tmp_limit = limit; if (group->get_group){ for (ColorList::iter i = args->selected_color_list->colors.begin(); i != args->selected_color_list->colors.end(); ++i){ in = (*i)->getColor(); node_update(group_nodes, &range, group->get_group(&in), 8); if (preview){ if (tmp_limit <= 0) break; tmp_limit--; } } } node_reduce(group_nodes, group_sensitivity / 100.0, max_groups); tmp_limit = limit; for (ColorList::iter i = args->selected_color_list->colors.begin(); i != args->selected_color_list->colors.end(); ++i){ in = (*i)->getColor(); uintptr_t node_ptr = 0; if (group->get_group){ node_ptr = reinterpret_cast(node_find(group_nodes, &range, group->get_group(&in))); } grouped_sorted_colors[node_ptr].insert(std::pair(sort->get_value(&in), *i)); if (preview){ if (tmp_limit <= 0) break; tmp_limit--; } } node_delete(group_nodes); for (GroupedSortedColors::iterator i = grouped_sorted_colors.begin(); i != grouped_sorted_colors.end(); ++i){ in = (*(*i).second.begin()).second->getColor(); sorted_groups.insert(std::pair(sort->get_value(&in), (*i).first)); } if (reverse_groups){ for (SortedGroups::reverse_iterator i = sorted_groups.rbegin(); i != sorted_groups.rend(); ++i){ GroupedSortedColors::iterator a, b; a = grouped_sorted_colors.lower_bound((*i).second); b = grouped_sorted_colors.upper_bound((*i).second); for (GroupedSortedColors::iterator j = a; j != b; ++j){ if (reverse){ for (SortedColors::reverse_iterator k = (*j).second.rbegin(); k != (*j).second.rend(); ++k){ color_list_add_color_object(color_list, (*k).second, true); } }else{ for (SortedColors::iterator k = (*j).second.begin(); k != (*j).second.end(); ++k){ color_list_add_color_object(color_list, (*k).second, true); } } } } }else{ for (SortedGroups::iterator i = sorted_groups.begin(); i != sorted_groups.end(); ++i){ GroupedSortedColors::iterator a, b; a = grouped_sorted_colors.lower_bound((*i).second); b = grouped_sorted_colors.upper_bound((*i).second); for (GroupedSortedColors::iterator j = a; j != b; ++j){ if (reverse){ for (SortedColors::reverse_iterator k = (*j).second.rbegin(); k != (*j).second.rend(); ++k){ color_list_add_color_object(color_list, (*k).second, true); } }else{ for (SortedColors::iterator k = (*j).second.begin(); k != (*j).second.end(); ++k){ color_list_add_color_object(color_list, (*k).second, true); } } } } } } static void update(GtkWidget *widget, DialogSortArgs *args ){ color_list_remove_all(args->preview_color_list); calc(args, true, 100); } bool dialog_sort_show(GtkWindow* parent, ColorList *selected_color_list, ColorList *sorted_color_list, GlobalState* gs) { DialogSortArgs *args = new DialogSortArgs; args->gs = gs; args->options = args->gs->settings().getOrCreateMap("gpick.group_and_sort"); args->sorted_color_list = sorted_color_list; GtkWidget *table; GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Group and sort"), parent, GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, nullptr); gtk_window_set_default_size(GTK_WINDOW(dialog), args->options->getInt32("window.width", -1), args->options->getInt32("window.height", -1)); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); gint table_y; table = gtk_table_new(4, 4, FALSE); table_y = 0; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Group type:"),0,0.5,0,0),2,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); args->group_type = gtk_combo_box_text_new(); for (uint32_t i = 0; i < sizeof(group_types) / sizeof(GroupType); i++){ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(args->group_type), _(group_types[i].name)); } gtk_combo_box_set_active(GTK_COMBO_BOX(args->group_type), args->options->getInt32("group_type", 0)); g_signal_connect(G_OBJECT(args->group_type), "changed", G_CALLBACK(update), args); gtk_table_attach(GTK_TABLE(table), args->group_type,3,4,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Grouping sensitivity:"),0,0,0,0),2,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); args->group_sensitivity = gtk_spin_button_new_with_range(0, 100, 0.01); gtk_spin_button_set_value(GTK_SPIN_BUTTON(args->group_sensitivity), args->options->getFloat("group_sensitivity", 50)); gtk_table_attach(GTK_TABLE(table), args->group_sensitivity,3,4,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); g_signal_connect(G_OBJECT(args->group_sensitivity), "value-changed", G_CALLBACK(update), args); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Maximum number of groups:"),0,0,0,0),2,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); args->max_groups = gtk_spin_button_new_with_range(1, 255, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(args->max_groups), args->options->getInt32("max_groups", 10)); gtk_table_attach(GTK_TABLE(table), args->max_groups,3,4,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); g_signal_connect(G_OBJECT(args->max_groups), "value-changed", G_CALLBACK(update), args); table_y++; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Sort type:"),0,0.5,0,0),2,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); args->sort_type = gtk_combo_box_text_new(); for (uint32_t i = 0; i < sizeof(sort_types) / sizeof(SortType); i++){ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(args->sort_type), _(sort_types[i].name)); } gtk_combo_box_set_active(GTK_COMBO_BOX(args->sort_type), args->options->getInt32("sort_type", 0)); g_signal_connect (G_OBJECT (args->sort_type), "changed", G_CALLBACK(update), args); gtk_table_attach(GTK_TABLE(table), args->sort_type,3,4,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); table_y++; args->toggle_reverse_groups = gtk_check_button_new_with_mnemonic(_("_Reverse group order")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(args->toggle_reverse_groups), args->options->getBool("reverse_groups", false)); gtk_table_attach(GTK_TABLE(table), args->toggle_reverse_groups,1,4,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); g_signal_connect (G_OBJECT(args->toggle_reverse_groups), "toggled", G_CALLBACK(update), args); table_y++; args->toggle_reverse = gtk_check_button_new_with_mnemonic(_("_Reverse order inside groups")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(args->toggle_reverse), args->options->getBool("reverse", false)); gtk_table_attach(GTK_TABLE(table), args->toggle_reverse,1,4,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); g_signal_connect (G_OBJECT(args->toggle_reverse), "toggled", G_CALLBACK(update), args); table_y++; GtkWidget* preview_expander; ColorList* preview_color_list = nullptr; gtk_table_attach(GTK_TABLE(table), preview_expander = palette_list_preview_new(gs, true, args->options->getBool("show_preview", true), gs->getColorList(), &preview_color_list), 0, 4, table_y, table_y + 1 , GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL | GTK_EXPAND), 5, 5); table_y++; args->selected_color_list = selected_color_list; args->preview_color_list = preview_color_list; update(0, args); gtk_widget_show_all(table); setDialogContent(dialog, table); bool retval = false; if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK){ calc(args, false, 0); retval = true; } gint width, height; gtk_window_get_size(GTK_WINDOW(dialog), &width, &height); args->options->set("window.width", width); args->options->set("window.height", height); args->options->set("show_preview", gtk_expander_get_expanded(GTK_EXPANDER(preview_expander))); gtk_widget_destroy(dialog); color_list_destroy(args->preview_color_list); delete args; return retval; } gpick-gpick-0.2.6/source/uiDialogSort.h000066400000000000000000000034511377073231300177760ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_UI_DIALOG_SORT_H_ #define GPICK_UI_DIALOG_SORT_H_ #include struct GlobalState; struct ColorList; bool dialog_sort_show(GtkWindow* parent, ColorList *selected_color_list, ColorList *sorted_color_list, GlobalState* gs); #endif /* GPICK_UI_DIALOG_SORT_H_ */ gpick-gpick-0.2.6/source/uiDialogVariations.cpp000066400000000000000000000265151377073231300215270ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "uiDialogVariations.h" #include "uiListPalette.h" #include "uiUtilities.h" #include "ColorList.h" #include "ColorObject.h" #include "MathUtil.h" #include "dynv/Map.h" #include "GlobalState.h" #include "ToolColorNaming.h" #include "I18N.h" #include using namespace std; typedef struct DialogVariationsArgs { GtkWidget *toggle_multiplication, *toggle_linearization; GtkWidget *range_lightness_from, *range_lightness_to, *range_steps; GtkWidget *range_saturation_from, *range_saturation_to; ColorList *selected_color_list; ColorList *preview_color_list; dynv::Ref options; GlobalState* gs; }DialogVariationsArgs; struct VariationsColorNameAssigner: public ToolColorNameAssigner { protected: stringstream m_stream; const char *m_name; uint32_t m_step_i; public: VariationsColorNameAssigner(GlobalState *gs): ToolColorNameAssigner(gs) { } void assign(ColorObject *color_object, const Color *color, const char *name, uint32_t step_i) { m_name = name; m_step_i = step_i; ToolColorNameAssigner::assign(color_object, color); } virtual std::string getToolSpecificName(ColorObject *color_object, const Color *color) { m_stream.str(""); m_stream << m_name << " " << _("variation") << " " << m_step_i; return m_stream.str(); } }; static void calc(DialogVariationsArgs *args, bool preview, int limit) { gint steps = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(args->range_steps)); float lightness_from = gtk_spin_button_get_value(GTK_SPIN_BUTTON(args->range_lightness_from)); float lightness_to = gtk_spin_button_get_value(GTK_SPIN_BUTTON(args->range_lightness_to)); float saturation_from = gtk_spin_button_get_value(GTK_SPIN_BUTTON(args->range_saturation_from)); float saturation_to = gtk_spin_button_get_value(GTK_SPIN_BUTTON(args->range_saturation_to)); bool multiplication = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->toggle_multiplication)); bool linearization = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->toggle_linearization)); if (!preview){ args->options->set("steps", steps); args->options->set("lightness_from", lightness_from); args->options->set("lightness_to", lightness_to); args->options->set("saturation_from", saturation_from); args->options->set("saturation_to", saturation_to); args->options->set("multiplication", multiplication); args->options->set("linearization", linearization); } Color r, hsl; gint step_i; ColorList *color_list; if (preview) color_list = args->preview_color_list; else color_list = args->gs->getColorList(); VariationsColorNameAssigner name_assigner(args->gs); for (ColorList::iter i = args->selected_color_list->colors.begin(); i != args->selected_color_list->colors.end(); ++i){ Color in = (*i)->getColor(); const char* name = (*i)->getName().c_str(); if (linearization) color_rgb_get_linear(&in, &in); for (step_i = 0; step_i < steps; ++step_i) { if (preview){ if (limit <= 0) return; limit--; } color_rgb_to_hsl(&in, &hsl); if (steps == 1){ if (multiplication){ hsl.hsl.saturation *= mix_float(saturation_from, saturation_to, 0); hsl.hsl.lightness *= mix_float(lightness_from, lightness_to, 0); }else{ hsl.hsl.saturation += mix_float(saturation_from, saturation_to, 0); hsl.hsl.lightness += mix_float(lightness_from, lightness_to, 0); } }else{ if (multiplication){ hsl.hsl.saturation *= mix_float(saturation_from, saturation_to, (step_i / (float) (steps - 1))); hsl.hsl.lightness *= mix_float(lightness_from, lightness_to, (step_i / (float) (steps - 1))); }else{ hsl.hsl.saturation += mix_float(saturation_from, saturation_to, (step_i / (float) (steps - 1))); hsl.hsl.lightness += mix_float(lightness_from, lightness_to, (step_i / (float) (steps - 1))); } } hsl.hsl.saturation = clamp_float(hsl.hsl.saturation, 0, 1); hsl.hsl.lightness = clamp_float(hsl.hsl.lightness, 0, 1); color_hsl_to_rgb(&hsl, &r); if (linearization) color_linear_get_rgb(&r, &r); ColorObject *color_object = color_list_new_color_object(color_list, &r); name_assigner.assign(color_object, &r, name, step_i); color_list_add_color_object(color_list, color_object, 1); color_object->release(); } } } static void update(GtkWidget *widget, DialogVariationsArgs *args) { color_list_remove_all(args->preview_color_list); calc(args, true, 100); } void dialog_variations_show(GtkWindow* parent, ColorList *selected_color_list, GlobalState* gs) { DialogVariationsArgs *args = new DialogVariationsArgs; args->gs = gs; args->options = args->gs->settings().getOrCreateMap("gpick.variations"); GtkWidget *table, *toggle_multiplication; GtkWidget *range_lightness_from, *range_lightness_to, *range_steps; GtkWidget *range_saturation_from, *range_saturation_to; GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Variations"), parent, GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, nullptr); gtk_window_set_default_size(GTK_WINDOW(dialog), args->options->getInt32("window.width", -1), args->options->getInt32("window.height", -1)); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); gint table_y; table = gtk_table_new(5, 3, FALSE); table_y = 0; gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Lightness:"),0,0,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); range_lightness_from = gtk_spin_button_new_with_range(-100,100,0.001); gtk_spin_button_set_value(GTK_SPIN_BUTTON(range_lightness_from), args->options->getFloat("lightness_from", 1)); gtk_table_attach(GTK_TABLE(table), range_lightness_from,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); args->range_lightness_from = range_lightness_from; g_signal_connect(G_OBJECT(range_lightness_from), "value-changed", G_CALLBACK(update), args); range_lightness_to = gtk_spin_button_new_with_range(-100,100,0.001); gtk_spin_button_set_value(GTK_SPIN_BUTTON(range_lightness_to), args->options->getFloat("lightness_to", 1)); gtk_table_attach(GTK_TABLE(table), range_lightness_to,2,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); table_y++; args->range_lightness_to = range_lightness_to; g_signal_connect(G_OBJECT(range_lightness_to), "value-changed", G_CALLBACK(update), args); gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Saturation:"),0,0,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); range_saturation_from = gtk_spin_button_new_with_range(-100,100,0.001); gtk_spin_button_set_value(GTK_SPIN_BUTTON(range_saturation_from), args->options->getFloat("saturation_from", 0)); gtk_table_attach(GTK_TABLE(table), range_saturation_from,1,2,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); args->range_saturation_from = range_saturation_from; g_signal_connect(G_OBJECT(range_saturation_from), "value-changed", G_CALLBACK(update), args); range_saturation_to = gtk_spin_button_new_with_range(-100,100,0.001); gtk_spin_button_set_value(GTK_SPIN_BUTTON(range_saturation_to), args->options->getFloat("saturation_to", 1)); gtk_table_attach(GTK_TABLE(table), range_saturation_to,2,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); table_y++; args->range_saturation_to = range_saturation_to; g_signal_connect(G_OBJECT(range_saturation_to), "value-changed", G_CALLBACK(update), args); gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(_("Steps:"),0,0,0,0),0,1,table_y,table_y+1,GtkAttachOptions(GTK_FILL),GTK_FILL,5,5); range_steps = gtk_spin_button_new_with_range(1, 255, 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(range_steps), args->options->getInt32("steps", 3)); gtk_table_attach(GTK_TABLE(table), range_steps,1,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); table_y++; args->range_steps = range_steps; g_signal_connect(G_OBJECT(range_steps), "value-changed", G_CALLBACK(update), args); toggle_multiplication = gtk_check_button_new_with_mnemonic(_("_Use multiplication")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle_multiplication), args->options->getBool("multiplication", true)); gtk_table_attach(GTK_TABLE(table), toggle_multiplication,1,3,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); table_y++; args->toggle_multiplication = toggle_multiplication; g_signal_connect(G_OBJECT(toggle_multiplication), "toggled", G_CALLBACK(update), args); args->toggle_linearization = gtk_check_button_new_with_mnemonic(_("_Linearization")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(args->toggle_linearization), args->options->getBool("linearization", false)); gtk_table_attach(GTK_TABLE(table), args->toggle_linearization,1,4,table_y,table_y+1,GtkAttachOptions(GTK_FILL | GTK_EXPAND),GTK_FILL,5,0); g_signal_connect(G_OBJECT(args->toggle_linearization), "toggled", G_CALLBACK(update), args); table_y++; GtkWidget* preview_expander; ColorList* preview_color_list = nullptr; gtk_table_attach(GTK_TABLE(table), preview_expander = palette_list_preview_new(gs, true, args->options->getBool("show_preview", true), gs->getColorList(), &preview_color_list), 0, 3, table_y, table_y+1 , GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL | GTK_EXPAND), 5, 5); table_y++; args->selected_color_list = selected_color_list; args->preview_color_list = preview_color_list; update(0, args); gtk_widget_show_all(table); setDialogContent(dialog, table); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) calc(args, false, 0); gint width, height; gtk_window_get_size(GTK_WINDOW(dialog), &width, &height); args->options->set("window.width", width); args->options->set("window.height", height); args->options->set("show_preview", gtk_expander_get_expanded(GTK_EXPANDER(preview_expander))); gtk_widget_destroy(dialog); color_list_destroy(args->preview_color_list); delete args; } gpick-gpick-0.2.6/source/uiDialogVariations.h000066400000000000000000000034431377073231300211670ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_UI_DIALOG_VARIATIONS_H_ #define GPICK_UI_DIALOG_VARIATIONS_H_ #include struct GlobalState; struct ColorList; void dialog_variations_show(GtkWindow* parent, ColorList *selected_color_list, GlobalState *gs); #endif /* GPICK_UI_DIALOG_VARIATIONS_H_ */ gpick-gpick-0.2.6/source/uiImportExport.cpp000066400000000000000000000563661377073231300207530ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "uiImportExport.h" #include "uiUtilities.h" #include "uiListPalette.h" #include "dynv/Map.h" #include "ImportExport.h" #include "StringUtils.h" #include "ColorList.h" #include "Converters.h" #include "Converter.h" #include "GlobalState.h" #include "I18N.h" #include "parser/TextFile.h" #include #include using namespace std; struct ImportExportFormat { const char *name; const char *pattern; FileType type; }; struct ListOption { const char *name; const char *label; }; struct ImportExportDialogOptions { enum class Options { import, import_text_file, }; Options m_options; GtkWidget *m_dialog; GtkWidget *m_converters, *m_item_sizes, *m_backgrounds, *m_include_color_names; GtkWidget *m_single_line_c_comments, *m_multi_line_c_comments, *m_single_line_hash_comments, *m_css_rgb, *m_css_rgba, *m_short_hex, *m_full_hex, *m_float_values, *m_int_values; GlobalState *m_gs; ImportExportDialogOptions(GtkWidget *dialog, GlobalState *gs) { m_dialog = dialog; m_gs = gs; } void createImportOptions() { m_options = Options::import; m_converters = newConverterList(); g_signal_connect(G_OBJECT(m_dialog), "notify::filter", G_CALLBACK(filterChanged), this); GtkTreeIter iter; GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(m_converters)); bool converter_found = false; string converter_name = m_gs->settings().getString("gpick.import.converter", ""); for (auto &converter: m_gs->converters().all()){ gtk_list_store_append(GTK_LIST_STORE(model), &iter); gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, converter->label().c_str(), 1, converter, -1); if (converter->name() == converter_name){ gtk_combo_box_set_active_iter(GTK_COMBO_BOX(m_converters), &iter); converter_found = true; } } if (!converter_found){ gtk_combo_box_set_active(GTK_COMBO_BOX(m_converters), 0); } const ListOption item_size_options[] = { {"small", _("Small")}, {"medium", _("Medium")}, {"big", _("Big")}, {"controllable", _("User controllable")}, }; m_item_sizes = newOptionList(item_size_options, sizeof(item_size_options) / sizeof(ListOption), m_gs->settings().getString("gpick.import.item_size", "medium")); const ListOption background_options[] = { {"none", _("None")}, {"white", _("White")}, {"gray", _("Gray")}, {"black", _("Black")}, {"first_color", _("First color")}, {"last_color", _("Last color")}, {"controllable", _("User controllable")}, }; m_backgrounds = newOptionList(background_options, sizeof(background_options) / sizeof(ListOption), m_gs->settings().getString("gpick.import.background", "none")); m_include_color_names = newCheckbox(_("Include color names"), m_gs->settings().getBool("gpick.import.include_color_names", true)); afterFilterChanged(); int y = 0; GtkWidget *table = gtk_table_new(2, 3, false); addOption(_("Converter:"), m_converters, 0, y, table); addOption(_("Item size:"), m_item_sizes, 0, y, table); addOption(_("Background:"), m_backgrounds, 0, y, table); addOption(m_include_color_names, 0, y, table); gtk_widget_show_all(table); gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(m_dialog), table); } void createImportTextFileOptions() { m_options = Options::import_text_file; int y = 0; GtkWidget *table = gtk_table_new(2, 3, false); addOption(m_single_line_c_comments = newCheckbox(string(_("C style single-line comments")) + " (//abc)", m_gs->settings().getBool("gpick.import_text_file.single_line_c_comments", true)), 0, y, table); addOption(m_multi_line_c_comments = newCheckbox(string(_("C style multi-line comments")) + " (/*abc*/)", m_gs->settings().getBool("gpick.import_text_file.multi_line_c_comments", true)), 0, y, table); addOption(m_single_line_hash_comments = newCheckbox(string(_("Hash single-line comments")) + " (#abc)", m_gs->settings().getBool("gpick.import_text_file.single_line_hash_comments", true)), 0, y, table); y = 0; addOption(m_css_rgb = newCheckbox("CSS rgb()", m_gs->settings().getBool("gpick.import_text_file.css_rgb", true)), 1, y, table); addOption(m_css_rgba = newCheckbox("CSS rgba()", m_gs->settings().getBool("gpick.import_text_file.css_rgba", true)), 1, y, table); addOption(m_full_hex = newCheckbox(_("Full hex"), m_gs->settings().getBool("gpick.import_text_file.full_hex", true)), 1, y, table); y = 0; addOption(m_short_hex = newCheckbox(_("Short hex"), m_gs->settings().getBool("gpick.import_text_file.short_hex", true)), 2, y, table); addOption(m_int_values = newCheckbox(_("Integer values"), m_gs->settings().getBool("gpick.import_text_file.int_values", true)), 2, y, table); addOption(m_float_values = newCheckbox(_("Real values"), m_gs->settings().getBool("gpick.import_text_file.float_values", true)), 2, y, table); gtk_widget_show_all(table); gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(m_dialog), table); } GtkWidget *addOption(const char *label, GtkWidget *widget, int x, int &y, GtkWidget *table) { gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(label, 0, 0.5, 0, 0), x * 3, x * 3 + 1, y, y + 1, GTK_FILL, GTK_FILL, 3, 1); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, y, y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 3, 1); y++; return widget; } GtkWidget *addOption(GtkWidget *widget, int x, int &y, GtkWidget *table) { gtk_table_attach(GTK_TABLE(table), widget, x * 3 + 1, x * 3 + 2, y, y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 3, 1); y++; return widget; } Converter *getSelectedConverter() { GtkTreeIter iter; if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(m_converters), &iter)){ GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(m_converters)); Converter *converter; gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 1, &converter, -1); return converter; } return nullptr; } string getOptionValue(GtkWidget *widget) { GtkTreeIter iter; if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter)){ GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget)); gchar *value; gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 1, &value, -1); string result(value); g_free(value); return result; } return string(); } string getSelectedItemSize() { return getOptionValue(m_item_sizes); } string getSelectedBackground() { return getOptionValue(m_backgrounds); } bool isIncludeColorNamesEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_include_color_names)); } bool isSingleLineCCommentsEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_single_line_c_comments)); } bool isMultiLineCCommentsEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_multi_line_c_comments)); } bool isSingleLineHashCommentsEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_single_line_hash_comments)); } bool isCssRgbEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_css_rgb)); } bool isCssRgbaEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_css_rgba)); } bool isFullHexEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_full_hex)); } bool isShortHexEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_short_hex)); } bool isIntValuesEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_int_values)); } bool isFloatValuesEnabled() { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_float_values)); } void saveState() { auto &settings = m_gs->settings(); if (m_options == Options::import){ Converter *converter = getSelectedConverter(); if (converter) settings.set("gpick.import.converter", converter->name().c_str()); string item_size = getSelectedItemSize(); settings.set("gpick.import.item_size", item_size.c_str()); string background = getSelectedBackground(); settings.set("gpick.import.background", background.c_str()); settings.set("gpick.import.include_color_names", isIncludeColorNamesEnabled()); }else if (m_options == Options::import_text_file){ settings.set("gpick.import_text_file.single_line_c_comments", isSingleLineCCommentsEnabled()); settings.set("gpick.import_text_file.multi_line_c_comments", isMultiLineCCommentsEnabled()); settings.set("gpick.import_text_file.single_line_hash_comments", isSingleLineHashCommentsEnabled()); settings.set("gpick.import_text_file.css_rgb", isCssRgbEnabled()); settings.set("gpick.import_text_file.css_rgba", isCssRgbaEnabled()); settings.set("gpick.import_text_file.full_hex", isFullHexEnabled()); settings.set("gpick.import_text_file.short_hex", isShortHexEnabled()); settings.set("gpick.import_text_file.int_values", isIntValuesEnabled()); settings.set("gpick.import_text_file.float_values", isFloatValuesEnabled()); } } GtkWidget* newConverterList() { GtkListStore *store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER); GtkWidget *list = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(list), renderer, true); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(list), renderer, "text", 0, nullptr); if (store) g_object_unref(store); return list; } GtkWidget* newOptionList(const ListOption *options, size_t n_options, const string &selected_value) { GtkListStore *store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); GtkWidget *list = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(list), renderer, true); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(list), renderer, "text", 0, nullptr); bool found = false; GtkTreeIter iter; for (size_t i = 0; i != n_options; i++){ gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, options[i].label, 1, options[i].name, -1); if (selected_value == options[i].name){ gtk_combo_box_set_active_iter(GTK_COMBO_BOX(list), &iter); found = true; } } if (!found){ gtk_combo_box_set_active(GTK_COMBO_BOX(list), 0); } g_object_unref(store); return list; } GtkWidget *newCheckbox(const char *label, bool value) { GtkWidget *widget = gtk_check_button_new_with_label(label); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), value); return widget; } GtkWidget *newCheckbox(const string &label, bool value) { GtkWidget *widget = gtk_check_button_new_with_label(label.c_str()); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), value); return widget; } void afterFilterChanged() { GtkFileFilter *filter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(m_dialog)); ImportExportFormat *format = (ImportExportFormat*)g_object_get_data(G_OBJECT(filter), "format"); gtk_widget_set_sensitive(m_converters, format->type == FileType::txt); gtk_widget_set_sensitive(m_item_sizes, format->type == FileType::html); gtk_widget_set_sensitive(m_backgrounds, format->type == FileType::html); gtk_widget_set_sensitive(m_include_color_names, format->type == FileType::html | format->type == FileType::txt); } static void filterChanged(GtkFileChooserDialog*, GParamSpec*, ImportExportDialogOptions *import_export_dialog) { import_export_dialog->afterFilterChanged(); } }; ImportExportDialog::ImportExportDialog(GtkWindow* parent, ColorList *color_list, GlobalState *gs): m_parent(parent), m_color_list(color_list), m_gs(gs) { } ImportExportDialog::~ImportExportDialog() { } bool ImportExportDialog::showImport() { GtkWidget *dialog = gtk_file_chooser_dialog_new(_("Import"), m_parent, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, nullptr); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); const ImportExportFormat formats[] = { {_("Gpick Palette (*.gpa)"), "*.gpa", FileType::gpa}, {_("GIMP/Inkscape Palette (*.gpl)"), "*.gpl", FileType::gpl}, {_("Adobe Swatch Exchange (*.ase)"), "*.ase", FileType::ase}, {_("Text File (*.txt)"), "*.txt", FileType::txt}, {_("rgb.txt File (rgb.txt)"), "rgb.txt", FileType::rgbtxt}, }; const size_t n_formats = sizeof(formats) / sizeof(ImportExportFormat); auto default_path = m_gs->settings().getString("gpick.import.path", ""); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), default_path.c_str()); auto selected_filter = m_gs->settings().getString("gpick.import.filter", "all_supported"); GtkFileFilter *filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("All files")); g_object_set_data(G_OBJECT(filter), "identification", (gpointer)"all"); gtk_file_filter_add_pattern(filter, "*"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); if (selected_filter == "all") { gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); } filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("All supported formats")); g_object_set_data(G_OBJECT(filter), "identification", (gpointer)"all_supported"); for (size_t i = 0; i != n_formats; ++i){ gtk_file_filter_add_pattern(filter, formats[i].pattern); } gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); if (selected_filter == "all_supported"){ gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); } for (size_t i = 0; i != n_formats; ++i){ filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, formats[i].name); g_object_set_data(G_OBJECT(filter), "identification", (gpointer)formats[i].pattern); gtk_file_filter_add_pattern(filter, formats[i].pattern); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); if (formats[i].pattern == selected_filter) { gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); } } bool finished = false; while (!finished){ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK){ gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gchar *path = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog)); m_gs->settings().set("gpick.import.path", path); g_free(path); FileType type = ImportExport::getFileType(filename); if (type == FileType::unknown){ const gchar *format_name = gtk_file_filter_get_name(gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog))); for (size_t i = 0; i != n_formats; ++i){ if (g_strcmp0(formats[i].name, format_name) == 0){ type = formats[i].type; break; } } } GtkWidget* message; if (type == FileType::unknown){ message = gtk_message_dialog_new(GTK_WINDOW(dialog), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("File format is not supported")); gtk_window_set_title(GTK_WINDOW(message), _("Import")); gtk_dialog_run(GTK_DIALOG(message)); gtk_widget_destroy(message); }else{ for (size_t i = 0; i != n_formats; ++i){ if (formats[i].type == type){ ColorList *color_list = color_list_new(m_color_list); ImportExport import_export(color_list, filename, m_gs); import_export.setConverters(&m_gs->converters()); if (import_export.importType(formats[i].type)){ finished = true; color_list_add(m_color_list, color_list, true); }else{ message = gtk_message_dialog_new(GTK_WINDOW(dialog), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("File could not be imported")); gtk_window_set_title(GTK_WINDOW(message), _("Import")); gtk_dialog_run(GTK_DIALOG(message)); gtk_widget_destroy(message); } const char *identification = (const char*)g_object_get_data(G_OBJECT(gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog))), "identification"); m_gs->settings().set("gpick.import.filter", identification); color_list_destroy(color_list); break; } } } g_free(filename); }else break; } gtk_widget_destroy(dialog); return finished; } bool ImportExportDialog::showImportTextFile() { GtkWidget *dialog = gtk_file_chooser_dialog_new(_("Import text file"), m_parent, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, nullptr); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); auto default_path = m_gs->settings().getString("gpick.import_text_file.path", ""); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), default_path.c_str()); ImportExportDialogOptions import_export_dialog_options(dialog, m_gs); import_export_dialog_options.createImportTextFileOptions(); bool finished = false; while (!finished){ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK){ gchar *path = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog)); m_gs->settings().set("gpick.import_text_file.path", path); g_free(path); import_export_dialog_options.saveState(); GtkWidget* message; gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); ColorList *color_list = color_list_new(m_color_list); ImportExport import_export(color_list, filename, m_gs); import_export.setConverters(&m_gs->converters()); text_file_parser::Configuration configuration; configuration.single_line_c_comments = import_export_dialog_options.isSingleLineCCommentsEnabled(); configuration.multi_line_c_comments = import_export_dialog_options.isMultiLineCCommentsEnabled(); configuration.single_line_hash_comments = import_export_dialog_options.isSingleLineHashCommentsEnabled(); configuration.css_rgb = import_export_dialog_options.isCssRgbEnabled(); configuration.css_rgba = import_export_dialog_options.isCssRgbaEnabled(); configuration.full_hex = import_export_dialog_options.isFullHexEnabled(); configuration.short_hex = import_export_dialog_options.isShortHexEnabled(); configuration.int_values = import_export_dialog_options.isIntValuesEnabled(); configuration.float_values = import_export_dialog_options.isFloatValuesEnabled(); if (import_export.importTextFile(configuration)){ finished = true; color_list_add(m_color_list, color_list, true); }else{ message = gtk_message_dialog_new(GTK_WINDOW(dialog), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("File could not be imported")); gtk_window_set_title(GTK_WINDOW(message), _("Import text file")); gtk_dialog_run(GTK_DIALOG(message)); gtk_widget_destroy(message); } g_free(filename); color_list_destroy(color_list); }else break; } gtk_widget_destroy(dialog); return finished; } bool ImportExportDialog::showExport() { GtkWidget *dialog = gtk_file_chooser_dialog_new(_("Export"), m_parent, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, nullptr); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), true); const ImportExportFormat formats[] = { {_("Gpick Palette (*.gpa)"), "*.gpa", FileType::gpa}, {_("GIMP/Inkscape Palette (*.gpl)"), "*.gpl", FileType::gpl}, {_("Alias/WaveFront Material (*.mtl)"), "*.mtl", FileType::mtl}, {_("Adobe Swatch Exchange (*.ase)"), "*.ase", FileType::ase}, {_("Cascading Style Sheet (*.css)"), "*.css", FileType::css}, {_("Hyper Text Markup Language (*.html, *.htm)"), "*.html,*.htm", FileType::html}, {_("Text file (*.txt)"), "*.txt", FileType::txt}, }; const size_t n_formats = sizeof(formats) / sizeof(ImportExportFormat); auto default_path = m_gs->settings().getString("gpick.export.path", ""); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), default_path.c_str()); string selected_filter = m_gs->settings().getString("gpick.export.filter", "*.gpl"); for (size_t i = 0; i != n_formats; ++i){ GtkFileFilter *filter = gtk_file_filter_new(); g_object_set_data(G_OBJECT(filter), "format", (gpointer)&formats[i]); gtk_file_filter_set_name(filter, formats[i].name); split(formats[i].pattern, ',', true, [filter](const string &value){ gtk_file_filter_add_pattern(filter, value.c_str()); }); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); if (formats[i].pattern == selected_filter){ gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); } } ImportExportDialogOptions import_export_dialog_options(dialog, m_gs); import_export_dialog_options.createImportOptions(); bool finished = false; while (!finished){ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK){ gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gchar *path = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog)); m_gs->settings().set("gpick.export.path", path); g_free(path); import_export_dialog_options.saveState(); string format_name = gtk_file_filter_get_name(gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog))); for (size_t i = 0; i != n_formats; ++i){ if (formats[i].name == format_name){ ImportExport import_export(m_color_list, filename, m_gs); import_export.fixFileExtension(formats[i].pattern); import_export.setConverter(import_export_dialog_options.getSelectedConverter()); string item_size = import_export_dialog_options.getSelectedItemSize(); import_export.setItemSize(item_size.c_str()); string background = import_export_dialog_options.getSelectedBackground(); import_export.setBackground(background.c_str()); import_export.setIncludeColorNames(import_export_dialog_options.isIncludeColorNamesEnabled()); if (import_export.exportType(formats[i].type)){ finished = true; }else{ GtkWidget* message = gtk_message_dialog_new(GTK_WINDOW(dialog), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("File could not be exported")); gtk_window_set_title(GTK_WINDOW(dialog), _("Export")); gtk_dialog_run(GTK_DIALOG(message)); gtk_widget_destroy(message); } m_gs->settings().set("gpick.export.filter", formats[i].pattern); } } g_free(filename); }else break; } gtk_widget_destroy(dialog); return finished; } gpick-gpick-0.2.6/source/uiImportExport.h000066400000000000000000000037171377073231300204100ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_UI_IMPORT_EXPORT_H_ #define GPICK_UI_IMPORT_EXPORT_H_ #include struct GlobalState; struct ColorList; struct ImportExportDialog { ImportExportDialog(GtkWindow* parent, ColorList *color_list, GlobalState *gs); ~ImportExportDialog(); bool showImport(); bool showImportTextFile(); bool showExport(); private: GtkWindow *m_parent; ColorList *m_color_list; GlobalState *m_gs; }; #endif /* GPICK_UI_IMPORT_EXPORT_H_ */ gpick-gpick-0.2.6/source/uiListPalette.cpp000066400000000000000000001267461377073231300205310ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "uiListPalette.h" #include "uiUtilities.h" #include "gtk/ColorCell.h" #include "ColorObject.h" #include "ColorList.h" #include "ColorSource.h" #include "DragDrop.h" #include "GlobalState.h" #include "Converters.h" #include "Converter.h" #include "GlobalState.h" #include "dynv/Map.h" #include "Vector2.h" #include "I18N.h" #include "common/Format.h" #include "StandardMenu.h" #include "StandardEventHandler.h" #include #include using namespace math; using namespace std; static void foreachSelectedItem(GtkTreeView *treeView, std::function callback); static void foreachItem(GtkTreeView *treeView, std::function callback); struct ListPaletteArgs : public IReadonlyColorsUI { ColorSource source; GtkWidget *treeview; gint scroll_timeout; Vec2 last_click_position; bool disable_selection; GtkWidget* count_label; GlobalState* gs; virtual ~ListPaletteArgs() { } virtual void addToPalette(const ColorObject &) override { foreachSelectedItem(GTK_TREE_VIEW(treeview), [this](ColorObject *colorObject) { color_list_add_color_object(gs->getColorList(), colorObject, true); return true; }); } virtual void addAllToPalette() override { foreachItem(GTK_TREE_VIEW(treeview), [this](ColorObject *colorObject) { color_list_add_color_object(gs->getColorList(), colorObject, true); return true; }); } virtual const ColorObject &getColor() override { foreachSelectedItem(GTK_TREE_VIEW(treeview), [this](ColorObject *colorObject) { this->colorObject = *colorObject; return false; }); return colorObject; } virtual bool hasColor() override { bool result = false; foreachItem(GTK_TREE_VIEW(treeview), [&result](ColorObject *) { result = true; return false; }); return result; } virtual bool hasSelectedColor() override { bool result = false; foreachSelectedItem(GTK_TREE_VIEW(treeview), [&result](ColorObject *) { result = true; return false; }); return result; } virtual std::vector getColors(bool selected) { std::vector result; if (selected) foreachSelectedItem(GTK_TREE_VIEW(treeview), [&result](ColorObject *colorObject) { result.push_back(*colorObject); return true; }); else foreachItem(GTK_TREE_VIEW(treeview), [&result](ColorObject *colorObject) { result.push_back(*colorObject); return true; }); return result; } ColorObject colorObject; }; static void destroy_arguments(gpointer data); static ColorObject* get_color_object(struct DragDrop* dd); static ColorObject** get_color_object_list(struct DragDrop* dd, size_t *color_object_n); #define SCROLL_EDGE_SIZE 15 //SCROLL_EDGE_SIZE from gtktreeview.c static void add_scroll_timeout(ListPaletteArgs *args); static void remove_scroll_timeout(ListPaletteArgs *args); static gboolean scroll_row_timeout(ListPaletteArgs *args); static void palette_list_vertical_autoscroll(GtkTreeView *treeview); static void update_counts(ListPaletteArgs *args); static gboolean scroll_row_timeout(ListPaletteArgs *args){ palette_list_vertical_autoscroll(GTK_TREE_VIEW(args->treeview)); return true; } static void add_scroll_timeout(ListPaletteArgs *args){ if (!args->scroll_timeout){ args->scroll_timeout = gdk_threads_add_timeout(150, (GSourceFunc)scroll_row_timeout, args); } } static void remove_scroll_timeout(ListPaletteArgs *args){ if (args->scroll_timeout){ g_source_remove(args->scroll_timeout); args->scroll_timeout = 0; } } static bool drag_end(struct DragDrop* dd, GtkWidget *widget, GdkDragContext *context){ remove_scroll_timeout((ListPaletteArgs*)dd->userdata); update_counts((ListPaletteArgs*)dd->userdata); return true; } typedef struct SelectionBoundsArgs{ int min_index; int max_index; int last_index; bool discontinuous; } SelectionBoundsArgs; static void find_selection_bounds(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data){ gint *indices = gtk_tree_path_get_indices(path); SelectionBoundsArgs *args = (SelectionBoundsArgs *) data; int index = indices[0]; // currently indices are all 1d. int diff = index - args->last_index; if ((args->last_index != 0x7fffffff) && (diff != 1) && (diff != -1)){ args->discontinuous = true; } if (index > args->max_index){ args->max_index = index; } if (index < args->min_index){ args->min_index = index; } args->last_index = index; } static void update_counts(ListPaletteArgs *args){ stringstream s; GtkTreeSelection *sel; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(args->treeview)); SelectionBoundsArgs bounds; int selected_count; int total_colors; if (!args->count_label){ return; } sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(args->treeview)); selected_count = gtk_tree_selection_count_selected_rows(sel); total_colors = gtk_tree_model_iter_n_children(model, nullptr); bounds.discontinuous = false; bounds.min_index = 0x7fffffff; bounds.last_index = 0x7fffffff; bounds.max_index = 0; if (selected_count > 0){ s.str(""); s << "#"; gtk_tree_selection_selected_foreach(sel, &find_selection_bounds, &bounds); if (bounds.min_index < bounds.max_index){ s << bounds.min_index; if (bounds.discontinuous){ s << ".."; }else{ s << "-"; } s << bounds.max_index; }else{ s << bounds.min_index; } #ifdef ENABLE_NLS s << " (" << common::format(ngettext("{} color", "{} colors", selected_count), selected_count) << ")"; #else s << " (" << ((selected_count == 1) ? "color" : "colors") << ")"; #endif s << " " << _("selected") << ". "; } #ifdef ENABLE_NLS s << common::format(ngettext("Total {} color", "Total {} colors", total_colors), total_colors); #else s << "Total " << total_colors << ((total_colors == 1) ? " color" : " colors"); #endif auto message = s.str(); gtk_label_set_text(GTK_LABEL(args->count_label), message.c_str()); } static void palette_list_vertical_autoscroll(GtkTreeView *treeview) { GdkRectangle visible_rect; gint y; gint offset; gdk_window_get_pointer(gtk_tree_view_get_bin_window(treeview), nullptr, &y, nullptr); gint dy; gtk_tree_view_convert_bin_window_to_tree_coords(treeview, 0, 0, 0, &dy); y += dy; gtk_tree_view_get_visible_rect(treeview, &visible_rect); offset = y - (visible_rect.y + 2 * SCROLL_EDGE_SIZE); if (offset > 0) { offset = y - (visible_rect.y + visible_rect.height - 2 * SCROLL_EDGE_SIZE); if (offset < 0) return; } GtkAdjustment *adjustment = gtk_tree_view_get_vadjustment(treeview); gtk_adjustment_set_value(adjustment, min(max(gtk_adjustment_get_value(adjustment) + offset, 0.0), gtk_adjustment_get_upper(adjustment) - gtk_adjustment_get_page_size (adjustment))); } static void palette_list_entry_fill(GtkListStore* store, GtkTreeIter *iter, ColorObject* color_object, ListPaletteArgs* args) { string text = args->gs->converters().serialize(color_object, Converters::Type::colorList); gtk_list_store_set(store, iter, 0, color_object->reference(), 1, text.c_str(), 2, color_object->getName().c_str(), -1); } static void palette_list_entry_update_row(GtkListStore* store, GtkTreeIter *iter, ColorObject* color_object, ListPaletteArgs* args) { string text = args->gs->converters().serialize(color_object, Converters::Type::colorList); gtk_list_store_set(store, iter, 1, text.c_str(), 2, color_object->getName().c_str(), -1); } static void palette_list_entry_update_name(GtkListStore* store, GtkTreeIter *iter, ColorObject* color_object) { gtk_list_store_set(store, iter, 2, color_object->getName().c_str(), -1); } static void palette_list_cell_edited(GtkCellRendererText *cell, gchar *path, gchar *new_text, gpointer user_data) { GtkTreeIter iter; GtkTreeModel *model=GTK_TREE_MODEL(user_data); gtk_tree_model_get_iter_from_string(model, &iter, path ); gtk_list_store_set(GTK_LIST_STORE(model), &iter, 2, new_text, -1); ColorObject *color_object; gtk_tree_model_get(model, &iter, 0, &color_object, -1); color_object->setName(new_text); } static void palette_list_row_activated(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data) { ListPaletteArgs* args = (ListPaletteArgs*)user_data; GtkTreeModel* model = gtk_tree_view_get_model(tree_view);; GtkTreeIter iter; gtk_tree_model_get_iter(model, &iter, path); ColorObject *color_object; gtk_tree_model_get(model, &iter, 0, &color_object, -1); ColorSource *color_source = args->gs->getCurrentColorSource(); if (color_source != nullptr) color_source_set_color(color_source, color_object); update_counts(args); } static int palette_list_preview_on_insert(ColorList* color_list, ColorObject* color_object){ palette_list_add_entry(GTK_WIDGET(color_list->userdata), color_object); return 0; } static int palette_list_preview_on_clear(ColorList* color_list){ palette_list_remove_all_entries(GTK_WIDGET(color_list->userdata)); return 0; } static void destroy_cb(GtkWidget* widget, ListPaletteArgs *args){ remove_scroll_timeout(args); palette_list_remove_all_entries(widget); } GtkWidget* palette_list_get_widget(ColorList *color_list){ return (GtkWidget*)color_list->userdata; } static gboolean controlSelection(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, ListPaletteArgs *args) { return args->disable_selection; } static void disablePaletteSelection(GtkTreeView *treeView, gboolean disable, int x, int y, ListPaletteArgs *args) { auto selection = gtk_tree_view_get_selection(treeView); args->disable_selection = disable; gtk_tree_selection_set_select_function(selection, (GtkTreeSelectionFunc)controlSelection, args, nullptr); args->last_click_position.x = x; args->last_click_position.y = y; } static void onPreviewActivate(GtkTreeView *treeView, GtkTreePath *path, GtkTreeViewColumn *column, ListPaletteArgs *args) { auto model = gtk_tree_view_get_model(treeView); GtkTreeIter iter; gtk_tree_model_get_iter(model, &iter, path); ColorObject *colorObject; gtk_tree_model_get(model, &iter, 0, &colorObject, -1); if (colorObject) color_list_add_color_object(args->gs->getColorList(), colorObject, true); } static void foreachItem(GtkTreeView *treeView, std::function callback) { auto model = gtk_tree_view_get_model(treeView); GtkTreeIter iter; auto valid = gtk_tree_model_get_iter_first(model, &iter); while (valid) { ColorObject *colorObject; gtk_tree_model_get(model, &iter, 0, &colorObject, -1); if (!callback(colorObject)) break; valid = gtk_tree_model_iter_next(model, &iter); } } static void foreachSelectedItem(GtkTreeView *treeView, std::function callback) { auto model = gtk_tree_view_get_model(treeView); auto selection = gtk_tree_view_get_selection(treeView); GList *list = gtk_tree_selection_get_selected_rows(selection, 0); GList *i = list; while (i) { GtkTreeIter iter; gtk_tree_model_get_iter(model, &iter, reinterpret_cast(i->data)); ColorObject *colorObject; gtk_tree_model_get(model, &iter, 0, &colorObject, -1); if (!callback(colorObject)) break; i = g_list_next(i); } g_list_foreach(list, (GFunc)gtk_tree_path_free, nullptr); g_list_free(list); } #if GTK_MAJOR_VERSION >= 3 static void onExpanderStateChange(GtkExpander *expander, GParamSpec *, ListPaletteArgs *args) { bool expanded = gtk_expander_get_expanded(expander); gtk_widget_set_hexpand(args->treeview, expanded); gtk_widget_set_vexpand(args->treeview, expanded); } #endif static gboolean onPreviewButtonPress(GtkTreeView *treeView, GdkEventButton *event, ListPaletteArgs *args) { if (event->button == 3) { return false; } disablePaletteSelection(treeView, true, -1, -1, args); if (event->button != 1) return false; if (event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) return false; GtkTreePath *path = nullptr; if (!gtk_tree_view_get_path_at_pos(treeView, static_cast(event->x), static_cast(event->y), &path, nullptr, nullptr, nullptr)) return false; auto selection = gtk_tree_view_get_selection(treeView); if (gtk_tree_selection_path_is_selected(selection, path)) disablePaletteSelection(treeView, false, static_cast(event->x), static_cast(event->y), args); if (path) gtk_tree_path_free(path); return false; } static gboolean onPreviewButtonRelease(GtkTreeView *treeView, GdkEventButton *event, ListPaletteArgs *args) { if (args->last_click_position != Vec2(-1, -1)) { Vec2 clickPosition = args->last_click_position; disablePaletteSelection(treeView, true, -1, -1, args); if (clickPosition.x == static_cast(event->x) && clickPosition.y == static_cast(event->y)) { GtkTreePath *path = nullptr; GtkTreeViewColumn *column; if (gtk_tree_view_get_path_at_pos(treeView, static_cast(event->x), static_cast(event->y), &path, &column, nullptr, nullptr)) { gtk_tree_view_set_cursor(treeView, path, column, false); } if (path) gtk_tree_path_free(path); } } return false; } GtkWidget* palette_list_preview_new(GlobalState* gs, bool expander, bool expanded, ColorList* color_list, ColorList** out_color_list) { auto args = new ListPaletteArgs; args->gs = gs; args->scroll_timeout = 0; args->count_label = nullptr; auto view = args->treeview = gtk_tree_view_new(); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), 0); gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(view), true); auto store = gtk_list_store_new(3, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING); auto col = gtk_tree_view_column_new(); gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_column_set_resizable(col, 0); auto renderer = custom_cell_renderer_color_new(); custom_cell_renderer_color_set_size(renderer, 16, 16); gtk_tree_view_column_pack_start(col, renderer, true); gtk_tree_view_column_add_attribute(col, renderer, "color", 0); gtk_tree_view_append_column(GTK_TREE_VIEW(view), col); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(view), false); gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store)); g_object_unref(GTK_TREE_MODEL(store)); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); g_signal_connect(G_OBJECT(view), "button-press-event", G_CALLBACK(onPreviewButtonPress), args); g_signal_connect(G_OBJECT(view), "button-release-event", G_CALLBACK(onPreviewButtonRelease), args); g_signal_connect(G_OBJECT(view), "row-activated", G_CALLBACK(onPreviewActivate), args); StandardEventHandler::forWidget(view, args->gs, args, StandardEventHandler::Options().afterEvents(false)); gtk_drag_source_set(view, GDK_BUTTON1_MASK, 0, 0, GdkDragAction(GDK_ACTION_COPY)); struct DragDrop dd; dragdrop_init(&dd, gs); dd.converterType = Converters::Type::colorList; dd.get_color_object = get_color_object; dd.get_color_object_list = get_color_object_list; dd.drag_end = drag_end; dd.userdata = args; dragdrop_widget_attach(view, DragDropFlags(DRAGDROP_SOURCE), &dd); if (out_color_list) { ColorList* cl=color_list_new(); cl->userdata=view; cl->on_insert=palette_list_preview_on_insert; cl->on_clear=palette_list_preview_on_clear; *out_color_list=cl; } GtkWidget *scrolledWindow = gtk_scrolled_window_new(0, 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledWindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledWindow), GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(scrolledWindow), view); GtkWidget *mainWidget = scrolledWindow; if (expander){ GtkWidget *expander = gtk_expander_new(_("Preview")); gtk_container_add(GTK_CONTAINER(expander), scrolledWindow); #if GTK_MAJOR_VERSION >= 3 g_signal_connect(expander, "notify::expanded", G_CALLBACK(onExpanderStateChange), args); #endif gtk_expander_set_expanded(GTK_EXPANDER(expander), expanded); mainWidget = expander; } g_object_set_data_full(G_OBJECT(view), "arguments", args, destroy_arguments); g_signal_connect(G_OBJECT(view), "destroy", G_CALLBACK(destroy_cb), args); return mainWidget; } static ColorObject** get_color_object_list(struct DragDrop* dd, size_t *color_object_n){ GtkTreeIter iter; GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dd->widget)); GtkTreeModel* model; gint selected = gtk_tree_selection_count_selected_rows(selection); if (selected <= 1){ if (color_object_n) *color_object_n = selected; return 0; } GList *list = gtk_tree_selection_get_selected_rows(selection, &model); ColorObject** color_objects = new ColorObject*[selected]; if (color_object_n) *color_object_n = selected; if (list){ GList *i = list; ColorObject* color_object; uint32_t j = 0; while (i) { gtk_tree_model_get_iter(model, &iter, (GtkTreePath*) (i->data)); gtk_tree_model_get(model, &iter, 0, &color_object, -1); color_objects[j] = color_object->reference(); i = g_list_next(i); j++; } g_list_foreach (list, (GFunc)gtk_tree_path_free, nullptr); g_list_free (list); } return color_objects; } static ColorObject* get_color_object(struct DragDrop* dd){ GtkTreeIter iter; GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dd->widget)); GtkTreeModel* model; GList *list = gtk_tree_selection_get_selected_rows ( selection, &model ); if (list){ GList *i = list; ColorObject* color_object; while (i) { gtk_tree_model_get_iter(model, &iter, (GtkTreePath*) (i->data)); gtk_tree_model_get(model, &iter, 0, &color_object, -1); g_list_foreach (list, (GFunc)gtk_tree_path_free, nullptr); g_list_free (list); return color_object->reference(); i = g_list_next(i); } g_list_foreach (list, (GFunc)gtk_tree_path_free, nullptr); g_list_free (list); } return 0; } static bool getPathAt(GtkTreeView *tree_view, int x, int y, GtkTreePath *&path, GtkTreeViewDropPosition &position) { if (gtk_tree_view_get_dest_row_at_pos(tree_view, x, y, &path, &position)) { GdkModifierType mask; gdk_window_get_pointer(gtk_tree_view_get_bin_window(tree_view), nullptr, nullptr, &mask); if ((mask & GDK_CONTROL_MASK) && (position == GTK_TREE_VIEW_DROP_INTO_OR_AFTER || position == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE)) { position = GTK_TREE_VIEW_DROP_INTO_OR_BEFORE; } else if (position == GTK_TREE_VIEW_DROP_BEFORE || position == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE) { position = GTK_TREE_VIEW_DROP_BEFORE; } else { position = GTK_TREE_VIEW_DROP_AFTER; } return true; }else{ int tx, ty; gtk_tree_view_convert_widget_to_tree_coords(tree_view, x, y, &tx, &ty); GtkTreeModel *model = gtk_tree_view_get_model(tree_view); GtkTreeIter last, iter; if (!gtk_tree_model_get_iter_first(model, &iter)) { position = GTK_TREE_VIEW_DROP_AFTER; return false; } if (ty >= 0) { do { last = iter; } while (gtk_tree_model_iter_next(model, &iter)); position = GTK_TREE_VIEW_DROP_AFTER; iter = last; } else { position = GTK_TREE_VIEW_DROP_BEFORE; } path = gtk_tree_model_get_path(model, &iter); return true; } } static int set_color_object_list_at(DragDrop* dd, ColorObject** color_objects, size_t color_object_n, int x, int y, bool move, bool sameWidget) { ListPaletteArgs* args = (ListPaletteArgs*)dd->userdata; color_list_set_selected(args->gs->getColorList(), false); remove_scroll_timeout(args); auto model = gtk_tree_view_get_model(GTK_TREE_VIEW(dd->widget)); boost::optional insertIterator; GtkTreePath* path; GtkTreeViewDropPosition pos; if (getPathAt(GTK_TREE_VIEW(dd->widget), x, y, path, pos)) { GtkTreeIter iter; gtk_tree_model_get_iter(model, &iter, path); gtk_tree_path_free(path); insertIterator = iter; } if (sameWidget && move) { for (size_t i = 0; i != color_object_n; i++) { ColorObject *color_object = nullptr; if (pos == GTK_TREE_VIEW_DROP_BEFORE || pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE) { color_object = color_objects[i]; } else if (pos == GTK_TREE_VIEW_DROP_AFTER || pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) { color_object = color_objects[color_object_n - i - 1]; } ColorObject *reference_color_object = nullptr; if (insertIterator) { gtk_tree_model_get(GTK_TREE_MODEL(model), &*insertIterator, 0, &reference_color_object, -1); } if (reference_color_object == color_object){ // Reference item is going to be removed, so any further inserts // will fail if the same iterator is used. Iterator is moved forward // to avoid that. GtkTreeIter iter = *insertIterator; if (pos == GTK_TREE_VIEW_DROP_BEFORE || pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE) { if (gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter)){ insertIterator = iter; } else { insertIterator.reset(); } }else if (pos == GTK_TREE_VIEW_DROP_AFTER || pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) { GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(model), &iter); if (gtk_tree_path_prev(path)) { if (gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path)){ insertIterator = iter; } else { insertIterator.reset(); } }else{ insertIterator.reset(); } gtk_tree_path_free(path); } } color_list_remove_color_object(args->gs->getColorList(), color_object); color_object->setSelected(true); if (insertIterator) { GtkTreeIter iter; if (pos == GTK_TREE_VIEW_DROP_BEFORE || pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE) { gtk_list_store_insert_before(GTK_LIST_STORE(model), &iter, &*insertIterator); } else { gtk_list_store_insert_after(GTK_LIST_STORE(model), &iter, &*insertIterator); } palette_list_entry_fill(GTK_LIST_STORE(model), &iter, color_object, args); color_list_add_color_object(args->gs->getColorList(), color_object, false); }else{ color_list_add_color_object(args->gs->getColorList(), color_object, true); } } } else { for (size_t i = 0; i != color_object_n; i++) { ColorObject *color_object = nullptr; if (pos == GTK_TREE_VIEW_DROP_BEFORE || pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE) { color_object = color_objects[i]->copy(); } else if (pos == GTK_TREE_VIEW_DROP_AFTER || pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) { color_object = color_objects[color_object_n - i - 1]->copy(); } color_object->setSelected(true); if (insertIterator) { GtkTreeIter iter; if (pos == GTK_TREE_VIEW_DROP_BEFORE || pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE) { gtk_list_store_insert_before(GTK_LIST_STORE(model), &iter, &*insertIterator); } else { gtk_list_store_insert_after(GTK_LIST_STORE(model), &iter, &*insertIterator); } palette_list_entry_fill(GTK_LIST_STORE(model), &iter, color_object, args); color_list_add_color_object(args->gs->getColorList(), color_object, false); }else{ color_list_add_color_object(args->gs->getColorList(), color_object, true); color_object->release(); } } } auto *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dd->widget)); gtk_tree_selection_set_select_function(selection, nullptr, nullptr, nullptr); gtk_tree_selection_unselect_all(selection); GtkTreeIter iter; bool valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter); while (valid) { ColorObject *colorObject; gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &colorObject, -1); if (colorObject->isSelected()) { gtk_tree_selection_select_iter(selection, &iter); } valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter); } update_counts(args); return 0; } static int set_color_object_at(struct DragDrop* dd, ColorObject* color_object, int x, int y, bool move, bool sameWidget) { ListPaletteArgs* args = (ListPaletteArgs*)dd->userdata; color_list_set_selected(args->gs->getColorList(), false); remove_scroll_timeout(args); auto model = gtk_tree_view_get_model(GTK_TREE_VIEW(dd->widget)); boost::optional insertIterator; GtkTreePath* path; GtkTreeViewDropPosition pos; if (getPathAt(GTK_TREE_VIEW(dd->widget), x, y, path, pos)) { GtkTreeIter iter; gtk_tree_model_get_iter(model, &iter, path); gtk_tree_path_free(path); insertIterator = iter; } if (sameWidget && move) { ColorObject *reference_color_object = nullptr; if (insertIterator) { gtk_tree_model_get(GTK_TREE_MODEL(model), &*insertIterator, 0, &reference_color_object, -1); } if (reference_color_object == color_object){ // Reference item is going to be removed, so any further inserts // will fail if the same iterator is used. Iterator is moved forward // to avoid that. GtkTreeIter iter = *insertIterator; if (pos == GTK_TREE_VIEW_DROP_BEFORE || pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE) { if (gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter)){ insertIterator = iter; } else { insertIterator.reset(); } }else if (pos == GTK_TREE_VIEW_DROP_AFTER || pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) { GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(model), &iter); if (gtk_tree_path_prev(path)) { if (gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path)){ insertIterator = iter; } else { insertIterator.reset(); } }else{ insertIterator.reset(); } gtk_tree_path_free(path); } } color_list_remove_color_object(args->gs->getColorList(), color_object); color_object->setSelected(true); if (insertIterator) { GtkTreeIter iter; if (pos == GTK_TREE_VIEW_DROP_BEFORE || pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE) { gtk_list_store_insert_before(GTK_LIST_STORE(model), &iter, &*insertIterator); } else { gtk_list_store_insert_after(GTK_LIST_STORE(model), &iter, &*insertIterator); } palette_list_entry_fill(GTK_LIST_STORE(model), &iter, color_object, args); color_list_add_color_object(args->gs->getColorList(), color_object, false); }else{ color_list_add_color_object(args->gs->getColorList(), color_object, true); } } else { color_object = color_object->copy(); color_object->setSelected(true); if (insertIterator) { GtkTreeIter iter; if (pos == GTK_TREE_VIEW_DROP_BEFORE || pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE) { gtk_list_store_insert_before(GTK_LIST_STORE(model), &iter, &*insertIterator); } else { gtk_list_store_insert_after(GTK_LIST_STORE(model), &iter, &*insertIterator); } palette_list_entry_fill(GTK_LIST_STORE(model), &iter, color_object, args); color_list_add_color_object(args->gs->getColorList(), color_object, false); }else{ color_list_add_color_object(args->gs->getColorList(), color_object, true); color_object->release(); } } auto *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dd->widget)); gtk_tree_selection_set_select_function(selection, nullptr, nullptr, nullptr); gtk_tree_selection_unselect_all(selection); GtkTreeIter iter; bool valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter); while (valid) { ColorObject *colorObject; gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, 0, &colorObject, -1); if (colorObject->isSelected()) { gtk_tree_selection_select_iter(selection, &iter); } valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter); } update_counts(args); return 0; } static bool test_at(struct DragDrop* dd, int x, int y) { GtkTreePath* path; GtkTreeViewDropPosition pos; if (getPathAt(GTK_TREE_VIEW(dd->widget), x, y, path, pos)) { gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(dd->widget), path, pos); gtk_tree_path_free(path); } else { gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(dd->widget), nullptr, pos); } add_scroll_timeout((ListPaletteArgs*)dd->userdata); return true; } static void destroy_arguments(gpointer data){ ListPaletteArgs* args = (ListPaletteArgs*)data; delete args; } static gboolean on_palette_button_press(GtkTreeView *treeView, GdkEventButton *event, ListPaletteArgs *args) { disablePaletteSelection(treeView, true, -1, -1, args); if (event->button != 1) return false; if (event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) return false; GtkTreePath *path = nullptr; if (!gtk_tree_view_get_path_at_pos(treeView, static_cast(event->x), static_cast(event->y), &path, nullptr, nullptr, nullptr)) return false; auto selection = gtk_tree_view_get_selection(treeView); if (gtk_tree_selection_path_is_selected(selection, path)) { disablePaletteSelection(treeView, false, static_cast(event->x), static_cast(event->y), args); } if (path) gtk_tree_path_free(path); update_counts(args); return false; } static gboolean on_palette_button_release(GtkTreeView *treeView, GdkEventButton *event, ListPaletteArgs *args) { if (args->last_click_position != Vec2(-1, -1)) { Vec2 clickPosition = args->last_click_position; disablePaletteSelection(treeView, true, -1, -1, args); if (clickPosition.x == static_cast(event->x) && clickPosition.y == static_cast(event->y)) { GtkTreePath *path = nullptr; GtkTreeViewColumn *column; if (gtk_tree_view_get_path_at_pos(treeView, static_cast(event->x), static_cast(event->y), &path, &column, nullptr, nullptr)) { gtk_tree_view_set_cursor(treeView, path, column, FALSE); } if (path) gtk_tree_path_free(path); } } update_counts(args); return false; } static void on_palette_cursor_changed(GtkTreeView *treeview, ListPaletteArgs *args){ update_counts(args); } static gboolean on_palette_select_all(GtkTreeView *treeview, ListPaletteArgs *args){ update_counts(args); return FALSE; } static gboolean on_palette_unselect_all(GtkTreeView *treeview, ListPaletteArgs *args){ update_counts(args); return FALSE; } GtkWidget* palette_list_new(GlobalState* gs, GtkWidget* count_label) { auto args = new ListPaletteArgs; args->gs = gs; args->count_label = count_label; args->scroll_timeout = 0; auto view = args->treeview = gtk_tree_view_new(); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), true); gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(view), true); auto store = gtk_list_store_new (3, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING); auto col = gtk_tree_view_column_new(); gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_column_set_resizable(col,1); gtk_tree_view_column_set_title(col, _("Color")); auto renderer = custom_cell_renderer_color_new(); gtk_tree_view_column_pack_start(col, renderer, true); gtk_tree_view_column_add_attribute(col, renderer, "color", 0); gtk_tree_view_append_column(GTK_TREE_VIEW(view), col); col = gtk_tree_view_column_new(); gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_column_set_resizable(col,1); gtk_tree_view_column_set_title(col, _("Color")); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(col, renderer, true); gtk_tree_view_column_add_attribute(col, renderer, "text", 1); gtk_tree_view_append_column(GTK_TREE_VIEW(view), col); col = gtk_tree_view_column_new(); gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_column_set_resizable(col,1); gtk_tree_view_column_set_title(col, _("Name")); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(col, renderer, true); gtk_tree_view_column_add_attribute(col, renderer, "text", 2); gtk_tree_view_append_column(GTK_TREE_VIEW(view), col); g_object_set(renderer, "editable", TRUE, nullptr); g_signal_connect(renderer, "edited", (GCallback) palette_list_cell_edited, store); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(view), false); gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store)); g_object_unref(GTK_TREE_MODEL(store)); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); g_signal_connect(G_OBJECT(view), "row-activated", G_CALLBACK(palette_list_row_activated), args); g_signal_connect(G_OBJECT(view), "button-press-event", G_CALLBACK(on_palette_button_press), args); g_signal_connect(G_OBJECT(view), "button-release-event", G_CALLBACK(on_palette_button_release), args); g_signal_connect(G_OBJECT(view), "cursor-changed", G_CALLBACK(on_palette_cursor_changed), args); g_signal_connect_after(G_OBJECT(view), "select-all", G_CALLBACK(on_palette_select_all), args); g_signal_connect_after(G_OBJECT(view), "unselect-all", G_CALLBACK(on_palette_unselect_all), args); ///gtk_tree_view_set_reorderable(GTK_TREE_VIEW (view), TRUE); gtk_drag_dest_set( view, GtkDestDefaults(GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT), 0, 0, GdkDragAction(GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK)); gtk_drag_source_set( view, GDK_BUTTON1_MASK, 0, 0, GdkDragAction(GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK)); struct DragDrop dd; dragdrop_init(&dd, gs); dd.get_color_object = get_color_object; dd.get_color_object_list = get_color_object_list; dd.set_color_object_at = set_color_object_at; dd.set_color_object_list_at = set_color_object_list_at; dd.test_at = test_at; dd.drag_end = drag_end; dd.converterType = Converters::Type::colorList; dd.userdata = args; dragdrop_widget_attach(view, DragDropFlags(DRAGDROP_SOURCE | DRAGDROP_DESTINATION), &dd); g_object_set_data_full(G_OBJECT(view), "arguments", args, destroy_arguments); g_signal_connect(G_OBJECT(view), "destroy", G_CALLBACK(destroy_cb), args); if (count_label){ update_counts(args); } return view; } void palette_list_remove_all_entries(GtkWidget* widget) { ListPaletteArgs* args = (ListPaletteArgs*)g_object_get_data(G_OBJECT(widget), "arguments"); GtkTreeIter iter; GtkListStore *store; gboolean valid; store=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(widget))); valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter); while (valid){ ColorObject* c; gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &c, -1); c->release(); valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter); } gtk_list_store_clear(GTK_LIST_STORE(store)); update_counts(args); } gint32 palette_list_get_selected_count(GtkWidget* widget) { return gtk_tree_selection_count_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(widget))); } gint32 palette_list_get_count(GtkWidget* widget){ GtkTreeModel *store; store=gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); return gtk_tree_model_iter_n_children(store, nullptr); } gint32 palette_list_get_selected_color(GtkWidget* widget, Color* color) { GtkTreeSelection *selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(widget) ); GtkListStore *store; GtkTreeIter iter; if (gtk_tree_selection_count_selected_rows(selection) != 1){ return -1; } store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(widget))); GList *list = gtk_tree_selection_get_selected_rows ( selection, 0 ); GList *i = list; if (i){ ColorObject* color_object; gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, (GtkTreePath*)i->data); gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &color_object, -1); *color = color_object->getColor(); } g_list_foreach(list, (GFunc)gtk_tree_path_free, nullptr); g_list_free(list); return 0; } void palette_list_remove_selected_entries(GtkWidget* widget) { ListPaletteArgs* args = (ListPaletteArgs*)g_object_get_data(G_OBJECT(widget), "arguments"); GtkTreeIter iter; GtkListStore *store; gboolean valid; store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(widget))); valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter); ColorObject* color_object; while (valid){ gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &color_object, -1); if (color_object->isSelected()){ valid = gtk_list_store_remove(GTK_LIST_STORE(store), &iter); color_object->release(); }else{ valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter); } } update_counts(args); } void palette_list_add_entry(GtkWidget* widget, ColorObject* color_object) { ListPaletteArgs* args = (ListPaletteArgs*)g_object_get_data(G_OBJECT(widget), "arguments"); GtkTreeIter iter1; GtkListStore *store; store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(widget))); gtk_list_store_append(store, &iter1); palette_list_entry_fill(store, &iter1, color_object, args); update_counts(args); } int palette_list_remove_entry(GtkWidget* widget, ColorObject* r_color_object) { ListPaletteArgs* args = (ListPaletteArgs*)g_object_get_data(G_OBJECT(widget), "arguments"); GtkTreeIter iter; GtkListStore *store; gboolean valid; store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(widget))); valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter); ColorObject* color_object; while (valid){ gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &color_object, -1); if (color_object == r_color_object){ valid = gtk_list_store_remove(GTK_LIST_STORE(store), &iter); color_object->release(); return 0; } valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter); } update_counts(args); return -1; } static void execute_callback(GtkListStore *store, GtkTreeIter *iter, ListPaletteArgs* args, PaletteListCallback callback, void *userdata) { ColorObject* color_object; gtk_tree_model_get(GTK_TREE_MODEL(store), iter, 0, &color_object, -1); PaletteListCallbackReturn r = callback(color_object, userdata); switch (r){ case PALETTE_LIST_CALLBACK_UPDATE_NAME: palette_list_entry_update_name(store, iter, color_object); break; case PALETTE_LIST_CALLBACK_UPDATE_ROW: palette_list_entry_update_row(store, iter, color_object, args); break; case PALETTE_LIST_CALLBACK_NO_UPDATE: break; } } static void execute_replace_callback(GtkListStore *store, GtkTreeIter *iter, ListPaletteArgs* args, PaletteListReplaceCallback callback, void *userdata) { ColorObject *color_object, *orig_color_object; gtk_tree_model_get(GTK_TREE_MODEL(store), iter, 0, &color_object, -1); orig_color_object = color_object; color_object->reference(); PaletteListCallbackReturn r = callback(&color_object, userdata); if (color_object != orig_color_object){ gtk_list_store_set(store, iter, 0, color_object, -1); } switch (r){ case PALETTE_LIST_CALLBACK_UPDATE_NAME: palette_list_entry_update_name(store, iter, color_object); break; case PALETTE_LIST_CALLBACK_UPDATE_ROW: palette_list_entry_update_row(store, iter, color_object, args); break; case PALETTE_LIST_CALLBACK_NO_UPDATE: break; } color_object->release(); } gint32 palette_list_foreach(GtkWidget* widget, PaletteListCallback callback, void *userdata) { ListPaletteArgs* args = (ListPaletteArgs*)g_object_get_data(G_OBJECT(widget), "arguments"); GtkTreeIter iter; GtkListStore *store; gboolean valid; store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(widget))); valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter); while (valid){ execute_callback(store, &iter, args, callback, userdata); valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter); } return 0; } gint32 palette_list_foreach_selected(GtkWidget* widget, PaletteListCallback callback, void *userdata) { ListPaletteArgs* args = (ListPaletteArgs*)g_object_get_data(G_OBJECT(widget), "arguments"); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); GtkListStore *store; GtkTreeIter iter; store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(widget))); GList *list = gtk_tree_selection_get_selected_rows(selection, 0); GList *i = list; while (i) { gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, (GtkTreePath*) (i->data)); execute_callback(store, &iter, args, callback, userdata); i = g_list_next(i); } g_list_foreach(list, (GFunc)gtk_tree_path_free, nullptr); g_list_free(list); return 0; } gint32 palette_list_foreach_selected(GtkWidget* widget, PaletteListReplaceCallback callback, void *userdata){ ListPaletteArgs* args = (ListPaletteArgs*)g_object_get_data(G_OBJECT(widget), "arguments"); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); GtkListStore *store; GtkTreeIter iter; store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(widget))); GList *list = gtk_tree_selection_get_selected_rows(selection, 0); GList *i = list; while (i) { gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, (GtkTreePath*) (i->data)); execute_replace_callback(store, &iter, args, callback, userdata); i = g_list_next(i); } g_list_foreach(list, (GFunc)gtk_tree_path_free, nullptr); g_list_free(list); return 0; } gint32 palette_list_forfirst_selected(GtkWidget* widget, PaletteListCallback callback, void *userdata) { ListPaletteArgs* args = (ListPaletteArgs*)g_object_get_data(G_OBJECT(widget), "arguments"); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); GtkListStore *store; GtkTreeIter iter; store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(widget))); GList *list = gtk_tree_selection_get_selected_rows(selection, 0); GList *i = list; if (i) { gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, (GtkTreePath*) (i->data)); execute_callback(store, &iter, args, callback, userdata); } g_list_foreach(list, (GFunc)gtk_tree_path_free, nullptr); g_list_free(list); return 0; } ColorObject *palette_list_get_first_selected(GtkWidget* widget) { GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); GList *list = gtk_tree_selection_get_selected_rows(selection, 0); GList *i = list; ColorObject *color_object = nullptr; if (i){ GtkTreeIter iter; gtk_tree_model_get_iter(model, &iter, reinterpret_cast(i->data)); gtk_tree_model_get(model, &iter, 0, &color_object, -1); } g_list_foreach(list, (GFunc)gtk_tree_path_free, nullptr); g_list_free(list); return color_object; } void palette_list_update_first_selected(GtkWidget* widget, bool only_name) { ListPaletteArgs* args = (ListPaletteArgs*)g_object_get_data(G_OBJECT(widget), "arguments"); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); GList *list = gtk_tree_selection_get_selected_rows(selection, 0); GList *i = list; ColorObject *color_object = nullptr; if (i){ GtkTreeIter iter; gtk_tree_model_get_iter(model, &iter, reinterpret_cast(i->data)); gtk_tree_model_get(model, &iter, 0, &color_object, -1); if (only_name) palette_list_entry_update_name(GTK_LIST_STORE(model), &iter, color_object); else palette_list_entry_update_row(GTK_LIST_STORE(model), &iter, color_object, args); } g_list_foreach(list, (GFunc)gtk_tree_path_free, nullptr); g_list_free(list); } void palette_list_append_copy_menu(GtkWidget* widget, GtkWidget *menu) { auto args = reinterpret_cast(g_object_get_data(G_OBJECT(widget), "arguments")); StandardMenu::appendMenu(menu, args, args->gs); } gpick-gpick-0.2.6/source/uiListPalette.h000066400000000000000000000064461377073231300201700ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_UI_LIST_PALETTE_H_ #define GPICK_UI_LIST_PALETTE_H_ #include struct GlobalState; struct ColorObject; struct ColorList; GtkWidget* palette_list_new(GlobalState* gs, GtkWidget* count_label); void palette_list_add_entry(GtkWidget* widget, ColorObject *color_object); GtkWidget* palette_list_preview_new(GlobalState* gs, bool expander, bool expanded, ColorList* color_list, ColorList** out_color_list); GtkWidget* palette_list_get_widget(ColorList *color_list); void palette_list_remove_all_entries(GtkWidget* widget); void palette_list_remove_selected_entries(GtkWidget* widget); int palette_list_remove_entry(GtkWidget* widget, ColorObject *color_object); enum PaletteListCallbackReturn { PALETTE_LIST_CALLBACK_NO_UPDATE = 0, PALETTE_LIST_CALLBACK_UPDATE_ROW = 1, PALETTE_LIST_CALLBACK_UPDATE_NAME = 2, }; typedef PaletteListCallbackReturn (*PaletteListCallback)(ColorObject* color_object, void *userdata); typedef PaletteListCallbackReturn (*PaletteListReplaceCallback)(ColorObject** color_object, void *userdata); gint32 palette_list_foreach_selected(GtkWidget* widget, PaletteListCallback callback, void *userdata); gint32 palette_list_foreach_selected(GtkWidget* widget, PaletteListReplaceCallback callback, void *userdata); gint32 palette_list_forfirst_selected(GtkWidget* widget, PaletteListCallback callback, void *userdata); gint32 palette_list_foreach(GtkWidget* widget, PaletteListCallback callback, void *userdata); gint32 palette_list_get_selected_count(GtkWidget* widget); gint32 palette_list_get_count(GtkWidget* widget); ColorObject *palette_list_get_first_selected(GtkWidget* widget); void palette_list_update_first_selected(GtkWidget* widget, bool only_name); void palette_list_append_copy_menu(GtkWidget* widget, GtkWidget *menu); #endif /* GPICK_UI_LIST_PALETTE_H_ */ gpick-gpick-0.2.6/source/uiStatusIcon.cpp000066400000000000000000000102151377073231300203520ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "uiStatusIcon.h" #include "gtk/Zoomed.h" #include "gtk/ColorWidget.h" #include "uiUtilities.h" #include "uiApp.h" #include "GlobalState.h" #include "ColorPicker.h" #include "FloatingPicker.h" #include "Converter.h" #include "dynv/Map.h" #include "I18N.h" #include using namespace math; struct uiStatusIcon { GtkWidget *parent; GtkStatusIcon *status_icon; FloatingPicker floating_picker; GlobalState *gs; }; static void status_icon_destroy_parent(GtkWidget *, uiStatusIcon* si) { gtk_widget_destroy(GTK_WIDGET(si->parent)); } static void status_icon_show_parent(GtkWidget *, uiStatusIcon* si) { floating_picker_deactivate(si->floating_picker); status_icon_set_visible(si, false); auto options = si->gs->settings().getOrCreateMap("gpick.main"); main_show_window(si->parent, options); } static void status_icon_popup(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data) { struct uiStatusIcon* si = (struct uiStatusIcon*)user_data; auto menu = gtk_menu_new(); auto item = newMenuItem(_("_Show Main Window"), "gpick"); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(status_icon_show_parent), si); gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); item = newMenuItem(_("_Quit"), GTK_STOCK_QUIT); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(status_icon_destroy_parent), si); showContextMenu(menu, nullptr); } static void status_icon_activate(GtkWidget *widget, gpointer user_data) { struct uiStatusIcon* si = (struct uiStatusIcon*)user_data; floating_picker_activate(si->floating_picker, false, false, nullptr); } void status_icon_set_visible(struct uiStatusIcon* si, bool visible) { if (visible == false){ floating_picker_deactivate(si->floating_picker); } gtk_status_icon_set_visible(si->status_icon, visible); } struct uiStatusIcon* status_icon_new(GtkWidget* parent, GlobalState* gs, FloatingPicker floating_picker) { struct uiStatusIcon *si = new struct uiStatusIcon; si->gs = gs; si->parent = gtk_widget_get_toplevel(parent); GtkStatusIcon *status_icon = gtk_status_icon_new(); gtk_status_icon_set_visible(status_icon, FALSE); gtk_status_icon_set_from_icon_name(status_icon, "gpick-tray"); g_signal_connect(G_OBJECT(status_icon), "popup-menu", G_CALLBACK(status_icon_popup), si); #ifndef WIN32 g_signal_connect(G_OBJECT(status_icon), "activate", G_CALLBACK(status_icon_activate), si); #endif si->floating_picker = floating_picker; si->status_icon = status_icon; return si; } void status_icon_destroy(struct uiStatusIcon* si) { delete si; } gpick-gpick-0.2.6/source/uiStatusIcon.h000066400000000000000000000036341377073231300200260ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_UI_STATUS_ICON_H_ #define GPICK_UI_STATUS_ICON_H_ #include "FloatingPicker.h" #include struct GlobalState; struct uiStatusIcon; uiStatusIcon* status_icon_new(GtkWidget* parent, GlobalState* gs, FloatingPicker floating_picker); void status_icon_set_visible(uiStatusIcon* si, bool visible); void status_icon_destroy(uiStatusIcon* si); #endif /* GPICK_UI_STATUS_ICON_H_ */ gpick-gpick-0.2.6/source/uiTransformations.cpp000066400000000000000000000400431377073231300214510ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "uiTransformations.h" #include "Converter.h" #include "uiUtilities.h" #include "dynv/Map.h" #include "GlobalState.h" #include "I18N.h" #include "transformation/Chain.h" #include "transformation/Factory.h" #include "transformation/ColorVisionDeficiency.h" #include using namespace std; enum TransformationsColumns { TRANSFORMATIONS_HUMAN_NAME = 0, TRANSFORMATIONS_TRANSFORMATION_PTR, TRANSFORMATIONS_N_COLUMNS }; enum AvailableTransformationsColumns { AVAILABLE_TRANSFORMATIONS_HUMAN_NAME = 0, AVAILABLE_TRANSFORMATIONS_NAME, AVAILABLE_TRANSFORMATIONS_N_COLUMNS }; struct TransformationsArgs { GtkWidget *available_transformations; GtkWidget *transformation_list; GtkWidget *config_vbox; GtkWidget *vpaned; GtkWidget *configuration_label; GtkWidget *enabled; transformation::Transformation *transformation; std::unique_ptr configuration; dynv::Ref options; GlobalState *gs; }; static void configure_transformation(TransformationsArgs *args, transformation::Transformation *transformation); static void tranformations_update_row(GtkTreeModel *model, GtkTreeIter *iter1, transformation::Transformation *transformation, TransformationsArgs *args) { gtk_list_store_set(GTK_LIST_STORE(model), iter1, TRANSFORMATIONS_HUMAN_NAME, transformation->getReadableName().c_str(), TRANSFORMATIONS_TRANSFORMATION_PTR, transformation, -1); } static void available_tranformations_update_row(GtkTreeModel *model, GtkTreeIter *iter1, transformation::Factory::TypeInfo *type_info, TransformationsArgs *args) { gtk_list_store_set(GTK_LIST_STORE(model), iter1, AVAILABLE_TRANSFORMATIONS_HUMAN_NAME, type_info->name, AVAILABLE_TRANSFORMATIONS_NAME, type_info->id, -1); } static void available_transformation_row_activated(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, TransformationsArgs *args) { GtkTreeModel* model; GtkTreeIter iter; model = gtk_tree_view_get_model(tree_view); gtk_tree_model_get_iter(model, &iter, path); gchar *name = 0; gtk_tree_model_get(model, &iter, AVAILABLE_TRANSFORMATIONS_NAME, &name, -1); auto transformation = transformation::Factory::create(name); if (transformation){ auto chain = args->gs->getTransformationChain(); configure_transformation(args, transformation.get()); model = gtk_tree_view_get_model(GTK_TREE_VIEW(args->transformation_list)); gtk_list_store_append(GTK_LIST_STORE(model), &iter); tranformations_update_row(model, &iter, transformation.get(), args); chain->add(std::move(transformation)); } } static void add_transformation_cb(GtkWidget *widget, TransformationsArgs *args) { GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(args->available_transformations)); GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(args->available_transformations)); GtkTreeIter iter; if (gtk_tree_selection_count_selected_rows(selection) == 0){ return; } GList *list = gtk_tree_selection_get_selected_rows(selection, 0); GList *i = list; while (i) { gtk_tree_model_get_iter(model, &iter, (GtkTreePath*)i->data); gchar *name = 0; gtk_tree_model_get(model, &iter, AVAILABLE_TRANSFORMATIONS_NAME, &name, -1); auto transformation = transformation::Factory::create(name); if (transformation){ auto chain = args->gs->getTransformationChain(); configure_transformation(args, transformation.get()); model = gtk_tree_view_get_model(GTK_TREE_VIEW(args->transformation_list)); gtk_list_store_append(GTK_LIST_STORE(model), &iter); tranformations_update_row(model, &iter, transformation.get(), args); chain->add(std::move(transformation)); } i = g_list_next(i); } g_list_foreach(list, (GFunc)gtk_tree_path_free, nullptr); g_list_free(list); } static void remove_transformation_cb(GtkWidget *widget, TransformationsArgs *args) { GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(args->transformation_list)); GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(args->transformation_list)); GtkTreeIter iter; if (gtk_tree_selection_count_selected_rows(selection) == 0){ return; } configure_transformation(args, nullptr); GList *list = gtk_tree_selection_get_selected_rows(selection, 0); GList *ref_list = nullptr; GList *i = list; while (i) { ref_list = g_list_prepend(ref_list, gtk_tree_row_reference_new(model, (GtkTreePath*) (i->data))); i = g_list_next(i); } auto chain = args->gs->getTransformationChain(); i = ref_list; GtkTreePath *path; while (i) { path = gtk_tree_row_reference_get_path((GtkTreeRowReference*)i->data); if (path) { gtk_tree_model_get_iter(model, &iter, path); gtk_tree_path_free(path); transformation::Transformation *transformation; gtk_tree_model_get(model, &iter, TRANSFORMATIONS_TRANSFORMATION_PTR, &transformation, -1); chain->remove(transformation); gtk_list_store_remove(GTK_LIST_STORE(model), &iter); } i = g_list_next(i); } g_list_foreach(ref_list, (GFunc)gtk_tree_row_reference_free, nullptr); g_list_free(ref_list); g_list_foreach(list, (GFunc)gtk_tree_path_free, nullptr); g_list_free(list); } static GtkWidget* transformations_list_new(bool selection_list) { GtkListStore *store; GtkCellRenderer *renderer; GtkTreeViewColumn *col; GtkWidget *view; view = gtk_tree_view_new(); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), 1); if (selection_list){ store = gtk_list_store_new(AVAILABLE_TRANSFORMATIONS_N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING); }else{ store = gtk_list_store_new(TRANSFORMATIONS_N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER); } col = gtk_tree_view_column_new(); gtk_tree_view_column_set_sizing(col,GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_resizable(col, 1); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(col, renderer, true); gtk_tree_view_append_column(GTK_TREE_VIEW(view), col); if (selection_list){ gtk_tree_view_column_set_title(col, _("Available filters")); gtk_tree_view_column_add_attribute(col, renderer, "text", AVAILABLE_TRANSFORMATIONS_HUMAN_NAME); }else{ gtk_tree_view_column_set_title(col, _("Active filters")); gtk_tree_view_column_add_attribute(col, renderer, "text", TRANSFORMATIONS_HUMAN_NAME); } gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store)); g_object_unref(GTK_TREE_MODEL(store)); if (!selection_list){ GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); gtk_tree_view_set_reorderable(GTK_TREE_VIEW(view), true); } return view; } static void apply_configuration(TransformationsArgs *args) { if (args->configuration && args->transformation) { dynv::Map options; args->configuration->apply(options); args->transformation->deserialize(options); } } static void configure_transformation(TransformationsArgs *args, transformation::Transformation *transformation) { if (args->configuration){ gtk_container_remove(GTK_CONTAINER(args->config_vbox), args->configuration->getWidget()); apply_configuration(args); args->configuration.reset(); } if (transformation){ gtk_label_set_text(GTK_LABEL(args->configuration_label), transformation->getReadableName().c_str()); args->configuration = std::move(transformation->getConfiguration()); args->transformation = transformation; gtk_box_pack_start(GTK_BOX(args->config_vbox), args->configuration->getWidget(), true, true, 0); }else{ gtk_label_set_text(GTK_LABEL(args->configuration_label), _("No filter selected")); } } static void transformation_chain_cursor_changed(GtkWidget *widget, TransformationsArgs *args) { GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(args->transformation_list)); GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(args->transformation_list)); GtkTreeIter iter; if (gtk_tree_selection_count_selected_rows(selection) == 0){ return; } configure_transformation(args, nullptr); GList *list = gtk_tree_selection_get_selected_rows(selection, 0); GList *i = list; if (i) { gtk_tree_model_get_iter(model, &iter, (GtkTreePath*)i->data); transformation::Transformation *transformation; gtk_tree_model_get(model, &iter, TRANSFORMATIONS_TRANSFORMATION_PTR, &transformation, -1); configure_transformation(args, transformation); } g_list_foreach(list, (GFunc)gtk_tree_path_free, nullptr); g_list_free(list); } static void transformation_chain_row_activated(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, TransformationsArgs *args) { GtkTreeModel* model; GtkTreeIter iter; model = gtk_tree_view_get_model(tree_view); gtk_tree_model_get_iter(model, &iter, path); transformation::Transformation *transformation; gtk_tree_model_get(model, &iter, TRANSFORMATIONS_TRANSFORMATION_PTR, &transformation, -1); configure_transformation(args, transformation); } void dialog_transformations_show(GtkWindow* parent, GlobalState* gs) { TransformationsArgs *args = new TransformationsArgs; args->gs = gs; args->options = args->gs->settings().getOrCreateMap("gpick.transformations"); args->transformation = 0; GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Display filters"), parent, GtkDialogFlags(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, nullptr); gtk_window_set_default_size(GTK_WINDOW(dialog), args->options->getInt32("window.width", -1), args->options->getInt32("window.height", -1)); gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); GtkWidget* vbox = gtk_vbox_new(false, 5); GtkWidget *widget = args->enabled = gtk_check_button_new_with_mnemonic(_("_Enable display filters")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), args->options->getBool("enabled", false)); gtk_box_pack_start(GTK_BOX(vbox), args->enabled, false, false, 0); args->vpaned = gtk_vpaned_new(); gtk_box_pack_start(GTK_BOX(vbox), args->vpaned, true, true, 0); GtkWidget *hbox = gtk_hbox_new(false, 5); GtkWidget *list = args->available_transformations = transformations_list_new(true); g_signal_connect(G_OBJECT(list), "row-activated", G_CALLBACK(available_transformation_row_activated), args); GtkWidget *scrolled = gtk_scrolled_window_new(0, 0); gtk_container_add(GTK_CONTAINER(scrolled), list); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start(GTK_BOX(hbox), scrolled, true, true, 0); GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list)); vector types = transformation::Factory::getAllTypes(); for (size_t i = 0; i != types.size(); i++){ GtkTreeIter iter; gtk_list_store_append(GTK_LIST_STORE(model), &iter); available_tranformations_update_row(model, &iter, &types[i], args); } GtkWidget *vbox3 = gtk_vbox_new(5, true); GtkWidget *button = gtk_button_new_from_stock(GTK_STOCK_ADD); gtk_box_pack_start(GTK_BOX(vbox3), button, false, false, 0); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(add_transformation_cb), args); button = gtk_button_new_from_stock(GTK_STOCK_REMOVE); gtk_box_pack_start(GTK_BOX(vbox3), button, false, false, 0); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(remove_transformation_cb), args); gtk_box_pack_start(GTK_BOX(hbox), vbox3, false, false, 0); args->transformation_list = list = transformations_list_new(false); g_signal_connect(G_OBJECT(list), "row-activated", G_CALLBACK(transformation_chain_row_activated), args); g_signal_connect(G_OBJECT(list), "cursor-changed", G_CALLBACK(transformation_chain_cursor_changed), args); scrolled = gtk_scrolled_window_new(0, 0); gtk_container_add(GTK_CONTAINER(scrolled), list); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start(GTK_BOX(hbox), scrolled, true, true, 0); gtk_paned_pack1(GTK_PANED(args->vpaned), hbox, false, false); GtkWidget *config_wrap_vbox = gtk_vbox_new(false, 5); args->configuration_label = gtk_label_new(_("No filter selected")); gtk_box_pack_start(GTK_BOX(config_wrap_vbox), gtk_widget_aligned_new(args->configuration_label, 0, 0.5, 0, 0), false, false, 5); args->config_vbox = gtk_vbox_new(false, 5); gtk_box_pack_start(GTK_BOX(config_wrap_vbox), args->config_vbox, true, true, 0); gtk_paned_pack2(GTK_PANED(args->vpaned), config_wrap_vbox, false, false); auto chain = args->gs->getTransformationChain(); model = gtk_tree_view_get_model(GTK_TREE_VIEW(list)); for (auto &transformation: chain->getAll()) { GtkTreeIter iter; gtk_list_store_append(GTK_LIST_STORE(model), &iter); tranformations_update_row(model, &iter, transformation.get(), args); } gtk_paned_set_position(GTK_PANED(args->vpaned), args->options->getInt32("paned_position", -1)); gtk_widget_show_all(vbox); setDialogContent(dialog, vbox); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK){ apply_configuration(args); GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list))); GtkTreeIter iter; bool valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter); bool enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(args->enabled)); args->options->set("enabled", enabled); chain->setEnabled(enabled); size_t count = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), nullptr); if (count > 0) { std::vector configurations(count); size_t i = 0; while (valid) { transformation::Transformation* transformation; gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, TRANSFORMATIONS_TRANSFORMATION_PTR, &transformation, -1); auto configuration = dynv::Map::create(); transformation->serialize(*configuration); configurations[i] = configuration; valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter); ++i; } args->options->set("items", configurations); } else { args->options->remove("items"); } } chain->clear(); chain->setEnabled(args->options->getBool("enabled", false)); auto configurations = args->options->getMaps("items"); for (auto &configuration: configurations) { if (!configuration) continue; auto name = configuration->getString("name", ""); if (name.empty()) continue; auto transformation = transformation::Factory::create(name.c_str()); if (!transformation) continue; transformation->deserialize(*configuration); chain->add(std::move(transformation)); } gint width, height; gtk_window_get_size(GTK_WINDOW(dialog), &width, &height); args->options->set("window.width", width); args->options->set("window.height", height); args->options->set("paned_position", gtk_paned_get_position(GTK_PANED(args->vpaned))); gtk_widget_destroy(dialog); delete args; } gpick-gpick-0.2.6/source/uiTransformations.h000066400000000000000000000033601377073231300211170ustar00rootroot00000000000000/* * Copyright (c) 2009-2016, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_UI_TRANSFORMATIONS_H_ #define GPICK_UI_TRANSFORMATIONS_H_ #include struct GlobalState; void dialog_transformations_show(GtkWindow* parent, GlobalState* gs); #endif /* GPICK_UI_TRANSFORMATIONS_H_ */ gpick-gpick-0.2.6/source/uiUtilities.cpp000066400000000000000000000137061377073231300202410ustar00rootroot00000000000000/* * Copyright (c) 2009-2019, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "uiUtilities.h" GtkWidget* gtk_label_aligned_new(const gchar* text, gfloat xalign, gfloat yalign, gfloat xscale, gfloat yscale) { GtkWidget *align = gtk_alignment_new(xalign, yalign, xscale, yscale); GtkWidget *label = gtk_label_new(text); gtk_container_add(GTK_CONTAINER(align), label); return align; } GtkWidget* gtk_label_mnemonic_aligned_new(const gchar* text, gfloat xalign, gfloat yalign, gfloat xscale, gfloat yscale) { GtkWidget *align = gtk_alignment_new(xalign, yalign, xscale, yscale); GtkWidget *label = gtk_label_new(""); gtk_label_set_text_with_mnemonic(GTK_LABEL(label), text); gtk_container_add(GTK_CONTAINER(align), label); return align; } GtkWidget* gtk_widget_aligned_new(GtkWidget* widget, gfloat xalign, gfloat yalign, gfloat xscale, gfloat yscale) { GtkWidget *align = gtk_alignment_new(xalign, yalign, xscale, yscale); gtk_container_add(GTK_CONTAINER(align), widget); return align; } GtkWidget *newCheckbox(const char *label, bool value) { GtkWidget *widget = gtk_check_button_new_with_label(label); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), value); return widget; } GtkWidget *newCheckbox(const std::string &label, bool value) { GtkWidget *widget = gtk_check_button_new_with_label(label.c_str()); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), value); return widget; } GtkWidget *addOption(const char *label, GtkWidget *widget, int x, int &y, GtkWidget *table) { gtk_table_attach(GTK_TABLE(table), gtk_label_aligned_new(label, 0, 0.5, 0, 0), x * 3, x * 3 + 1, y, y + 1, GTK_FILL, GTK_FILL, 3, 1); gtk_table_attach(GTK_TABLE(table), widget, 1, 2, y, y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 3, 1); y++; return widget; } GtkWidget *addOption(GtkWidget *widget, int x, int &y, GtkWidget *table) { gtk_table_attach(GTK_TABLE(table), widget, x * 3 + 1, x * 3 + 2, y, y + 1, GtkAttachOptions(GTK_FILL | GTK_EXPAND), GtkAttachOptions(GTK_FILL), 3, 1); y++; return widget; } GtkWidget *newTextView(const std::string &text) { GtkWidget *widget = gtk_text_view_new(); gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget)), text.c_str(), text.length()); return widget; } std::string getTextViewText(GtkWidget *widget) { auto buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget)); GtkTextIter start, end; gtk_text_buffer_get_start_iter(buffer, &start); gtk_text_buffer_get_end_iter(buffer, &end); gchar *text = gtk_text_buffer_get_text(buffer, &start, &end, false); std::string result(text); g_free(text); return result; } GtkWidget *newLabel(const std::string &text) { return gtk_label_aligned_new(text.c_str(), 0, 0.5, 0, 0); } guint getKeyval(const GdkEventKey &key, boost::optional latinKeysGroup) { guint keyval; gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display(gdk_display_get_default()), key.hardware_keycode, static_cast(0), latinKeysGroup ? *latinKeysGroup : 0, &keyval, nullptr, nullptr, nullptr); return keyval; } void setDialogContent(GtkWidget *dialog, GtkWidget *content) { auto contentArea = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_box_pack_start(GTK_BOX(contentArea), content, true, true, 5); gtk_widget_show_all(content); } GtkWidget *newIcon(const char *name, IconSize size) { #if GTK_MAJOR_VERSION >= 3 return gtk_image_new_from_icon_name(name, size == IconSize::menu ? GTK_ICON_SIZE_MENU : GTK_ICON_SIZE_SMALL_TOOLBAR); #else return gtk_image_new_from_stock(name, size == IconSize::menu ? GTK_ICON_SIZE_MENU : GTK_ICON_SIZE_SMALL_TOOLBAR); #endif } GtkWidget *newIcon(const char *name, int size) { #if GTK_MAJOR_VERSION >= 3 auto image = gtk_image_new_from_icon_name(name, GTK_ICON_SIZE_SMALL_TOOLBAR); #else auto image = gtk_image_new_from_stock(name, GTK_ICON_SIZE_SMALL_TOOLBAR); #endif gtk_image_set_pixel_size(GTK_IMAGE(image), size); return image; } GtkWidget *newMenuItem(const char *label, const char *iconName) { auto menuItem = gtk_image_menu_item_new_with_mnemonic(label); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuItem), newIcon(iconName, IconSize::menu)); return menuItem; } void showContextMenu(GtkWidget *menu, GdkEventButton *event) { gtk_widget_show_all(GTK_WIDGET(menu)); gint32 button, eventTime; if (event) { button = event->button; eventTime = event->time; } else { button = 0; eventTime = gtk_get_current_event_time(); } gtk_menu_popup(GTK_MENU(menu), nullptr, nullptr, nullptr, nullptr, button, eventTime); g_object_ref_sink(menu); g_object_unref(menu); } gpick-gpick-0.2.6/source/uiUtilities.h000066400000000000000000000055531377073231300177070ustar00rootroot00000000000000/* * Copyright (c) 2009-2019, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef GPICK_UI_UTILITIES_H_ #define GPICK_UI_UTILITIES_H_ #include #include #include GtkWidget* gtk_label_aligned_new(const gchar* text, gfloat xalign = 0, gfloat yalign = 0, gfloat xscale = 0, gfloat yscale = 0); GtkWidget* gtk_label_mnemonic_aligned_new(const gchar* text, gfloat xalign, gfloat yalign, gfloat xscale, gfloat yscale); GtkWidget* gtk_widget_aligned_new(GtkWidget* widget, gfloat xalign, gfloat yalign, gfloat xscale, gfloat yscale); GtkWidget *addOption(const char *label, GtkWidget *widget, int x, int &y, GtkWidget *table); GtkWidget *addOption(GtkWidget *widget, int x, int &y, GtkWidget *table); GtkWidget *newCheckbox(const char *label, bool value); GtkWidget *newCheckbox(const std::string &label, bool value); GtkWidget *newTextView(const std::string &text); std::string getTextViewText(GtkWidget *widget); GtkWidget *newLabel(const std::string &text); guint getKeyval(const GdkEventKey &key, boost::optional latinKeysGroup); void setDialogContent(GtkWidget *dialog, GtkWidget *content); enum class IconSize { toolbar, menu, }; GtkWidget *newIcon(const char *name, IconSize size); GtkWidget *newIcon(const char *name, int size); GtkWidget *newMenuItem(const char *label, const char *iconName); void showContextMenu(GtkWidget *menu, GdkEventButton *event); #endif /* GPICK_UI_UTILITIES_H_ */ gpick-gpick-0.2.6/source/version/000077500000000000000000000000001377073231300167025ustar00rootroot00000000000000gpick-gpick-0.2.6/source/version/Version.cpp000066400000000000000000000034541377073231300210410ustar00rootroot00000000000000/* * Copyright (c) 2009-2018, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Version.h" #define TO_STRING(x) #x #define T_(x) TO_STRING(x) const char* gpick_build_version = T_(BUILD_VERSION); const char* gpick_build_revision = T_(BUILD_REVISION); const char* gpick_build_date = T_(BUILD_DATE); const char* gpick_build_platform = T_(BUILD_PLATFORM); gpick-gpick-0.2.6/source/version/Version.cpp.in000066400000000000000000000034121377073231300214400ustar00rootroot00000000000000/* * Copyright (c) 2009-2018, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "version/Version.h" const char* gpick_build_version = "@GPICK_VERSION@"; const char* gpick_build_revision = "@GPICK_REVISION@"; const char* gpick_build_date = "@GPICK_BUILD_DATE@"; const char* gpick_build_platform = "@GPICK_BUILD_PLATFORM@";gpick-gpick-0.2.6/source/version/Version.h000066400000000000000000000033241377073231300205020ustar00rootroot00000000000000/* * Copyright (c) 2009-2018, Albertas Vyšniauskas * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the software author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ extern const char* gpick_build_version; extern const char* gpick_build_revision; extern const char* gpick_build_date; extern const char* gpick_build_time; extern const char* gpick_build_platform; gpick-gpick-0.2.6/source/winres/000077500000000000000000000000001377073231300165245ustar00rootroot00000000000000gpick-gpick-0.2.6/source/winres/gpick-icon.ico000066400000000000000000003330561377073231300212550ustar00rootroot00000000000000 (f@@ (B00 %J  ^p h 0n( 6[wL!o :" 2 tXڗeJ5fڮ{r{4:]}um.Qwop- 60u9yqEKBc{sQ{!n}u?U.wd,0ٿy/zx>lQ)%4is87Ѷ wrd:Qv % |k8Dl/} nJ,n6܊S hB r^4ieܲlJQBmFÚoQ2(q+/$ va CxC<2i7 OF{ni^~=67 t';zm{n{nzmrf]SCŁ>7p609ggg4 #4DTdu{{{{: #4DTdutŏB #4DTdumxxx|ʟJ #4DTdug(slllvήS #4DTdu`&]]]pѼ^ #4DTduZ$ ~QQQli #4DTduT" jBBBiu #4DTduN  lZ444gق #4DTdvHRK(((e۾ #4DTdvC =fָ... #4DTdvR 1gѲJJJ #4DTdw!!!###""" C' jˬddd$ #4DTr###&&&%%%###"""  oĤ* #4S&&&***(((&&&%%%###""" v񼓓0 3(((---+++***(((&&&%%%###"""4}§9 +++000///---+++***((('''%%%### ~ ...333222000///---+++***((('''$$$רa"///777555333222000///---+++***(((%|NNNH,.222:::888777555333222000///---+++***tttnA@...999;;;:::888777555333222000///---,,,4rS+++666888999;;;:::888777555444222000///...$$$` a(((333444666777999;;;:::888777555444222111...,,,***""" $$$///111333444666777999;;;:::888777555444222000...,,,***(((&&&$$$""",,,...///111333444666777999::::::999888666444222000...,,,***(((&&&$$$"""M )))+++,,,...///111222444666777999:::::::::888666444222000...,,,***(((&&&$$$""" &&&((()))+++,,,...///111222444555777666888::::::888666444222000...,,,***(((%%%###"""###$$$&&&''')))+++,,,...///111222444333444666888::::::888666444222000...+++***(((%%%###!!! !!!###$$$&&&''')))+++,,,...///111222000222444666888::::::888666444222000...+++)))'''%%%###!!!%!!!###$$$&&&''')))***,,,......---...000222444666888::::::888666444222///...+++)))'''%%%###!!!!!!"""$$$&&&''')))***,,,+++***,,,...000222444666888::::::888666444222///---+++)))'''%%%###!!!!!!"""$$$&&&&&&&&&(((EEE,,,...000222444666888::::::888555333111///---+++)))'''%%%###!!!p   &&&444,,,...000222444666888;;;999888555333111///---+++)))'''%%%###!!!Fr  ]G***,,,...000222555666888;;;999777555333111///---+++)))'''%%%###!!!  u o*mmm***,,,///111222555777999;;;999777555333111///---+++)))'''%%%###!!!w<IgggEEE+++---///111333555777999;;;999777555333111///---+++)))'''%%%###!!!$ ###...+++---///111333555777999;;;999777555333111///---+++)))'''%%%###!!!)))+++---///111333555777999;;;999777555333111///---+++)))'''%%%"""  /UUUvvv)))+++---///111333555777999;;;999777555333111///---+++((('''%%%"""cqqq)))+++---///111333555777999;;;999777555333111///---+++(((&&&$$$""" &222lll)))+++---///111333555777999;;;999777555333111///,,,***(((&&&$$$iii)))+++---///111333555777999;;;999777555222111///,,,***(((&&&eee)))+++---///111333555777999;;;999777555222000...,,,***((("7$$$ddd)))+++---///111333555777999;;;888666555222000...,,,***y...444+++---///111333555888999;;;888666444222000...,,,888[[[+++---///222444555888::::::888666444222000...@@@555...///222444666888::::::888666444222---m###[[[...000222444666888::::::888666444 rrrbbb222222444666888::::::888&&&TBBBBTTT666666888:::)))SSS888s777yyy~~~FFFW& gewW ???????C!?p A ???(@ !E0 3&hF^|DI#" zrX$ )$t:1.4;xD($ f|2aj"4.;X-%!ʫ$OC7AN J$ ׯ:&B7f `'  b z% Z2e1,QIK$ (F-zm{nrfPGe0,2 "bWzm{nrfbXRJq60 Er81pdzm{nrfbXRJr71 3f[pdzm{nrfbXRJt82 "ؾ\Rvlpdzm{nrfbXRJv:4  F?ڀwpdzm{nrfbXRJx;4 !׷܇~pdzm{nrfbXRJz;5 *մލpdzm{nrfbXRJ|<6 $ (Үᖎpdzm{nrfbXRJ~=7 ( 'Χ㞗pdzm{nrfbXRJ>7 - %ʟ槠pdzm{nrfbXRJ>8 (!%ŗ诪qezm{nrfbXRJ>7 #! ٭ɾe^jwlZznXcYdE?zi2-? ǏJJJ4T ǁfff#4TW sss|||)4TS aaa04TM .QQQĤ84TT  DDDʷ@4T $$$"""666Kh ***(((%%%"""1+++Ѣ7= 000///+++(((%%%ZZZ>M666555222///+++j 666;;;888555222///$$$i ///444777;;;888555333...((( u2 )))...111444777:::999666222...***&&&!!!. """'''+++...111444555888:::666222...***%%%!!!3+!!!$$$'''***...///000444888:::666222...)))%%%!!! B(!!!$$$'''%%%)))111000444888:::555222---)))%%%!!! uuu,,,000555888999555111---)))%%%!!!L Ɋkkk,,,111555999999555111---)))%%%!!!yE\\\EEE---111555999999555111---)))%%%!!!<<<---111555999999555111---((($$$ ybbb:::---111555999999555111,,,((({ ͘888---111555999888555000,,,!!! 䤤]]]---222555:::888444000P"888222666:::888444 "dddbbb999:::mooovvv' ????~A?(0` &=:'O0D$,$ Gi f>=6Bz}q-95Qj-'$\ǮF[P*a!M5/ QJ+o]4ɇ'i1*ޮV< C5* r*% w:4JBM%"1"y"N&"zm{ng\G@G!#_/h\zm{ng\RJO&"!e 9C=mazm{ng\RJP'"! lP'#אpdzm{ng\RJR'# s.ŝ辺sgzm{ng\RJT(% z1̪vkzm{ng\RJU)% 1Ȣzozm{ng\RJW*% 1Ú~tzm{ng\RJX*&"1yzm{ng\RJW*&'άJ)TjѹT)Tci%uuu_)T] o %fffk)TW i^|WWWx)T""" lGGG@@@y***&&&!!! \<<<Ɉ:\333///***IM---|;;;777333/// |222666;;;777444...### qO***...222666999999333...(((### M!!!%%%)))...111333888888333...(((### ( !!!!!!111222333888888333---((("""  D珏...333888888222---((("""c0 www...333999888222---'''""" ]]]]]]...444999888222---''' III///444999777222,,,"""{ѯ]]]///444:::777222 J!!!ᓓAAA444:::777 DDD```I^&&&... !??|??????( @  j|_a'.+Me?/,FL<@|[S){C;_-g laB3'i%ZA:F?e0,A!p60zmrfNG@M$!j_zmrfNGB .7{zmrfNGD!E##`⚓zmrfNGH#N$$\壜zmrfNGK$ V(%Y㵰zmnbB;)6ڗ[C0zzzߠ [*lll[  %^^^殿 %%%((( !PPP///555///}###444:::666... Fp'''...333888666...%%%x===000888555---%%% A\ {LLL{{{111999555---%%%ibbb111999555---)(((ż```111999444'''?777ǡZZZ;;; FMMMQQQ+++"????q!?(  ++pt?a;;'.jǩeyjR^7 AWN܍D=a,(:TNxKCb/+<R)|JAb/+Ah..pI#* ._ zzz"""---,,,:::+++NNN888---___nnn:::'''WWWzzz,,,PNG  IHDR\rf IDATxwx?N[mL1TSM6 @^ސ1Pބ6 1%`cܛdY]wҝn?vt|E>3fwF~wΈ1EQWo@Qġ(I$1jĨ(J(I$1jĨ(J(I$1jĨ(J(I$1ENH ``  uRscLMn5*.$;"2 8މ#ƘbHp6p=0)9\.18:iG/K?Oc{DZA @I*D0 v \.D$1x^^/:|>_7⒱.$ "r)p7PGVVyyydff!CaРAihhSVVw}ڵk2*++[>.1ƬsV;=?ӝ8ENNyyy{sGp!KU֭[x뭷(--eΝرF [(q7v呗nj38c)** ]ڌ |駼k^uQYYzݭo@ @镈 `'.==" 1cz*YYY-.q@ 6rJV\ɚ5kGD(--eLc7Jm^6X| 9s&gq~ס׳b VZիz: CC}}=˖->8^ҫ[dffRXXȸq1bD%K[om۶oQ˗ƘbN D$ pG>} 9sfpH/o#mܸ7x? Y|9 %.15E) L?STTĸqOʐ!C"@ '|oի;%pwB]]˗/w ˁ1;bW2hDd$0 %%>}0m4nF233C f-[ƣ>کj~G[uVr0ƜjJEDbFqq1\p{n3q'q.]j_o!rJ@qƘ7cXLmHDX`tML:~@}}=?/83fОP[[˷~ʓƘscUN+=^zz:Çg- {>c{1ʂ"'~7-"~c ddd8Hfd/ȑ#뮻5jTs#<;Vy )tFNw 8 x6"cT93ᄏ߾};rKw,iD8]1[KXG}`=9DҥKi==S6N1 SPz"r 0Ç`?pB^|N;d @B! da5cRxmt{DdO>z 6y~[SS XjU4Ù#bh2Ά[-@ @Q#".q@nn.^{-'Ony^ߖsmy.3g<vM)jJwf(&s9r)N'~_QRR5vAZ@h| (9>Caܹ-i͛7smQ^^;t9AD2E|ĿvZ~_SSSS>AG bbRtWFdee1g2WXw[FZ@^s?9SCokrw㊗#5:B^$hP tGn^믿٘|Ko&4~ZǼD#t+ZG`M934h]+++۩NÙA{̀?(Jc͌̚5 /~c6Й?@TP "2 wawͺu뺅 tCCMMpSZ`Y6jJwvarg?C=_mV-04b\PP"R ֌ӧڴ>_|%Kt;3,=ӂm5ptNN~xD5kְhѢn)4|>_hcxn$YAqq1p@hllgq1-EDƋHZ8=NnyٱcGUz[ 466R[[di=R<ʷ-VrY,"7~Gn9 HCmy?[|GABVMCk1gѩJ3Dd.{cpvX\e˞e_~5{_Dشi>("WJM w cmcp "2&񓚚:\8*l334kv}`ʔ)꿈=\߉ v }l)lY5!\ӃO/GCCCuqvR,Cxts999;ֹ}ш+83h-P[[:}@D!G?XBhhh`vP-"a4Ƭ s41dggo)X/߽ ' &*h*pKMMv磾>Bo?" `(X[y'ر?OC9ݻ***BMrA8#L$jIk} õdddx^< f.{گ墨!;;F/廻^/uuuNGs\dee Xxtcx18,ĊƓsRSSc.ṕhEc̿cg j Ƙzw٬&ѧzXFmT`Z1fo{h' ǚwXs?%W,k`Uc%p5iԄVTuARPZ!"X&?X&0`Vmuܨ#xw2te_1,&(a"`@zz:aWk@: U =n+Nc#V(kw}z_РAaWm;m5)3Lgp1)b&"x 33A9cΊ?& w9x]ap1 b."k8L`С^s{wG@>M7{+0.ƘQ͛[=k#4_3wzzl߾=T07t  C ;DPAB ]e/zM*jJX&0u ֪c>ˆ:U^?7kTB @4"2ܰe\sB;U͝h *jkkiƘQ@ @"r""yyy1";Iggu%QYYi];1ձ,Dt9xgȑ1hU&ty຅>eVcMޒ(BDN5 `PPPPȑ##6Z~ŅOx|->&t9x{AO ܉m5**OBu۷o& gz7Ǣtx#/aZO>LN'* 8q۶m<[1fkǢx(k.aX&P\\ѣc&Uu9WeNcbU6= &a๙3g?&e@%Ν;lKs15ۨ(a<dGz_={v߇z6mZ&7@@II ֭kSшkOY2VivTXro~3/###[D̹;&;K,lرcG& c  0+ӫPP!"vT-p;٭:g?Uiii"bDL4i>N[vmLo!%%%10~oAi5%4-vU X`nA㏀۷~Nۋs>9YqĴz j "2k~;_~E)))P㧵}>֒`6nt\=';;;pnJ "#6cc=vYf\.i)~eRSS3,X0oMd%ضm6mm "ܙ_DqxeG~xgr)z[_DLuuҧ~z#`yx2-[^Vk9k:l PxLrTKᇊ)Sܵa/m߾V xH8p  Z` `Æ cƢz ZHRD`ܙR{hO%%%/5N?cp}>۶mcQBcD䠨\/C X:JY.++=a„m͋~i1El۶NBoAmd%?bB|p{YOcǎ}v‰?Ě'k,(--J_@FFFpBl>0$"c/4M}۠Aȑ#$~W_ݳ~=9/ n;Cj#T5$AD?ocǎMyw/#ӧϠHoll|g~2cƌ;;߭~yiÕ{N\H- kJ5^df덾OO:餼 /$~_?ٳg ."^=Rh р0BD$xk XOYf<7'' 6u]?'.ZR k;RǠv/$\zbpU+{WeffDn;BşxP;1Ƙ{y5JJJM:pnmD"Dd& ~7gH⯭]vb^9Xi'-0=$kcKfffj@;w:Im9f7סKqXbGjΙ3ԔH⯬\zꫯj}a:cu\""p6 C1:_½mDd2>M_u=;wmΝN<8? kG‰nlSZZ԰`zz 8sۻ@GDcїkG} =ÓO?½֭/?뉏ۂU_ہ|&HOO3kp}AF #"?Ětk+k… p '#u=9~b-;ہ%՝ρ_nM5Ic6vmPD|4mM9L$~[p'D2ഹ+?B9{!??T'&@BDnI#yyy9mS /2?&'DCƘCee3ԧZ!ﰦȂC_aÆ}WDL |1o޼UOaI ,TDkx&7`9;\Җ~}8(N1bތ1Z'Hm%QB ֛r`>`پ~....:Ϳ/n#~LkN3Ƽݒi<˗ĩ;@7EDRXgFX}g,Z¾x;w/y2'À|Ƙע\40F{)*}IǚsU =csyKrss #>%KT?V9Ƙg\4m""jy>ɨt3i!J:6vi<%ٹ_^^[rZ'zc̢( Ѝ\vaѷ墋.ww^I%%%N2/d2*@7AD ׀R,o꫇z}_D̦M^0a O)%1z(1C  "$;jV[nyG|_D̚5k4i"Ew,Ŀ_g:1GdX`Dd Mn;se]vVJJ+K=_~#v؋WhGr1薌 ޡiquXC}>YfE|_D|W{a.t1(=H"2iyۇ+\99C' b 5ϕ/5FwZntsr@kn)s{꽕*wCCeզ|unn{~56֧5ݵ5[>Ę#ۍ1?c)QF ~ ⽘xuٜt8N8n4 HȿzâgKٴ5&%% ˍ+Mo0i:硱ъ,˟$s1'q*2%Fh Έ;ۏ ^۝3a#.Oc*BwGD@ ;  ~伳'0_Qߟ*r?Icc1ũȔ'D0p0x L f?& (2?:W\_S:IS@c4OMzz&_|{+(-xxR+ͬZ4U9xkk*{InN_ (=5!"`SF9{JaA̙€95\S[ªeOkv\ eǧԔxD e\c:cNoq̙BqhioSW޺2V-[HC}[LcLC)5(#"?Z <AS'Z"r3Wk _<԰} Ƙ8 n""7}&]AAġ>")a__oxl֓_şd"r-?r >Cyg +ں=Rw{vƘ8ҍP""2kD\=R‘pƌHXWTyK= /*F ]= ʉǍ/㱧SS+ N'IYDPl =1GE<x]/k&ϱ_bJR DBXfܾ1d:s"2,_as%) Bâgv}C_e Ԗ8I~%.(!:±l1 y??Jůt5p<((lW4ؓ[(H?D' s*@zz>j)>p U$D Ap\/mu1E@ I? <+-(~]QcPS' _W+B 5?p>].7xyR\}%-  'I)J;fsof"wܼ~EDnw\W+7 ZZ^3񧤤%V˚%Wvf,@N#~o/4hu1Ej!H> 'wHg/ ɯWv5qr&\v][ۿ 4gs?<6\]חXx$%j4gsPP8:aⷶ~"tOuO%ڨ4@4 JkjB| 5N'v]J,Pk}Ƒ%{˜AxTmdղE}uNoa[b(?1⯪XϷw~8SP5&t3%|)Ze'JAAMe%߰vA?64'J2ālxMK?\i -JRH0+|]/v|L90F JQ8 H4e$.2<*YΈkken$ 8Y|(Iz'?c,~-Tmv+u5۩DU)_`s3(HzN2ufQQҒ(+YFyJ*IvwcjE jpÊdlۿ`gWڹ6X |<{BR0t eÿY|Tmj/;`eЗxJRo."fzbRR3X#[2 ~/BNHzbPP4N݀=ƘmqME)=oLcKxeMQB2Cc>IM)JIg7c̮ݕğ4B p1vW^I5D$ ?؎1ޒ$dFp읨QDT5qIc̹3EI V5 ܻ`N"gnJQEL10s\3kܙ$1w8R`)0z"2&ҏ7 "'G00>^O`- ߄ܠ$^ ("XS{!8Xg`2=1xˊ7p0g^ZO' 0+X HnI=*JB5zO j(p>y%c1aE%w|R pY:q%I5) /}y9}੭5} ;No܅?~Yy'vƃ5?*J " >ӯ \=VTӼ3G;\fOV^K4~k= ZZqgE;DX`*SO M]L]Hσ:) E'Dd p,OC _ tnf}?7 *JWmk~L[k04d9N} $(o"28 ?hwi!'X0? '+c#E=GWxʇzC ?{^vsCQz=-.àp3s hzX]t / ű̓ēmHN> RAў+]jӡ`ssD$3R i_L;38I)(J`?`h4lf. T6Tzl=fb=͙jM yaQNrG+)J'@SF JI-t¾ٰ_Ob+E#=Ddpc"=1'`0.1TϋU%^HkU?9fUj;!%p+"Cb9E=&L=*(i0y緅 D`G&;=Rxӳ F-βM%DO hgLQI3&0@@<`w B~x3(q0gqL&dh($=RDzb* 3 OPܐtǪNn_t('@E}oXmL:XzEjߊV D2m4 yS < 27.Q˙ęhkGhu?#N^4S Q5ƒCL &jޏcq`)*M0_(k.٘$L\6`gL3(1"6LW9*Z?]70} lz5Ƙpg)J@z_ X_juA01(Y|Ccȱul[cqȲĄY0Ƭ֋5Ut ߑ7_Hp\h|Y%8>7eIQJl8A;@6Gww6|o\e˝cމC%ht"{MѶ l/~{.%P1,O%x~/kpFO!%PU %V(_a?6lu~%^ pqmN5{+^e" v~@:au*n oi*J{\B,ї%Ƙޞ$1EQZӓ((J(I$1jĨ(J(I$1jĨ(J(I$1jĨ(J(I$1jĨ(J(I$1j?<>DNIENDB`gpick-gpick-0.2.6/source/winres/gpick.exe.manifest000066400000000000000000000011501377073231300221260ustar00rootroot00000000000000 gpick-gpick-0.2.6/source/winres/resources.rct000066400000000000000000000012571377073231300212550ustar00rootroot000000000000001 ICON "gpick-icon.ico" 1 VERSIONINFO FILEVERSION %VERSION_COMMA% PRODUCTVERSION %VERSION_COMMA% BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN VALUE "CompanyName", "Gpick developers" VALUE "FileDescription", "Gpick - Advanced color picker" VALUE "FileVersion", "%VERSION%" VALUE "InternalName", "gpick" VALUE "LegalCopyright", "New BSD License" VALUE "OriginalFilename", "gpick.exe" VALUE "ProductName", "Gpick" VALUE "ProductVersion", "%VERSION%" VALUE "Comments", "Revision %REVISION%, built at %BUILD_DATE%" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1252 END END gpick-gpick-0.2.6/test/000077500000000000000000000000001377073231300146745ustar00rootroot00000000000000gpick-gpick-0.2.6/test/config01.xml000066400000000000000000000002101377073231300170150ustar00rootroot00000000000000
  • a
  • b
  • c
  • gpick-gpick-0.2.6/test/textImport01.txt000066400000000000000000000000171377073231300177530ustar00rootroot00000000000000color: #aabbcc gpick-gpick-0.2.6/test/textImport02.txt000066400000000000000000000000141377073231300177510ustar00rootroot00000000000000color: #abc gpick-gpick-0.2.6/test/textImport03.txt000066400000000000000000000000321377073231300177520ustar00rootroot00000000000000color: rgb(170, 187, 204) gpick-gpick-0.2.6/test/textImport04.txt000066400000000000000000000000401377073231300177520ustar00rootroot00000000000000color: rgba(170, 187, 204, 0.5) gpick-gpick-0.2.6/test/textImport05.txt000066400000000000000000000000251377073231300177560ustar00rootroot00000000000000color: 170, 187, 204 gpick-gpick-0.2.6/test/textImport06.txt000066400000000000000000000000371377073231300177620ustar00rootroot00000000000000color: 0.666667, 0.733333, 0.8 gpick-gpick-0.2.6/test/textImport07.txt000066400000000000000000000000401377073231300177550ustar00rootroot00000000000000//color: #ccbbaa color: #aabbcc gpick-gpick-0.2.6/test/textImport08.txt000066400000000000000000000000431377073231300177610ustar00rootroot00000000000000/*color: #ccbbaa */ color: #aabbcc gpick-gpick-0.2.6/test/textImport09.txt000066400000000000000000000000371377073231300177650ustar00rootroot00000000000000#color: #ccbbaa color: #aabbcc gpick-gpick-0.2.6/test/textImport10.txt000066400000000000000000000000351377073231300177530ustar00rootroot00000000000000color: 0.666667 0.733333 0.8 gpick-gpick-0.2.6/test/textImport11.txt000066400000000000000000000000401377073231300177500ustar00rootroot00000000000000color: 0.666667 0.733333 1e1000 gpick-gpick-0.2.6/tools/000077500000000000000000000000001377073231300150555ustar00rootroot00000000000000gpick-gpick-0.2.6/tools/__init__.py000066400000000000000000000001111377073231300171570ustar00rootroot00000000000000from .gpick import GpickEnvironment, WriteNsisVersion, RegexEscape, Glob gpick-gpick-0.2.6/tools/crossmingw.py000066400000000000000000000113111377073231300176170ustar00rootroot00000000000000 import os import os.path import string import SCons.Action import SCons.Builder import SCons.Defaults import SCons.Tool import SCons.Util # This is what we search for to find mingw: prefixes = SCons.Util.Split(""" mingw32- i386-mingw32msvc- i486-mingw32msvc- i586-mingw32msvc- i686-mingw32msvc- i686-w64-mingw32- """) def find(env): for prefix in prefixes: # First search in the SCons path and then the OS path: if env.WhereIs(prefix + 'gcc') or SCons.Util.WhereIs(prefix + 'gcc'): return prefix return '' def shlib_generator(target, source, env, for_signature): cmd = SCons.Util.CLVar(['$SHLINK', '$SHLINKFLAGS']) dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX') if dll: cmd.extend(['-o', dll]) cmd.extend(['$SOURCES', '$_LIBDIRFLAGS', '$_LIBFLAGS']) implib = env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX') if implib: cmd.append('-Wl,--out-implib,'+implib.get_string(for_signature)) def_target = env.FindIxes(target, 'WIN32DEFPREFIX', 'WIN32DEFSUFFIX') if def_target: cmd.append('-Wl,--output-def,'+def_target.get_string(for_signature)) return [cmd] def shlib_emitter(target, source, env): dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX') no_import_lib = env.get('no_import_lib', 0) if not dll: raise SCons.Errors.UserError, "A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX") if not no_import_lib and \ not env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX'): # Append an import library to the list of targets. target.append(env.ReplaceIxes(dll, 'SHLIBPREFIX', 'SHLIBSUFFIX', 'LIBPREFIX', 'LIBSUFFIX')) # Append a def file target if there isn't already a def file target # or a def file source. There is no option to disable def file # target emitting, because I can't figure out why someone would ever # want to turn it off. def_source = env.FindIxes(source, 'WIN32DEFPREFIX', 'WIN32DEFSUFFIX') def_target = env.FindIxes(target, 'WIN32DEFPREFIX', 'WIN32DEFSUFFIX') if not def_source and not def_target: target.append(env.ReplaceIxes(dll, 'SHLIBPREFIX', 'SHLIBSUFFIX', 'WIN32DEFPREFIX', 'WIN32DEFSUFFIX')) return (target, source) shlib_action = SCons.Action.Action(shlib_generator, generator=1) res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR') res_builder = SCons.Builder.Builder(action=res_action, suffix='.o', source_scanner=SCons.Tool.SourceFileScanner) SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan) def generate(env): mingw_prefix = find(env) if mingw_prefix: dir = os.path.dirname(env.WhereIs(mingw_prefix + 'gcc') or SCons.Util.WhereIs(mingw_prefix + 'gcc')) # The mingw bin directory must be added to the path: path = env['ENV'].get('PATH', []) if not path: path = [] if SCons.Util.is_String(path): path = path.split(os.pathsep) env['ENV']['PATH'] = os.pathsep.join([dir] + path) # Most of mingw is the same as gcc and friends... gnu_tools = ['gcc', 'g++', 'gnulink', 'ar', 'gas'] for tool in gnu_tools: SCons.Tool.Tool(tool)(env) #... but a few things differ: env['CC'] = mingw_prefix + 'gcc' env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') env['CXX'] = mingw_prefix + 'g++' env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -shared') env['SHLINKCOM'] = shlib_action env.Append(SHLIBEMITTER = [shlib_emitter]) # This line isn't required and breaks C++ linking #env['LINK'] = mingw_prefix + 'g++' env['AS'] = mingw_prefix + 'as' env['AR'] = mingw_prefix + 'ar' env['RANLIB'] = mingw_prefix + 'ranlib' env['WIN32DEFPREFIX'] = '' env['WIN32DEFSUFFIX'] = '.def' env['SHOBJSUFFIX'] = '.o' env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 env['RC'] = mingw_prefix + 'windres' env['RCFLAGS'] = SCons.Util.CLVar('') env['RCINCFLAGS'] = '$( ${_concat(RCINCPREFIX, CPPPATH, RCINCSUFFIX, __env__, RDirs, TARGET)} $)' env['RCINCPREFIX'] = '--include-dir ' env['RCINCSUFFIX'] = '' env['RCCOM'] = '$RC $RCINCFLAGS $RCINCPREFIX $SOURCE.dir $RCFLAGS -i $SOURCE -o $TARGET' env['BUILDERS']['RES'] = res_builder # Some setting from the platform also have to be overridden: env['OBJPREFIX'] = '' env['OBJSUFFIX'] = '.o' env['LIBPREFIX'] = 'lib' env['LIBSUFFIX'] = '.a' env['SHOBJPREFIX'] = '$OBJPREFIX' env['SHOBJSUFFIX'] = '$OBJSUFFIX' env['PROGPREFIX'] = '' env['PROGSUFFIX'] = '.exe' env['LIBPREFIX'] = '' env['LIBSUFFIX'] = '.lib' env['SHLIBPREFIX'] = '' env['SHLIBSUFFIX'] = '.dll' env['LIBPREFIXES'] = [ '$LIBPREFIX' ] env['LIBSUFFIXES'] = [ '$LIBSUFFIX' ] def exists(env): return find(env) gpick-gpick-0.2.6/tools/gettext.py000066400000000000000000000023431377073231300171150ustar00rootroot00000000000000from SCons.Script import Builder from SCons.Action import Action def addGettextBuilder(env): env.Append(BUILDERS = { 'Gettext': Builder( action = Action("$GETTEXTCOM", "$GETTEXTCOMSTR"), suffix = '.mo', src_suffix = '.po', single_source = True, ), 'Xgettext': Builder( action = Action("$XGETTEXTCOM", "$XGETTEXTCOMSTR"), suffix = '.pot', src_suffix = '.cpp', single_source = False, ), 'Msgmerge': Builder( action = Action("$MSGMERGECOM", "$MSGMERGECOMSTR"), suffix = '.pot', src_suffix = '.pot', single_source = False, ), 'Msgcat': Builder( action = Action("$MSGCATCOM", "$MSGCATCOMSTR"), suffix = '.pot', src_suffix = '.pot', single_source = False, ), }) env["GETTEXT"] = env.Detect("msgfmt") env["GETTEXTCOM"] = "$GETTEXT --check-format --check-domain -f -o $TARGET $SOURCE" env["XGETTEXT"] = env.Detect("xgettext") env["XGETTEXTCOM"] = "$XGETTEXT --keyword=_ --from-code utf-8 --package-name=gpick $XGETTEXT_FLAGS --output=$TARGET $SOURCES" env["MSGMERGE"] = env.Detect("msgmerge") env["MSGMERGECOM"] = "$MSGMERGE $MSGMERGE_FLAGS --output-file=$TARGET $SOURCES" env["MSGCAT"] = env.Detect("msgcat") env["MSGCATCOM"] = "$MSGCAT $MSGCAT_FLAGS --output-file=$TARGET $SOURCES" gpick-gpick-0.2.6/tools/gpick.py000066400000000000000000000135461377073231300165350ustar00rootroot00000000000000import os, time, re, string, glob, subprocess from .gettext import * from .resource_template import * from .ragel import * from .template import * from SCons.Script import Chmod, Flatten from SCons.Util import NodeList from SCons.Script.SConscript import SConsEnvironment def MatchFiles (files, path, repath, dir_exclude_pattern, file_exclude_pattern): for filename in os.listdir(path): fullname = os.path.join (path, filename) repath_file = os.path.join (repath, filename); if os.path.isdir (fullname): if not dir_exclude_pattern.search(repath_file): MatchFiles (files, fullname, repath_file, dir_exclude_pattern, file_exclude_pattern) else: if not file_exclude_pattern.search(filename): files.append (fullname) def CheckPKG(context, name): context.Message('Checking for library %s... ' % name) ret = context.TryAction('pkg-config --exists "%s"' % name)[0] context.Result(ret) return ret def CheckProgram(context, env, name, member_name): context.Message('Checking for program %s... ' % name) if env[member_name]: context.Result(True) return True else: context.Result(False) return False def CompareVersions(a, b): for i in range(0, min(len(a), len(b))): if a[i] < b[i]: return 1 if a[i] > b[i]: return -1 return 0 def CheckBoost(context, version): context.Message('Checking for library boost >= %s... ' % (version)) result, boost_version = context.TryRun(""" #include #include int main(){ std::cout << BOOST_LIB_VERSION << std::endl; return 0; } """, '.cpp') if result: found_version = boost_version.strip('\r\n\t ').split('_') required_version = version.strip('\r\n\t ').split('.') result = CompareVersions(required_version, found_version) >= 0 context.Result(result) return result class GpickLibrary(NodeList): include_dirs = [] class GpickEnvironment(SConsEnvironment): extern_libs = {} def AddCustomBuilders(self): addGettextBuilder(self) addResourceTemplateBuilder(self) addTemplateBuilder(self) addRagelBuilder(self) def DefineLibrary(self, library_name, library): self.extern_libs[library_name] = library def UseLibrary(self, library_name): lib = self.extern_libs[library_name] for i in lib: lib_include_path = os.path.split(i.path)[0] self.PrependUnique(LIBS = [library_name], LIBPATH = ['#' + lib_include_path]) self.PrependUnique(CPPPATH = lib.include_dirs) return lib def ConfirmPrograms(self, conf, programs): conf.AddTests({'CheckProgram': CheckProgram}) for evar, args in programs.items(): found = False for name, member_name in args['checks'].items(): if conf.CheckProgram(self, name, member_name): found = True; break if not found: if 'required' in args: if not args['required']==False: self.Exit(1) else: self.Exit(1) def ConfirmLibs(self, conf, libs): conf.AddTests({'CheckPKG': CheckPKG}) for evar, args in libs.items(): found = False for name, version in args['checks'].items(): if conf.CheckPKG(name + ' ' + version): self[evar]=name found = True; break if not found: if 'required' in args: if not args['required']==False: self.Exit(1) else: self.Exit(1) def ConfirmBoost(self, conf, version): conf.AddTests({'CheckBoost': CheckBoost}) if conf.CheckBoost(version): return else: self.Exit(1) def InstallPerm(self, dir, source, perm): obj = self.Install(dir, source) for i in obj: self.AddPostAction(i, Chmod(i, perm)) return dir def InstallPermAutoDir(self, dir, relative_dir, source, perm): for f in Flatten(source): path = dir if str(f.get_dir()).startswith(relative_dir): path = os.path.join(path, str(f.get_dir())[len(relative_dir):]) else: path = os.path.join(path, str(f.get_dir())) obj = self.Install(path, f) for i in obj: self.AddPostAction(i, Chmod(i, perm)) return dir InstallProgram = lambda self, dir, source: GpickEnvironment.InstallPerm(self, dir, source, 0o755) InstallData = lambda self, dir, source: GpickEnvironment.InstallPerm(self, dir, source, 0o644) InstallDataAutoDir = lambda self, dir, relative_dir, source: GpickEnvironment.InstallPermAutoDir(self, dir, relative_dir, source, 0o644) def GetSourceFiles(self, dir_exclude_pattern, file_exclude_pattern): dir_exclude_prog = re.compile(dir_exclude_pattern) file_exclude_prog = re.compile(file_exclude_pattern) files = [] MatchFiles(files, self.GetLaunchDir(), os.sep, dir_exclude_prog, file_exclude_prog) return files def GetVersionInfo(self): try: revision = subprocess.Popen(['git', 'show', '--no-patch', '--format="%H %ct"'], shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0] match = re.search('([\d\w]+) (\d+)', str(revision)) rev_hash = match.group(1) commit_date = time.gmtime(int(match.group(2))) rev_date = time.strftime("%Y-%m-%d", commit_date) rev_time = time.strftime("%H:%M:%S", commit_date) except: try: with open("../version.txt", "r") as version_file: lines = version_file.read().splitlines() rev_hash = lines[0] rev_date = lines[1] rev_time = lines[2] except: rev_hash = 'unknown' commit_date = time.gmtime(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))) rev_date = time.strftime("%Y-%m-%d", commit_date) rev_time = time.strftime("%H:%M:%S", commit_date) self.Replace( GPICK_BUILD_REVISION = rev_hash[0:10], GPICK_BUILD_DATE = rev_date, GPICK_BUILD_TIME = rev_time, ); def RegexEscape(str): return str.replace('\\', '\\\\') def WriteNsisVersion(target, source, env): for t in target: for s in source: file = open(str(t),"w") file.writelines('!define VERSION "' + str(env['GPICK_BUILD_VERSION']) + '"') file.close() return 0 def Glob(path): files = [] for f in glob.glob(os.path.join(path, '*')): if os.path.isdir(str(f)): files.extend(Glob(str(f))); else: files.append(str(f)); return files gpick-gpick-0.2.6/tools/ragel.py000066400000000000000000000006031377073231300165200ustar00rootroot00000000000000from SCons.Script import Builder from SCons.Action import Action def addRagelBuilder(env): env.Append(BUILDERS = { 'Ragel': Builder( action = Action("$RAGELCOM", "$RAGELCOMSTR"), suffix = '.cpp', src_suffix = '.rl', single_source = True, ), }) env["RAGEL"] = env.Detect("ragel") env["RAGELCOM"] = "$RAGEL $RAGELFLAGS -o $TARGET $SOURCE" env["RAGELFLAGS"] = "-F1 -C" gpick-gpick-0.2.6/tools/resource_template.py000066400000000000000000000013621377073231300211530ustar00rootroot00000000000000import re from SCons.Script import Builder from SCons.Action import Action def addResourceTemplateBuilder(env): def buildResourceFile(target, source, env): source_dest = SCons.Util.splitext(str(target[0]))[0] + ".rc" wfile = open(source_dest,"w") data = open(str(File(source[0]).srcnode())).read() for key, var in env['RESOURCE_TEMPLATE_VARS'].iteritems(): data = re.sub("%" + key + "%", var, data) wfile.write(data) wfile.close() return 0 def buildResourceFileString(target, source, env): return "Preparing resource file %s" % os.path.basename(str(target[0])) env.Append(BUILDERS = { 'ResourceTemplate': Builder( action = Action(buildResourceFile, buildResourceFileString), suffix = '.rc', src_suffix = '.rct', ), }) gpick-gpick-0.2.6/tools/template.py000066400000000000000000000017321377073231300172450ustar00rootroot00000000000000import re, os from SCons.Script import Builder from SCons.Action import Action from SCons.Node.FS import File def addTemplateBuilder(env): def buildEmitter(target, source, env): data = open(source[0].srcnode().get_path()).read() dict = env.Dictionary() keys = dict.keys() for key in keys: if isinstance(dict[key], str): env.Depends(target, env.Value(dict[key])) return target, source def buildFile(target, source, env): source_dest = str(target[0]) wfile = open(source_dest, "w") data = open(source[0].srcnode().get_path()).read() dict = env.Dictionary() keys = dict.keys() for key in keys: if isinstance(dict[key], str): data = re.sub("%" + key + "%", dict[key], data) wfile.write(data) wfile.close() return 0 def buildString(target, source, env): return "Preparing file %s" % os.path.basename(str(target[0])) env.Append(BUILDERS = { 'Template': Builder( action = Action(buildFile, buildString), emitter = buildEmitter, ), }) gpick-gpick-0.2.6/version.py000066400000000000000000000000341377073231300157510ustar00rootroot00000000000000GPICK_BUILD_VERSION='0.2.6' gpick-gpick-0.2.6/version.template000066400000000000000000000000751377073231300171410ustar00rootroot00000000000000%GPICK_BUILD_REVISION% %GPICK_BUILD_DATE% %GPICK_BUILD_TIME%