├── screenshots
├── a.png
└── b.png
├── .gitmodules
├── src
├── res.qrc
├── kcm_colorful.desktop
├── artworks
│ ├── refresh.svg
│ ├── pallete.svg
│ └── gen-colors.svg
├── helper
│ ├── CMakeLists.txt
│ ├── mmcq.h
│ ├── kcmcolorfulhelper.h
│ ├── main.cpp
│ ├── mmcq.cpp
│ ├── colordata.h
│ └── kcmcolorfulhelper.cpp
├── CMakeLists.txt
├── kcm_colorful.h
├── qml
│ ├── Header.qml
│ ├── colors.js
│ ├── main.qml
│ ├── WButton.qml
│ ├── ColorUnitW.qml
│ ├── ColorUnit.qml
│ ├── ColorWidget.qml
│ └── Wallpaper.qml
└── kcm_colorful.cpp
├── .gitignore
├── CMakeLists.txt
├── po
├── kcm_colorful.pot
├── zh_TW.po
├── CMakeLists.txt
└── zh_CN.po
├── extract-messages.sh
├── TRANSLATING.md
├── README.md
├── README.en.md
├── schemes
├── ColorfulDark.colors
└── ColorfulLight.colors
└── LICENSE
/screenshots/a.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/THMonster/kcm-colorful/HEAD/screenshots/a.png
--------------------------------------------------------------------------------
/screenshots/b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/THMonster/kcm-colorful/HEAD/screenshots/b.png
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "plasmathemes/kde-theme-backup"]
2 | path = plasmathemes/kde-theme-backup
3 | url = https://github.com/IsoaSFlus/kde-theme-backup
4 |
--------------------------------------------------------------------------------
/src/res.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | qml/ColorUnit.qml
4 | qml/ColorWidget.qml
5 | qml/Header.qml
6 | qml/main.qml
7 | qml/Wallpaper.qml
8 | qml/WButton.qml
9 | artworks/gen-colors.svg
10 | artworks/refresh.svg
11 | qml/ColorUnitW.qml
12 | qml/colors.js
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/kcm_colorful.desktop:
--------------------------------------------------------------------------------
1 | [Desktop Entry]
2 | Exec=kcmshell5 kcm_colorful
3 | Icon=kcolorchooser
4 | Type=Service
5 |
6 | X-KDE-ServiceTypes=KCModule
7 | X-KDE-Library=kcm_colorful
8 | X-KDE-ParentApp=kcontrol
9 |
10 | X-KDE-System-Settings-Parent-Category=appearance
11 | # X-KDE-Weight=60
12 |
13 |
14 | Name=Colorful
15 | Name[zh_CN]=多彩
16 | Name[zh_TW]=多彩
17 | Comment=Make your KDE Plasma colorful
18 | Comment[zh_CN]=让您的KDE Plasma丰富多彩
19 | Comment[zh_TW]=讓您的 KDE Plasma 更多彩
20 | X-KDE-Keywords=Color, Theme
21 | X-KDE-Keywords[zh_CN]=Color, Theme,色彩,颜色,主题
22 | X-KDE-Keywords[zh_TW]=Color, Theme, 色彩, 顏色, 主題
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # C++ objects and libs
2 | *.slo
3 | *.lo
4 | *.o
5 | *.a
6 | *.la
7 | *.lai
8 | *.so
9 | *.dll
10 | *.dylib
11 |
12 | # Qt-es
13 | object_script.*.Release
14 | object_script.*.Debug
15 | *_plugin_import.cpp
16 | /.qmake.cache
17 | /.qmake.stash
18 | *.pro.user
19 | *.pro.user.*
20 | *.qbs.user
21 | *.qbs.user.*
22 | *.moc
23 | moc_*.cpp
24 | moc_*.h
25 | qrc_*.cpp
26 | ui_*.h
27 | *.qmlc
28 | *.jsc
29 | Makefile*
30 | *build-*
31 |
32 | # Qt unit tests
33 | target_wrapper.*
34 |
35 | # QtCreator
36 | *.autosave
37 |
38 | # QtCreator Qml
39 | *.qmlproject.user
40 | *.qmlproject.user.*
41 |
42 | # QtCreator CMake
43 | CMakeLists.txt.user*
44 |
45 | # Mine
46 | build/
47 |
--------------------------------------------------------------------------------
/src/artworks/refresh.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/helper/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_executable(kcmcolorfulhelper "main.cpp"
2 | "kcmcolorfulhelper.cpp"
3 | "mmcq.cpp")
4 |
5 | target_link_libraries(kcmcolorfulhelper Qt5::Core
6 | Qt5::DBus
7 | KF5::ConfigCore
8 | KF5::ConfigGui
9 | KF5::ConfigWidgets
10 | KF5::KCMUtils
11 | KF5::I18n
12 | KF5::KIOCore
13 | KF5::CoreAddons)
14 |
15 | install(TARGETS kcmcolorfulhelper DESTINATION ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
16 |
--------------------------------------------------------------------------------
/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_subdirectory(helper)
2 | include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE)
3 |
4 | #add_definitions(-DTRANSLATION_DOMAIN=\"kcm5_colorful\")
5 |
6 | set(kcm_file_SRCS
7 | kcm_colorful.cpp
8 | )
9 |
10 | qt5_add_resources(kcm_file_SRCS res.qrc)
11 | add_library(kcm_colorful MODULE ${kcm_file_SRCS})
12 | target_compile_definitions(kcm_colorful PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}")
13 | target_link_libraries(kcm_colorful
14 | KF5::KIOWidgets
15 | KF5::CoreAddons
16 | KF5::ConfigWidgets
17 | KF5::I18n
18 | KF5::Solid
19 | KF5::Declarative
20 | Qt5::Core
21 | Qt5::Gui
22 | Qt5::QuickControls2
23 | Qt5::Widgets
24 | Qt5::QuickWidgets
25 | )
26 |
27 |
28 |
29 | install(FILES kcm_colorful.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
30 | install(TARGETS kcm_colorful DESTINATION ${KDE_INSTALL_PLUGINDIR})
31 |
--------------------------------------------------------------------------------
/src/kcm_colorful.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | class KCMColorful : public KCModule
10 | {
11 | Q_OBJECT
12 | public:
13 | KCMColorful(QWidget* parent, const QVariantList& args);
14 | ~KCMColorful();
15 | void readConfig();
16 | void saveConfig();
17 | void addColorGV1(QString color);
18 |
19 |
20 |
21 |
22 | private:
23 | QQuickWidget *root_qml = nullptr;
24 | QString current_wallpaper;
25 | QStringList recent_colors;
26 | QStringList user_colors;
27 | bool extracted_flag = false;
28 | QStringList colors;
29 | QProcess *helper = nullptr;
30 | KDeclarative::KDeclarative *kdeclarative = nullptr;
31 |
32 |
33 | public Q_SLOTS:
34 | void apply_color(const QString &c);
35 | void loadExtractedColors();
36 | void runHelper();
37 | void set_wp_view();
38 | };
39 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.0)
2 | SET(CMAKE_INSTALL_PREFIX /usr CACHE PATH "Set install prefix.")
3 | project(kcm-colorful)
4 | set(PROJECT_VERSION "1.0.5")
5 |
6 | set(CMAKE_INCLUDE_CURRENT_DIR ON)
7 | set(CMAKE_AUTOMOC ON)
8 |
9 |
10 | find_package(ECM 1.0.0 REQUIRED NO_MODULE)
11 | find_package( Gettext REQUIRED )
12 | set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
13 | include(KDEInstallDirs)
14 | include(ECMInstallIcons)
15 | include(KDECMakeSettings)
16 | include(KDECompilerSettings)
17 | include(FeatureSummary)
18 |
19 | find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS Core Gui Widgets X11Extras Quick QuickControls2 QuickWidgets DBus)
20 | find_package(KF5 REQUIRED COMPONENTS
21 | CoreAddons
22 | WidgetsAddons
23 | ConfigWidgets
24 | KIO
25 | KCMUtils
26 | I18n
27 | Declarative
28 | )
29 | add_definitions(-DTRANSLATION_DOMAIN=\"kcm_colorful\")
30 |
31 | add_subdirectory(src)
32 | add_subdirectory(po)
33 |
34 | file(GLOB schemefiles schemes/*.colors)
35 | install( FILES ${schemefiles} DESTINATION ${KDE_INSTALL_DATADIR}/color-schemes )
36 | install(DIRECTORY plasmathemes/kde-theme-backup/Colorful DESTINATION ${KDE_INSTALL_DATADIR}/plasma/desktoptheme)
37 |
--------------------------------------------------------------------------------
/src/helper/mmcq.h:
--------------------------------------------------------------------------------
1 | #ifndef MMCQ_H
2 | #define MMCQ_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | class VBox
10 | {
11 | public:
12 | VBox();
13 | explicit VBox(int r1, int r2, int g1, int g2, int b1, int b2);
14 | ~VBox();
15 |
16 |
17 | int r1, g1, b1, r2, g2, b2;
18 | };
19 |
20 |
21 | class MMCQ
22 | {
23 | public:
24 | explicit MMCQ(QString file, bool debug_flag, bool kcm_flag);
25 | ~MMCQ();
26 |
27 | QList get_palette(int color_count=10, int quality=10);
28 | int get_color_index(int r, int g, int b);
29 |
30 | private:
31 | bool debug_flag = false;
32 | bool kcm_flag = false;
33 | int sigbits = 5;
34 | int rshift = 8 - sigbits;
35 | double fract_by_populations = 0.75;
36 | int max_iter = 1000;
37 | QImage *img;
38 | int h = 0;
39 | int w = 0;
40 | std::vector pixels;
41 | std::unordered_map histo;
42 |
43 | int get_vbox_color_sum(VBox v);
44 | void calc_histo();
45 | VBox gen_vbox();
46 | std::vector do_median_cut(VBox v);
47 | QColor get_vbox_avg(VBox v);
48 | std::vector quantize(int max_color);
49 |
50 | template
51 | void quantize_iter(T &t, int target);
52 |
53 | };
54 |
55 |
56 |
57 |
58 | #endif
59 |
--------------------------------------------------------------------------------
/src/qml/Header.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.2
2 |
3 | import QtQuick.Layouts 1.1
4 | import QtQuick.Controls 1.4
5 | import QtQuick.Controls.Styles 1.4
6 | import QtGraphicalEffects 1.0
7 |
8 | import org.kde.plasma.core 2.0 as PlasmaCore
9 | import org.kde.plasma.components 2.0 as PlasmaComponents
10 | import org.kde.plasma.extras 2.0 as PlasmaExtras
11 |
12 | Item {
13 | property alias text: title.text
14 | id: root
15 | implicitHeight: title.height + 10
16 |
17 | PlasmaExtras.Heading {
18 | id: title
19 | text: 'Title'
20 | level: 2
21 |
22 | anchors {
23 | top: root.top
24 | topMargin: units.smallSpacing
25 | left: root.left
26 | right: root.right
27 | }
28 |
29 | /* horizontalAlignment: Text.AlignHCenter */
30 | /* verticalAlignment: Text.AlignTop */
31 | /* wrapMode: Text.WordWrap */
32 | /* font.underline: root.activeFocus */
33 | }
34 |
35 | /* Rectangle { */
36 | /* id: line */
37 | /* anchors { */
38 | /* top: title.bottom */
39 | /* /\* topMargin: units.smallSpacing *\/ */
40 | /* left: root.left */
41 | /* right: root.right */
42 | /* } */
43 | /* /\* width: root.width *\/ */
44 | /* height: 1 */
45 | /* color: "black" */
46 | /* } */
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/po/kcm_colorful.pot:
--------------------------------------------------------------------------------
1 | # SOME DESCRIPTIVE TITLE.
2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3 | # This file is distributed under the same license as the kcm_colorful package.
4 | # FIRST AUTHOR , YEAR.
5 | #
6 | #, fuzzy
7 | msgid ""
8 | msgstr ""
9 | "Project-Id-Version: kcm_colorful\n"
10 | "Report-Msgid-Bugs-To: me@isoasflus.com\n"
11 | "POT-Creation-Date: 2019-04-04 11:28+0800\n"
12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13 | "Last-Translator: FULL NAME \n"
14 | "Language-Team: LANGUAGE \n"
15 | "Language: \n"
16 | "MIME-Version: 1.0\n"
17 | "Content-Type: text/plain; charset=CHARSET\n"
18 | "Content-Transfer-Encoding: 8bit\n"
19 |
20 | #: src/kcm_colorful.cpp:33
21 | #, kde-format
22 | msgid "Author"
23 | msgstr ""
24 |
25 | #: src/kcm_colorful.cpp:29
26 | #, kde-format
27 | msgid "Colorful"
28 | msgstr ""
29 |
30 | #: src/qml/Wallpaper.qml:164
31 | #, kde-format
32 | msgid "Generate colors based on wallpaper"
33 | msgstr ""
34 |
35 | #: src/kcm_colorful.cpp:30
36 | #, kde-format
37 | msgid "Make your KDE Plasma colorful"
38 | msgstr ""
39 |
40 | #: src/qml/main.qml:44
41 | #, kde-format
42 | msgid "Recent Colors"
43 | msgstr ""
44 |
45 | #: src/qml/main.qml:64
46 | #, kde-format
47 | msgid "Recommended Colors"
48 | msgstr ""
49 |
50 | #: src/qml/Wallpaper.qml:150
51 | #, kde-format
52 | msgid "Refresh wallpaper"
53 | msgstr ""
54 |
55 | #: src/qml/main.qml:25
56 | #, kde-format
57 | msgid "Wallpaper"
58 | msgstr ""
59 |
--------------------------------------------------------------------------------
/po/zh_TW.po:
--------------------------------------------------------------------------------
1 | # Chinese translations for kcm_colorful package.
2 | # Copyright (C) 2019 THE kcm_colorful'S COPYRIGHT HOLDER
3 | # This file is distributed under the same license as the kcm_colorful package.
4 | # pan93412 , 2019.
5 | #
6 | msgid ""
7 | msgstr ""
8 | "Project-Id-Version: kcm_colorful\n"
9 | "Report-Msgid-Bugs-To: me@isoasflus.com\n"
10 | "POT-Creation-Date: 2019-04-04 15:13+0800\n"
11 | "PO-Revision-Date: 2019-04-04 15:10+0800\n"
12 | "Last-Translator: \n"
13 | "Language-Team: Chinese (traditional)\n"
14 | "Language: zh_TW\n"
15 | "MIME-Version: 1.0\n"
16 | "Content-Type: text/plain; charset=UTF-8\n"
17 | "Content-Transfer-Encoding: 8bit\n"
18 |
19 | #: src/kcm_colorful.cpp:33
20 | #, kde-format
21 | msgid "Author"
22 | msgstr "作者"
23 |
24 | #: src/kcm_colorful.cpp:29
25 | #, kde-format
26 | msgid "Colorful"
27 | msgstr "多彩"
28 |
29 | #: src/qml/Wallpaper.qml:164
30 | #, kde-format
31 | msgid "Generate colors based on wallpaper"
32 | msgstr "產生基於桌布的顏色"
33 |
34 | #: src/kcm_colorful.cpp:30
35 | #, kde-format
36 | msgid "Make your KDE Plasma colorful"
37 | msgstr "讓您的 KDE Plasma 更加多彩"
38 |
39 | #: src/qml/main.qml:44
40 | #, kde-format
41 | msgid "Recent Colors"
42 | msgstr "最近顏色"
43 |
44 | #: src/qml/main.qml:64
45 | #, kde-format
46 | msgid "Recommended Colors"
47 | msgstr "建議顏色"
48 |
49 | #: src/qml/Wallpaper.qml:150
50 | #, kde-format
51 | msgid "Refresh wallpaper"
52 | msgstr "重新載入桌布"
53 |
54 | #: src/qml/main.qml:25
55 | #, kde-format
56 | msgid "Wallpaper"
57 | msgstr "桌布"
58 |
--------------------------------------------------------------------------------
/po/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | FIND_PROGRAM(GETTEXT_MSGFMT_EXECUTABLE msgfmt)
2 |
3 | IF(NOT GETTEXT_MSGFMT_EXECUTABLE)
4 | MESSAGE(
5 | "------
6 | NOTE: msgfmt not found. Translations will *not* be installed
7 | ------")
8 | ELSE(NOT GETTEXT_MSGFMT_EXECUTABLE)
9 |
10 | SET(catalogname kcm_colorful)
11 |
12 | ADD_CUSTOM_TARGET(translations ALL)
13 | FILE(GLOB PO_FILES *.po)
14 | # SET(GMO_FILES)
15 |
16 | FOREACH(_poFile ${PO_FILES})
17 | GET_FILENAME_COMPONENT(_poFileName ${_poFile} NAME)
18 | STRING(REGEX REPLACE "^${catalogname}_?" "" _langCode ${_poFileName} )
19 | STRING(REGEX REPLACE "\\.po$" "" _langCode ${_langCode} )
20 |
21 | IF( _langCode )
22 | GET_FILENAME_COMPONENT(_lang ${_poFile} NAME_WE)
23 | SET(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_lang}.gmo)
24 |
25 | ADD_CUSTOM_COMMAND(TARGET translations
26 | COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} --check -o ${_gmoFile} ${_poFile}
27 | DEPENDS ${_poFile})
28 | INSTALL(FILES ${_gmoFile} DESTINATION ${LOCALE_INSTALL_DIR}/${_langCode}/LC_MESSAGES/ RENAME ${catalogname}.mo)
29 | LIST(APPEND GMO_FILES ${_gmoFile})
30 | ENDIF( _langCode )
31 |
32 | ENDFOREACH(_poFile ${PO_FILES})
33 |
34 | # ADD_CUSTOM_TARGET(translations ALL DEPENDS ${GMO_FILES})
35 |
36 | ENDIF(NOT GETTEXT_MSGFMT_EXECUTABLE)
37 |
--------------------------------------------------------------------------------
/extract-messages.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | BASEDIR=$(cd `dirname $0`; pwd) # root of translatable sources
3 | PROJECT="kcm_colorful" # project name
4 | WDIR="${BASEDIR}/po" # working dir
5 |
6 |
7 | echo "Preparing rc files"
8 | cd ${BASEDIR}
9 | # we use simple sorting to make sure the lines do not jump around too much from system to system
10 | find . -name '*.rc' -o -name '*.ui' -o -name '*.kcfg'| sort > ${WDIR}/rcfiles.list
11 | xargs --arg-file=${WDIR}/rcfiles.list extractrc > ${WDIR}/rc.cpp
12 | cd ${WDIR}
13 | echo "Done preparing rc files"
14 |
15 |
16 | echo "Extracting messages"
17 | cd ${BASEDIR}
18 | # see above on sorting
19 | find . -name '*.cpp' -o -name '*.h' -o -name '*.c' -o -name '*.qml' | sort > ${WDIR}/infiles.list
20 | echo "rc.cpp" >> ${WDIR}/infiles.list
21 | cd ${WDIR}
22 | xgettext --package-name=$PROJECT --add-comments --sort-output --msgid-bugs-address=me@isoasflus.com \
23 | --from-code=UTF-8 -C --kde -ci18n -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 -ktr2i18n:1 \
24 | -kI18N_NOOP:1 -kI18N_NOOP2:1c,2 -kaliasLocale -kki18n:1 -kki18nc:1c,2 -kki18np:1,2 -kki18ncp:1c,2,3 \
25 | --files-from=infiles.list -D ${BASEDIR} -D ${WDIR} -o ${PROJECT}.pot || { echo "error while calling xgettext. aborting."; exit 1; }
26 | echo "Done extracting messages"
27 |
28 |
29 | echo "Merging translations"
30 | catalogs=`find . -name '*.po'`
31 | for cat in $catalogs; do
32 | echo $cat
33 | msgmerge -q --backup=none -U $cat ${PROJECT}.pot
34 | done
35 | echo "Done merging translations"
36 |
37 |
38 | echo "Cleaning up"
39 | cd ${WDIR}
40 | rm rcfiles.list infiles.list rc.cpp
41 | echo "All Done! :)"
42 |
--------------------------------------------------------------------------------
/po/zh_CN.po:
--------------------------------------------------------------------------------
1 | # SOME DESCRIPTIVE TITLE.
2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3 | # This file is distributed under the same license as the kcm_colorful package.
4 | # FIRST AUTHOR , YEAR.
5 | #
6 | msgid ""
7 | msgstr ""
8 | "Project-Id-Version: kcm_colorful\n"
9 | "Report-Msgid-Bugs-To: me@isoasflus.com\n"
10 | "POT-Creation-Date: 2019-04-04 11:28+0800\n"
11 | "PO-Revision-Date: 2019-04-04 11:30+0800\n"
12 | "Last-Translator: \n"
13 | "Language-Team: \n"
14 | "Language: zh_CN\n"
15 | "MIME-Version: 1.0\n"
16 | "Content-Type: text/plain; charset=UTF-8\n"
17 | "Content-Transfer-Encoding: 8bit\n"
18 | "X-Generator: Poedit 2.2.1\n"
19 |
20 | #: src/kcm_colorful.cpp:33
21 | #, kde-format
22 | msgid "Author"
23 | msgstr "作者"
24 |
25 | #: src/kcm_colorful.cpp:29
26 | #, kde-format
27 | msgid "Colorful"
28 | msgstr "多彩"
29 |
30 | #: src/qml/Wallpaper.qml:164
31 | #, kde-format
32 | msgid "Generate colors based on wallpaper"
33 | msgstr "根据当前壁纸生成色彩"
34 |
35 | #: src/kcm_colorful.cpp:30
36 | #, kde-format
37 | msgid "Make your KDE Plasma colorful"
38 | msgstr "让您的KDE丰富多彩"
39 |
40 | #: src/qml/main.qml:44
41 | #, kde-format
42 | msgid "Recent Colors"
43 | msgstr "最近使用"
44 |
45 | #: src/qml/main.qml:64
46 | #, kde-format
47 | msgid "Recommended Colors"
48 | msgstr "推荐色彩"
49 |
50 | #: src/qml/Wallpaper.qml:150
51 | #, kde-format
52 | msgid "Refresh wallpaper"
53 | msgstr "刷新壁纸"
54 |
55 | #: src/qml/main.qml:25
56 | #, kde-format
57 | msgid "Wallpaper"
58 | msgstr "壁纸"
59 |
60 | #~ msgctxt "EMAIL OF TRANSLATORS"
61 | #~ msgid "Your emails"
62 | #~ msgstr "您的邮箱"
63 |
64 | #~ msgctxt "NAME OF TRANSLATORS"
65 | #~ msgid "Your names"
66 | #~ msgstr "您的名字"
67 |
--------------------------------------------------------------------------------
/src/qml/colors.js:
--------------------------------------------------------------------------------
1 | function color_table()
2 | {
3 | return [{"name": "default", "c": "#ffffff"},
4 | {"name": "default", "c": "#000000"},
5 | {"name": "default", "c": "#FFCCCC"},
6 | {"name": "default", "c": "#FF9999"},
7 | {"name": "default", "c": "#FF6666"},
8 | {"name": "default", "c": "#CC3333"},
9 | {"name": "default", "c": "#FF0033"},
10 | {"name": "default", "c": "#FFCC99"},
11 | {"name": "default", "c": "#FF9966"},
12 | {"name": "default", "c": "#FF9900"},
13 | {"name": "default", "c": "#FF6600"},
14 | {"name": "default", "c": "#FFFF00"},
15 | {"name": "default", "c": "#CCCC33"},
16 | {"name": "default", "c": "#CCFF99"},
17 | {"name": "default", "c": "#009966"},
18 | {"name": "default", "c": "#339933"},
19 | {"name": "default", "c": "#CCCC66"},
20 | {"name": "default", "c": "#66CCCC"},
21 | {"name": "default", "c": "#66CC99"},
22 | {"name": "default", "c": "#339999"},
23 | {"name": "default", "c": "#CCFFFF"},
24 | {"name": "default", "c": "#3399CC"},
25 | {"name": "default", "c": "#99CCFF"},
26 | {"name": "default", "c": "#6699CC"},
27 | {"name": "default", "c": "#9999FF"},
28 | {"name": "default", "c": "#6666FF"},
29 | {"name": "default", "c": "#6666FF"},
30 | {"name": "default", "c": "#CCCCFF"},
31 | {"name": "default", "c": "#9966CC"},
32 | {"name": "default", "c": "#CC99CC"},
33 | {"name": "default", "c": "#FF99CC"},
34 | {"name": "default", "c": "#FF3399"}];
35 | }
36 |
--------------------------------------------------------------------------------
/src/helper/kcmcolorfulhelper.h:
--------------------------------------------------------------------------------
1 | #ifndef KCMCOLORFULHELPER_H
2 | #define KCMCOLORFULHELPER_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | #include "mmcq.h"
13 |
14 | class KcmColorfulHelper : public QObject
15 | {
16 | Q_OBJECT
17 | public:
18 | explicit KcmColorfulHelper(QStringList args, QObject *parent = nullptr);
19 | ~KcmColorfulHelper();
20 | void run();
21 |
22 | private:
23 | QList palette;
24 | QList palette_16;
25 | MMCQ *mmcq = nullptr;
26 | QColor *c = nullptr;
27 | QMap pt_and_color;
28 | QString colorSchemeName;
29 | QString prevColorSchemeName;
30 | KSharedConfigPtr mConfig;
31 | KSharedConfigPtr tConfig;
32 | QString wallpaperFilePath;
33 | int paletteNum = 8;
34 | int selectNum = 1;
35 | double theme_opacity = 0.6;
36 | uint run_type = 0x00; // bit 1 for theme opacity, bit 2 for theme color.
37 | bool kcm_flag = false;
38 | bool debug_flag = false;
39 | void getPrevCSName();
40 | void readTemplateCS();
41 | void changeColorScheme();
42 | void changeColorSchemeB(); // change ColorScheme based on user's ColorScheme file
43 | void changeColorScheme(KSharedConfigPtr config);
44 | void save();
45 | void genCSName();
46 | void saveCSFile();
47 | QColor addJitter(QColor color); // due to a stupid bug of kde;
48 | bool isDarkTheme();
49 | void calcColor();
50 | void setWallpaper(QString pic);
51 | QColor color_refine(QColor color);
52 | void changeThemeOpacity();
53 |
54 | signals:
55 |
56 | public slots:
57 | // void dealStdOut();
58 | };
59 |
60 | #endif // KCMCOLORFULHELPER_H
61 |
--------------------------------------------------------------------------------
/src/qml/main.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.2
2 |
3 | import QtQuick.Layouts 1.1
4 | import QtQuick.Controls 1.4
5 | import QtQuick.Controls.Styles 1.4
6 | import QtGraphicalEffects 1.0
7 |
8 | import org.kde.plasma.core 2.0 as PlasmaCore
9 | import org.kde.plasma.components 2.0 as PlasmaComponents
10 | import org.kde.plasma.extras 2.0 as PlasmaExtras
11 |
12 | Rectangle {
13 | id: root
14 | implicitWidth: 500
15 | implicitHeight: 700
16 | color: PlasmaCore.ColorScope.backgroundColor
17 |
18 | Header {
19 | anchors {
20 | top: parent.top
21 | left: parent.left
22 | right: parent.right
23 | }
24 | id: h1
25 | text: i18n("Wallpaper")
26 | }
27 |
28 | Wallpaper {
29 | anchors {
30 | top: h1.bottom
31 | left: parent.left
32 | right: parent.right
33 | }
34 | id: wp
35 | }
36 |
37 | Header {
38 | anchors {
39 | top: wp.bottom
40 | left: parent.left
41 | right: parent.right
42 | }
43 | id: h2
44 | text: i18n("Recent Colors")
45 | }
46 |
47 | ColorWidget {
48 | anchors {
49 | top: h2.bottom
50 | left: parent.left
51 | right: parent.right
52 | }
53 | id: recent_color
54 | cw_type: "cw1"
55 | }
56 |
57 | Header {
58 | anchors {
59 | top: recent_color.bottom
60 | left: parent.left
61 | right: parent.right
62 | }
63 | id: h3
64 | text: i18n("Recommended Colors")
65 | }
66 |
67 | ColorWidget {
68 | anchors {
69 | top: h3.bottom
70 | left: parent.left
71 | right: parent.right
72 | /* bottom: parent.bottom */
73 | }
74 | height: (units.iconSizes.medium + units.smallSpacing) * 4
75 | id: recommended_color
76 | cw_type: "cw2"
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/TRANSLATING.md:
--------------------------------------------------------------------------------
1 | # `kcm-colorful` translate tutorial
2 | ## STEP TO TRANSLATE
3 | ### 1. TRANSLATE THE PO FILE (HIGH PRIORITY)
4 | The PO file stored the string which is in settings interface, for example: "Generate colors based on wallpaper".
5 |
6 | If your language has NEVER translated, you should generate the po file of your language:
7 |
8 | ```
9 | [translate@tutorial kcm-colorful]$ bash extract-messages.sh
10 | [translate@tutorial kcm-colorful]$ cd po
11 | [translate@tutorial po]$ msginit -l (your_language) -i kcm_colorful.pot
12 | ```
13 |
14 | and then, open that PO file with the PO editor you prefer to use.
15 |
16 | If your language has translated but not latest or incompleted, just run "extract-messages.sh"
17 | and that tool will merge the po file in `po` directory.
18 |
19 | ```
20 | [translate@tutorial kcm-colorful]$ bash extract-messages.sh
21 | ```
22 |
23 | and then, open the PO file of your language in `po` directory.
24 |
25 | ### 2. TRANSLATE THE DESKTOP FILE (MEDIUM PRIORITY)
26 | The desktop file stored the name and description of kcm-colorful in KDE System Settings.
27 |
28 | First, open `kcm_colorful.desktop` in `src` directory with the text editor you prefer to use.
29 |
30 | And then, you might see the following text:
31 | ```desktop
32 | [Desktop Entry]
33 | ...omitted
34 |
35 | Name=Colorful
36 | Name[zh_CN]=多彩
37 | Comment=Make your KDE Plasma colorful
38 | Comment[zh_CN]=让您的KDE Plasma丰富多彩
39 | X-KDE-Keywords=Color, Theme
40 | X-KDE-Keywords[zh_CN]=Color, Theme,色彩,颜色,主题
41 | ```
42 |
43 | Just add the localized translation like `zh_CN` does, for example:
44 | ```
45 | Name=Colorful
46 | Name[zh_CN]=多彩
47 | Name[LANG_CODE]=(Translation)
48 | Comment=Make your KDE Plasma colorful
49 | Comment[zh_CN]=让您的KDE Plasma丰富多彩
50 | Comment[LANG_CODE]=(Translation)
51 | X-KDE-Keywords=Color, Theme
52 | X-KDE-Keywords[zh_CN]=Color, Theme,色彩,颜色,主题
53 | X-KDE-Keywords[LANG_CODE]=(Translation)
54 | ```
55 |
56 | > **NOTE**: The keywords use "," as the delimiter.
57 |
58 | ### 3. Push and Create a Pull Request
59 | And then, you just need to wait for approve :)
60 |
--------------------------------------------------------------------------------
/src/artworks/pallete.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/qml/WButton.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.2
2 |
3 | import QtQuick.Layouts 1.1
4 | import QtQuick.Controls 1.4
5 | import QtQuick.Controls.Styles 1.4
6 | import QtGraphicalEffects 1.0
7 |
8 | import org.kde.plasma.core 2.0 as PlasmaCore
9 | import org.kde.plasma.components 2.0 as PlasmaComponents
10 |
11 | Item {
12 | id: root
13 | property string text: ''
14 | property alias iconSource: icon.source
15 | /* property alias containsMouse: mouseArea.containsMouse */
16 | /* property alias onBtn: p.onButton */
17 | /* property alias iconSource: icon.source */
18 | /* property alias font: label.font */
19 | signal clicked
20 |
21 | activeFocusOnTab: true
22 |
23 | property int iconSize: units.gridUnit * 2
24 |
25 | implicitWidth: iconSize + units.largeSpacing * 2
26 | implicitHeight: iconSize + units.smallSpacing
27 |
28 | /* Behavior on opacity { */
29 | /* OpacityAnimator { */
30 | /* duration: units.longDuration */
31 | /* easing.type: Easing.InOutQuad */
32 | /* } */
33 | /* } */
34 |
35 | PlasmaCore.IconItem {
36 | id: icon
37 | anchors {
38 | top: parent.top
39 | horizontalCenter: parent.horizontalCenter
40 | }
41 | width: iconSize
42 | height: iconSize
43 | /* source: './refresh.png' */
44 | colorGroup: PlasmaCore.ColorScope.colorGroup
45 | /* active: mouseArea.containsMouse || root.activeFocus */
46 | active: mouseArea.containsMouse
47 | /* ? onBtn = true : ((onBtn = false) == "This must be false!") */
48 | }
49 |
50 | MouseArea {
51 | id: mouseArea
52 | hoverEnabled: true
53 | /* onClicked: root.clicked() */
54 | onClicked: {
55 | root.clicked()
56 | }
57 | anchors.fill: parent
58 |
59 | onEntered: {
60 | label.text = root.text
61 | /* wallpaper.state = "on" */
62 | }
63 | onExited: {
64 | label.text = ''
65 | /* wallpaper.state = "off" */
66 | /* onBtn = false */
67 | }
68 | }
69 |
70 | /* Keys.onEnterPressed: clicked() */
71 | /* Keys.onReturnPressed: clicked() */
72 | /* Keys.onSpacePressed: clicked() */
73 |
74 | /* Accessible.onPressAction: clicked() */
75 | /* Accessible.role: Accessible.Button */
76 | /* Accessible.name: label.text */
77 | }
78 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # KCM-Colorful
2 | [English Version](https://github.com/IsoaSFlus/kcm-colorful/blob/master/README.en.md)
3 |
4 | 根据当前的壁纸改变KDE Plasma的颜色。
5 |
6 | ## Requirements
7 | * Qt5
8 | * KDE Frameworks 5
9 | * cmake
10 | * extra-cmake-modules
11 | * GNU gettext utilities
12 |
13 | ## Build
14 | ```
15 | git clone --recursive https://github.com/IsoaSFlus/kcm-colorful.git
16 | cd kcm-colorful
17 | mkdir build
18 | cd ./build
19 | cmake ../
20 | make
21 | sudo make install
22 | #Then set your plasma desktop theme to "Colorful" for best experience.
23 | ```
24 |
25 | ## Installation
26 | ### Archlinux (AUR)
27 | ```
28 | yaourt -S kcm-colorful-git # or any other aur helper
29 | ```
30 | Thanks for [@VOID001](https://github.com/VOID001)'s maintenance.
31 |
32 | ### Archlinux ([ArchlinuxCN](https://wiki.archlinux.org/index.php/Unofficial_user_repositories#archlinuxcn) repo)
33 | ```
34 | sudo pacman -S kcm-colorful-git
35 | ```
36 | Thanks for [@MarvelousBlack](https://github.com/MarvelousBlack)'s maintenance.
37 |
38 | ## Screenshots
39 | 
40 | 
41 |
42 | ## TODO
43 | - [x] 实现命令行helper
44 | - [x] 将颜色提取算法移植至C++并剔除Python依赖
45 | - [x] 实现KCM集成至KDE设置
46 | - [ ] 利用机器学习算法进一步优化主题色选择
47 |
48 | ## Postscript
49 | 除了KCM,本项目还提供了一个cli的程序,可以供用户配合脚本使用:
50 |
51 | ```
52 | Usage: kcmcolorfulhelper [options]
53 | Helper for kcm-colorful.
54 | Project address: https://github.com/IsoaSFlus/kcm-colorful
55 |
56 | Options:
57 | -h, --help Displays this help.
58 | -p, --picture Picture to extract color.
59 | -c, --color Set color manually, eg: #1234ef.
60 | -s, --set-as-wallpaper Set picture specified by "-p" as wallpaper.
61 | -d, --debug Show debug info.
62 | -n, --number Select the Nth color in candidate list. Default is
63 | 1.
64 | -o, --opacity Set the opacity of theme, from 0 to 1(1 is opaque).
65 | ```
66 |
67 | **如果你想实现像我截图中一样的效果,那么还需要一些额外的设置。**
68 |
69 | 首先,打开KDE的系统设置->桌面行为->桌面特效,找到“模糊”项并使能(可根据个人喜好调整该项设置中的模糊程度以及噪点厚度),依据个人喜好开启或关闭“背景对比度”项。
70 |
71 | 之后,打开KDE的系统设置->工作空间主题->桌面主题,设置主题为“Colorful”(当然,前提是你安装了本项目)。
72 |
73 | 第三,安装[BreezeBlurred](https://github.com/alex47/BreezeBlurred),这个项目在原版Breeze窗口装饰主题的基础上提供透明效果。在安装完成后打开KDE的系统设置->应用程序风格->窗口装饰,找到该主题“微风”(注意,你会发现你其中有复数个“微风”因为原版也叫“微风”)并打开其配置菜单,关闭绘制窗口背景渐变并调整透明度(推荐60%,因为这与桌面主题一致),如下图。
74 | 
75 |
76 | 最后,如果你对我截图左侧的dock感兴趣,请安装[Latte-Dock](https://github.com/psifidotos/Latte-Dock)。
77 |
--------------------------------------------------------------------------------
/src/helper/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "kcmcolorfulhelper.h"
3 |
4 | int main(int argc, char *argv[])
5 | {
6 | QCoreApplication a(argc, argv);
7 |
8 | QCommandLineParser parser;
9 | parser.setApplicationDescription("Helper for kcm-colorful.\nProject address: https://github.com/IsoaSFlus/kcm-colorful");
10 | parser.addHelpOption();
11 | // parser.addVersionOption();
12 |
13 | QCommandLineOption pictureOption(QStringList() << "p" << "picture", "Picture to extract color.", "file", "kcmcolorful-NOPIC");
14 | parser.addOption(pictureOption);
15 | QCommandLineOption colorOption(QStringList() << "c" << "color", "Set color manually, eg: #1234ef.", "colorcode", "kcmcolorful-NOCOLOR");
16 | parser.addOption(colorOption);
17 | QCommandLineOption paletteOption("palette-number", "Set the number of colors of palette in the first color extraction. Valid number is between 1 to 16, default is 8.", "int", "8");
18 | paletteOption.setFlags(QCommandLineOption::HiddenFromHelp);
19 | parser.addOption(paletteOption);
20 | QCommandLineOption setWPOption(QStringList() << "s" << "set-as-wallpaper", "Set picture specified by \"-p\" as wallpaper.");
21 | parser.addOption(setWPOption);
22 | QCommandLineOption debugOption(QStringList() << "d" << "debug", "Show debug info.");
23 | parser.addOption(debugOption);
24 | QCommandLineOption kcmOption("kcm");
25 | kcmOption.setFlags(QCommandLineOption::HiddenFromHelp);
26 | parser.addOption(kcmOption);
27 | QCommandLineOption colorNumOption(QStringList() << "n" << "number", "Select the Nth color in candidate list. Default is 1.", "int", "1");
28 | parser.addOption(colorNumOption);
29 | QCommandLineOption opacityOption(QStringList() << "o" << "opacity", "Set the opacity of theme, from 0 to 1(1 is opaque).", "float", "notset");
30 | parser.addOption(opacityOption);
31 |
32 |
33 | parser.process(a);
34 |
35 | if (QCoreApplication::arguments().size() <= 1) {
36 | qDebug().noquote() << "Error: You should at least specify one argument.";
37 | parser.showHelp();
38 | }
39 |
40 | QStringList args;
41 | args << parser.value(pictureOption);
42 | args << parser.value(colorOption);
43 | args << parser.value(paletteOption);
44 | args << (parser.isSet(setWPOption) ? "true" : " false");
45 | args << (parser.isSet(debugOption) ? "true" : " false");
46 | args << (parser.isSet(kcmOption) ? "true" : " false");
47 | args << parser.value(colorNumOption);
48 | args << parser.value(opacityOption);
49 | KcmColorfulHelper kch(args);
50 | kch.run();
51 |
52 | // return a.exec();
53 | return 0;
54 | }
55 |
--------------------------------------------------------------------------------
/src/qml/ColorUnitW.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.2
2 |
3 | import QtQuick.Layouts 1.1
4 | import QtQuick.Controls 1.4
5 | import QtQuick.Controls.Styles 1.4
6 | import QtGraphicalEffects 1.0
7 |
8 | import org.kde.plasma.core 2.0 as PlasmaCore
9 | import org.kde.plasma.components 2.0 as PlasmaComponents
10 |
11 | Item {
12 | id: root
13 | width: units.iconSizes.large
14 | height: width
15 | property alias inner_color: inner.color
16 | property string c_name: "null"
17 | state: "off"
18 | states: [
19 | State {
20 | name: "on"
21 | PropertyChanges {
22 | target: root
23 | scale: 1.3
24 | }
25 | },
26 | State {
27 | name: "off"
28 | PropertyChanges {
29 | target: root
30 | scale: 1
31 | }
32 | }
33 | ]
34 | transitions: [
35 | Transition {
36 | from: "off"
37 | to: "on"
38 | NumberAnimation {
39 | target: root
40 | property: "scale"
41 | duration: 200
42 | /* easing.type: Easing.InOutQuad */
43 | easing.type: Easing.OutCubic
44 | }
45 | },
46 | Transition {
47 | from: "on"
48 | to: "off"
49 | NumberAnimation {
50 | target: root
51 | property: "scale"
52 | duration: 200
53 | /* easing.type: Easing.InOutQuad */
54 | easing.type: Easing.OutCubic
55 | }
56 | }
57 | ]
58 |
59 | Rectangle {
60 | id: inner
61 | width: units.iconSizes.large
62 | height: width
63 | radius: width / 2
64 | border.width: width * 0.03
65 | border.color: PlasmaCore.ColorScope.textColor
66 | /* border.width: width / 10 */
67 | /* border.color: "transparent" */
68 |
69 | /* Behavior on border.color { */
70 | /* ColorAnimation { */
71 | /* duration: units.longDuration * 2 */
72 | /* /\* easing.type: Easing.InOutQuad *\/ */
73 | /* } */
74 | /* } */
75 |
76 | MouseArea {
77 | id: ma
78 | anchors.fill: parent
79 | hoverEnabled: true
80 | onEntered: {
81 | /* inner.border.color = PlasmaCore.ColorScope.highlightColor */
82 | /* wallpaper.state = "on" */
83 | root.state = "on"
84 | }
85 | onExited: {
86 | /* inner.border.color = "transparent" */
87 | root.state = "off"
88 | /* wallpaper.state = "off" */
89 | }
90 | onClicked: cuw_row.cuw_clicked(inner.color)
91 | }
92 |
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/README.en.md:
--------------------------------------------------------------------------------
1 | # KCM-Colorful
2 | Change your KDE Plasma's color based on your wallpaper.
3 |
4 | ## Requirements
5 | * Qt5
6 | * KDE Frameworks 5
7 | * cmake
8 | * extra-cmake-modules
9 | * GNU gettext utilities
10 |
11 | ## Build
12 | ```
13 | git clone --recursive https://github.com/IsoaSFlus/kcm-colorful.git
14 | cd kcm-colorful
15 | mkdir build
16 | cd ./build
17 | cmake ../
18 | make
19 | sudo make install
20 | #Then set your plasma desktop theme to "Colorful" for best experience.
21 | ```
22 |
23 | ## Installation
24 | ### Archlinux (AUR)
25 | ```
26 | yaourt -S kcm-colorful-git # or any other aur helper
27 | ```
28 | Thanks for [@VOID001](https://github.com/VOID001)'s work.
29 |
30 | ### Archlinux ([ArchlinuxCN](https://wiki.archlinux.org/index.php/Unofficial_user_repositories#archlinuxcn) repo)
31 | ```
32 | sudo pacman -S kcm-colorful-git
33 | ```
34 | Thanks for [@MarvelousBlack](https://github.com/MarvelousBlack)'s maintenance.
35 |
36 | ## Screenshots
37 | 
38 | 
39 |
40 | ## TODO
41 | - [x] Implement CLI helper
42 | - [x] Port color extraction code to C++
43 | - [x] Implement KCM
44 | - [ ] Improve color selection by ML
45 |
46 | ## Postscript
47 | Besides KCM, this project also provides a CLI program that could be used by your script:
48 | ```
49 | Usage: kcmcolorfulhelper [options]
50 | Helper for kcm-colorful.
51 | Project address: https://github.com/IsoaSFlus/kcm-colorful
52 |
53 | Options:
54 | -h, --help Displays this help.
55 | -p, --picture Picture to extract color.
56 | -c, --color Set color manually, eg: #1234ef.
57 | -s, --set-as-wallpaper Set picture specified by "-p" as wallpaper.
58 | -d, --debug Show debug info.
59 | -n, --number Select the Nth color in candidate list. Default is
60 | 1.
61 | -o, --opacity Set the opacity of theme, from 0 to 1(1 is opaque).
62 | ```
63 |
64 | **If you want to make your KDE look like the screenshots above, just follow these steps.**
65 |
66 | First,open KDE's systemsettings->Desktop Behavior->Desktop Effects. Find "blur" and enable it(You can set the Blur strength and Noise strength to preferable value).
67 |
68 | Then,open KDE's systemsettings->Workspace Theme->Desktop Theme, set your desktop theme to “Colorful”.
69 |
70 | Third,install [BreezeBlurred](https://github.com/alex47/BreezeBlurred),this project provide a blurred version of Breeze window decoration. After installation, open KDE's systemsettings->Application Style->Window Decorations. Find the item named "BreezeBlur" and click "Configure BleezeBlur". Disable "Draw window backbround gradient" and set the Opacity(I'll recommend 60%, because it is the same as desktop theme's).
71 |
72 | Finally,if your are curious about the dock on the Screenshots,just check out [Latte-Dock](https://github.com/psifidotos/Latte-Dock).
73 |
--------------------------------------------------------------------------------
/schemes/ColorfulDark.colors:
--------------------------------------------------------------------------------
1 | [ColorEffects:Disabled]
2 | Color=56,56,56
3 | ColorAmount=0
4 | ColorEffect=0
5 | ContrastAmount=0.65
6 | ContrastEffect=1
7 | IntensityAmount=0.1
8 | IntensityEffect=2
9 |
10 | [ColorEffects:Inactive]
11 | ChangeSelectionColor=true
12 | Color=112,111,110
13 | ColorAmount=0.025
14 | ColorEffect=2
15 | ContrastAmount=0.1
16 | ContrastEffect=2
17 | Enable=false
18 | IntensityAmount=0
19 | IntensityEffect=0
20 |
21 | [Colors:Button]
22 | BackgroundAlternate=77,77,77
23 | BackgroundNormal=49,54,59
24 | DecorationFocus=61,174,233
25 | DecorationHover=61,174,233
26 | ForegroundActive=61,174,233
27 | ForegroundInactive=189,195,199
28 | ForegroundLink=41,128,185
29 | ForegroundNegative=218,68,83
30 | ForegroundNeutral=246,116,0
31 | ForegroundNormal=239,240,241
32 | ForegroundPositive=39,174,96
33 | ForegroundVisited=127,140,141
34 |
35 | [Colors:Complementary]
36 | BackgroundAlternate=59,64,69
37 | BackgroundNormal=49,54,59
38 | DecorationFocus=30,146,255
39 | DecorationHover=61,174,230
40 | ForegroundActive=246,116,0
41 | ForegroundInactive=175,176,179
42 | ForegroundLink=61,174,230
43 | ForegroundNegative=237,21,21
44 | ForegroundNeutral=201,206,59
45 | ForegroundNormal=239,240,241
46 | ForegroundPositive=17,209,22
47 | ForegroundVisited=61,174,230
48 |
49 | [Colors:Selection]
50 | BackgroundAlternate=29,153,243
51 | BackgroundNormal=61,174,233
52 | DecorationFocus=61,174,233
53 | DecorationHover=61,174,233
54 | ForegroundActive=252,252,252
55 | ForegroundInactive=239,240,241
56 | ForegroundLink=253,188,75
57 | ForegroundNegative=218,68,83
58 | ForegroundNeutral=246,116,0
59 | ForegroundNormal=239,240,241
60 | ForegroundPositive=39,174,96
61 | ForegroundVisited=189,195,199
62 |
63 | [Colors:Tooltip]
64 | BackgroundAlternate=77,77,77
65 | BackgroundNormal=49,54,59
66 | DecorationFocus=61,174,233
67 | DecorationHover=61,174,233
68 | ForegroundActive=61,174,233
69 | ForegroundInactive=189,195,199
70 | ForegroundLink=41,128,185
71 | ForegroundNegative=218,68,83
72 | ForegroundNeutral=246,116,0
73 | ForegroundNormal=239,240,241
74 | ForegroundPositive=39,174,96
75 | ForegroundVisited=127,140,141
76 |
77 | [Colors:View]
78 | BackgroundAlternate=49,54,59
79 | BackgroundNormal=35,38,41
80 | DecorationFocus=61,174,233
81 | DecorationHover=61,174,233
82 | ForegroundActive=61,174,233
83 | ForegroundInactive=189,195,199
84 | ForegroundLink=41,128,185
85 | ForegroundNegative=218,68,83
86 | ForegroundNeutral=246,116,0
87 | ForegroundNormal=230,230,230
88 | ForegroundPositive=39,174,96
89 | ForegroundVisited=127,140,141
90 |
91 | [Colors:Window]
92 | BackgroundAlternate=77,77,77
93 | BackgroundNormal=49,54,59
94 | DecorationFocus=61,174,233
95 | DecorationHover=61,174,233
96 | ForegroundActive=61,174,233
97 | ForegroundInactive=189,195,199
98 | ForegroundLink=41,128,185
99 | ForegroundNegative=218,68,83
100 | ForegroundNeutral=246,116,0
101 | ForegroundNormal=230,230,230
102 | ForegroundPositive=39,174,96
103 | ForegroundVisited=127,140,141
104 |
105 | [General]
106 | ColorScheme=Breeze Dark
107 | Name=ColorfulDark
108 | shadeSortColumn=true
109 |
110 | [KDE]
111 | contrast=4
112 |
113 | [WM]
114 | activeBackground=49,54,59
115 | activeBlend=255,255,255
116 | activeForeground=239,240,241
117 | inactiveBackground=49,54,59
118 | inactiveBlend=75,71,67
119 | inactiveForeground=127,140,141
120 |
--------------------------------------------------------------------------------
/schemes/ColorfulLight.colors:
--------------------------------------------------------------------------------
1 | [ColorEffects:Disabled]
2 | Color=56,56,56
3 | ColorAmount=0
4 | ColorEffect=0
5 | ContrastAmount=0.65
6 | ContrastEffect=1
7 | IntensityAmount=0.1
8 | IntensityEffect=2
9 |
10 | [ColorEffects:Inactive]
11 | ChangeSelectionColor=true
12 | Color=112,111,110
13 | ColorAmount=0.025
14 | ColorEffect=2
15 | ContrastAmount=0.1
16 | ContrastEffect=2
17 | Enable=false
18 | IntensityAmount=0
19 | IntensityEffect=0
20 |
21 | [Colors:Button]
22 | BackgroundAlternate=189,195,199
23 | BackgroundNormal=239,240,241
24 | DecorationFocus=61,174,233
25 | DecorationHover=147,206,233
26 | ForegroundActive=61,174,233
27 | ForegroundInactive=127,140,141
28 | ForegroundLink=41,128,185
29 | ForegroundNegative=218,68,83
30 | ForegroundNeutral=246,116,0
31 | ForegroundNormal=35,38,39
32 | ForegroundPositive=39,174,96
33 | ForegroundVisited=127,140,141
34 |
35 | [Colors:Complementary]
36 | BackgroundAlternate=59,64,69
37 | BackgroundNormal=49,54,59
38 | DecorationFocus=30,146,255
39 | DecorationHover=61,174,230
40 | ForegroundActive=147,206,233
41 | ForegroundInactive=175,176,179
42 | ForegroundLink=61,174,230
43 | ForegroundNegative=231,76,60
44 | ForegroundNeutral=253,188,75
45 | ForegroundNormal=239,240,241
46 | ForegroundPositive=46,204,113
47 | ForegroundVisited=61,174,230
48 |
49 | [Colors:Selection]
50 | BackgroundAlternate=29,153,243
51 | BackgroundNormal=61,174,233
52 | DecorationFocus=61,174,233
53 | DecorationHover=147,206,233
54 | ForegroundActive=252,252,252
55 | ForegroundInactive=239,240,241
56 | ForegroundLink=253,188,75
57 | ForegroundNegative=218,68,83
58 | ForegroundNeutral=246,116,0
59 | ForegroundNormal=252,252,252
60 | ForegroundPositive=39,174,96
61 | ForegroundVisited=189,195,199
62 |
63 | [Colors:Tooltip]
64 | BackgroundAlternate=77,77,77
65 | BackgroundNormal=35,38,39
66 | DecorationFocus=61,174,233
67 | DecorationHover=147,206,233
68 | ForegroundActive=61,174,233
69 | ForegroundInactive=189,195,199
70 | ForegroundLink=41,128,185
71 | ForegroundNegative=218,68,83
72 | ForegroundNeutral=246,116,0
73 | ForegroundNormal=252,252,252
74 | ForegroundPositive=39,174,96
75 | ForegroundVisited=127,140,141
76 |
77 | [Colors:View]
78 | BackgroundAlternate=239,240,241
79 | BackgroundNormal=252,252,252
80 | DecorationFocus=61,174,233
81 | DecorationHover=147,206,233
82 | ForegroundActive=61,174,233
83 | ForegroundInactive=127,140,141
84 | ForegroundLink=41,128,185
85 | ForegroundNegative=218,68,83
86 | ForegroundNeutral=246,116,0
87 | ForegroundNormal=35,38,39
88 | ForegroundPositive=39,174,96
89 | ForegroundVisited=127,140,141
90 |
91 | [Colors:Window]
92 | BackgroundAlternate=189,195,199
93 | BackgroundNormal=239,240,241
94 | DecorationFocus=61,174,233
95 | DecorationHover=147,206,233
96 | ForegroundActive=61,174,233
97 | ForegroundInactive=127,140,141
98 | ForegroundLink=41,128,185
99 | ForegroundNegative=218,68,83
100 | ForegroundNeutral=246,116,0
101 | ForegroundNormal=35,38,39
102 | ForegroundPositive=39,174,96
103 | ForegroundVisited=127,140,141
104 |
105 | [General]
106 | ColorScheme=Breeze
107 | Name=ColorfulLight
108 | shadeSortColumn=true
109 |
110 | [KDE]
111 | contrast=4
112 |
113 | [WM]
114 | activeBackground=71,80,87
115 | activeBlend=252,252,252
116 | activeForeground=252,252,252
117 | inactiveBackground=239,240,241
118 | inactiveBlend=75,71,67
119 | inactiveForeground=189,195,199
120 |
--------------------------------------------------------------------------------
/src/qml/ColorUnit.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.2
2 |
3 | import QtQuick.Layouts 1.1
4 | import QtQuick.Controls 1.4
5 | import QtQuick.Controls.Styles 1.4
6 | import QtQuick.Dialogs 1.0
7 | import QtGraphicalEffects 1.0
8 |
9 | import org.kde.plasma.core 2.0 as PlasmaCore
10 | import org.kde.plasma.components 2.0 as PlasmaComponents
11 |
12 | Item {
13 | id: root
14 | property alias inner_color: inner.color
15 | property string c_name: "null"
16 | property int cu_index
17 | width: inner.width * 1.3
18 | height: width
19 | state: "off"
20 | states: [
21 | State {
22 | name: "on"
23 | PropertyChanges {
24 | target: root
25 | scale: 1.3
26 | }
27 | },
28 | State {
29 | name: "off"
30 | PropertyChanges {
31 | target: root
32 | scale: 1
33 | }
34 | }
35 | ]
36 | transitions: [
37 | Transition {
38 | from: "off"
39 | to: "on"
40 | NumberAnimation {
41 | target: root
42 | property: "scale"
43 | duration: 200
44 | easing.type: Easing.OutCubic
45 | }
46 | },
47 | Transition {
48 | from: "on"
49 | to: "off"
50 | NumberAnimation {
51 | target: root
52 | property: "scale"
53 | duration: 200
54 | easing.type: Easing.OutCubic
55 | }
56 | }
57 | ]
58 | Rectangle {
59 | id: inner
60 | width: units.iconSizes.medium * 1.2
61 | height: width
62 | radius: width / 2
63 | border.width: width * 0.03
64 | border.color: PlasmaCore.ColorScope.textColor
65 | anchors.centerIn: parent
66 |
67 | MouseArea {
68 | id: ma
69 | anchors.fill: parent
70 | hoverEnabled: true
71 | acceptedButtons: Qt.LeftButton | Qt.RightButton
72 | onEntered: {
73 | root.state = "on"
74 | }
75 | onExited: {
76 | root.state = "off"
77 | }
78 | onClicked: {
79 | if(mouse.button & Qt.RightButton) {
80 | if (root.c_name != "own" && root.c_name != "default") {
81 | gv.remove_color(root.cu_index);
82 | }
83 | } else {
84 | if (root.c_name != "own") {
85 | gv.cu_clicked(c)
86 | } else {
87 | colorDialog.open()
88 | }
89 | }
90 | }
91 | }
92 |
93 | ColorDialog {
94 | id: colorDialog
95 | /* title: "Please choose a color" */
96 | onAccepted: {
97 | /* console.log("You chose: " + colorDialog.color) */
98 | gv.add_color("" + colorDialog.color)
99 | Qt.quit()
100 | }
101 | onRejected: {
102 | /* console.log("Canceled") */
103 | Qt.quit()
104 | }
105 | /* Component.onCompleted: visible = true */
106 | }
107 |
108 | PlasmaCore.IconItem {
109 | id: icon
110 | anchors {
111 | /* top: parent.top */
112 | /* horizontalCenter: parent.horizontalCenter */
113 | centerIn: parent
114 | }
115 | source: 'kcolorchooser'
116 | width: parent.width * 0.7
117 | height: width
118 | /* source: './refresh.png' */
119 | colorGroup: PlasmaCore.ColorScope.colorGroup
120 | /* active: mouseArea.containsMouse || root.activeFocus */
121 | visible: root.c_name != "own" ? false : true
122 | }
123 |
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/src/artworks/gen-colors.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/qml/ColorWidget.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.2
2 |
3 | import QtQuick.Layouts 1.1
4 | import QtQuick.Controls 1.4
5 | import QtQuick.Controls.Styles 1.4
6 | import QtGraphicalEffects 1.0
7 |
8 | import org.kde.plasma.core 2.0 as PlasmaCore
9 | import org.kde.plasma.components 2.0 as PlasmaComponents
10 |
11 | import "./colors.js" as ColorTable
12 |
13 |
14 | Rectangle {
15 | id: root
16 | property string cw_type
17 | implicitHeight: gv.cellWidth
18 | /* + units.smallSpacing */
19 | color: "transparent"
20 |
21 | ListModel {
22 | id: colorModel
23 | /* objectName: "gv_model" */
24 |
25 | /* ListElement { */
26 | /* name: "Apple" */
27 | /* c: "red" */
28 | /* } */
29 | /* ListElement { */
30 | /* name: "Orange" */
31 | /* c: "orange" */
32 | /* } */
33 | /* ListElement { */
34 | /* name: "own" */
35 | /* c: "yellow" */
36 | /* } */
37 |
38 | }
39 |
40 | Component {
41 | id: colorDelegate
42 | ColorUnit {
43 | cu_index: index
44 | inner_color: c
45 | c_name: name
46 | }
47 | }
48 |
49 | /* ColorUnit { */
50 | /* id: colorDelegate */
51 | /* cu_index: index */
52 | /* inner_color: c */
53 | /* c_name: name */
54 | /* } */
55 |
56 | GridView {
57 | id: gv
58 | objectName: "grid_view"
59 | /* Layout.alignment: Qt.AlignCenter */
60 | signal cu_clicked(string color)
61 | clip: true
62 |
63 | anchors {
64 | fill: parent
65 | /* topMargin: units.smallSpacing * 1.3 */
66 | }
67 | cellWidth: units.iconSizes.medium * 1.5+ units.smallSpacing
68 | cellHeight: cellWidth
69 | /* anchors.fill: parent */
70 | model: colorModel
71 | delegate: colorDelegate
72 | remove: Transition {
73 | ParallelAnimation {
74 | NumberAnimation { property: "opacity"; from: 1.0; to: 0; duration: 200}
75 | NumberAnimation { property: "scale"; to: 0; duration: 300; easing.type: Easing.OutCubic}
76 | }
77 | }
78 | add: Transition {
79 | ParallelAnimation {
80 | NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 200}
81 | NumberAnimation { property: "scale"; from: 0; to: 1.0; duration: 300; easing.type: Easing.OutCubic}
82 | }
83 | }
84 | displaced: Transition {
85 | NumberAnimation { properties: "x,y"; duration: 300; easing.type: Easing.OutCubic}
86 | }
87 | move: Transition {
88 | NumberAnimation { properties: "x,y"; duration: 300; easing.type: Easing.OutCubic}
89 | }
90 |
91 | function add_user_color(color_code) {
92 | if (root.cw_type == "cw2") {
93 | colorModel.insert(colorModel.count - 1, {"name": "user", "c": color_code})
94 | }
95 | }
96 | function prepend_color(color_code) {
97 | if (root.cw_type == "cw1") {
98 | var i = 0;
99 | while (i < 10 && i < colorModel.count) {
100 | if (colorModel.get(i).c == color_code) {
101 | colorModel.move(i, 0, 1);
102 | return;
103 | }
104 | i++;
105 | }
106 | colorModel.insert(0, {"name": "user", "c": color_code});
107 | while (colorModel.count > 10) {
108 | colorModel.remove(i);
109 | }
110 | } else {
111 | colorModel.insert(0, {"name": "user", "c": color_code});
112 | }
113 | }
114 | function add_color(color_code) {
115 | var i = colorModel.count - 1;
116 | if (colorModel.get(i).name == "own") {
117 | colorModel.insert(i, {"name": "user", "c": color_code})
118 | } else {
119 | colorModel.append({"name": "user", "c": color_code})
120 | }
121 | }
122 | function get_colors() {
123 | var i = colorModel.count - 1;
124 | var r = "";
125 | while (i >= 0) {
126 | if (colorModel.get(i).name != "user") {
127 | if (colorModel.get(i).name == "own") {
128 | i--;
129 | continue;
130 | } else {
131 | break;
132 | }
133 | } else {
134 | r = colorModel.get(i).c + "," + r;
135 | }
136 | i--;
137 | }
138 | return r;
139 | }
140 | function remove_color(index) {
141 | colorModel.remove(index);
142 | }
143 |
144 | Component.onCompleted: {
145 | if (root.cw_type == "cw2") {
146 | var default_colors = ColorTable.color_table()
147 | for (var i = default_colors.length; i > 0; --i) {
148 | colorModel.insert(0, default_colors[i-1])
149 | }
150 | colorModel.append({"name": "own", "c": "grey"})
151 | }
152 | }
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/qml/Wallpaper.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.2
2 |
3 | import QtQuick.Layouts 1.1
4 | import QtQuick.Controls 1.4
5 | import QtQuick.Controls.Styles 1.4
6 | import QtGraphicalEffects 1.0
7 |
8 | import org.kde.plasma.core 2.0 as PlasmaCore
9 | import org.kde.plasma.components 2.0 as PlasmaComponents
10 | import org.kde.plasma.extras 2.0 as PlasmaExtras
11 |
12 |
13 | Item {
14 | id: root
15 | /* width: 1280 */
16 | /* height: 720 */
17 | implicitHeight: wallpaper.height + label.height
18 | Image {
19 | property real factor: 0
20 | property bool onButton: false
21 | id: wallpaper
22 | objectName: "wp_view"
23 | smooth: true
24 | height: units.largeSpacing * 10
25 | anchors {
26 | /* fill: parent */
27 | top: root.top
28 | left: root.left
29 | right: root.right
30 | /* bottom: label.top */
31 | }
32 | fillMode: Image.PreserveAspectCrop
33 | state: "off"
34 |
35 | states: [
36 | State {
37 | name: "on"
38 | PropertyChanges {
39 | target: wallpaper
40 | factor: 1
41 | }
42 | },
43 | State {
44 | name: "off"
45 | PropertyChanges {
46 | target: wallpaper
47 | factor: 0
48 | }
49 | },
50 | State {
51 | name: "busy"
52 | PropertyChanges {
53 | target: wallpaper
54 | factor: 1
55 | }
56 | },
57 | State {
58 | name: "generated"
59 | PropertyChanges {
60 | target: wallpaper
61 | factor: 1
62 | }
63 | }
64 | ]
65 |
66 | transitions: [
67 | Transition {
68 | from: "off"
69 | to: "on"
70 | ParallelAnimation {
71 | NumberAnimation {
72 | target: wallpaper
73 | property: "factor"
74 | duration: 200
75 | /* easing.type: Easing.InOutQuad */
76 | }
77 | }
78 | },
79 | Transition {
80 | from: "on"
81 | to: "off"
82 | ParallelAnimation {
83 | NumberAnimation {
84 | target: wallpaper
85 | property: "factor"
86 | duration: 200
87 | /* easing.type: Easing.InOutQuad */
88 | }
89 | }
90 | }
91 | ]
92 | }
93 |
94 | FastBlur {
95 | source: wallpaper
96 | id: blur
97 | anchors.fill: wallpaper
98 | radius: 60 * wallpaper.factor
99 | }
100 |
101 | MouseArea {
102 | id: mArea
103 | anchors.fill: wallpaper
104 | hoverEnabled: true
105 |
106 | onEntered: {
107 | if (wallpaper.state == "off") {
108 | wallpaper.state = "on"
109 | }
110 | }
111 | onExited: {
112 | if (wallpaper.state == "on" || wallpaper.state == "generated") {
113 | wallpaper.state = "off"
114 | }
115 | }
116 |
117 | /* onClicked: { */
118 | /* if (wallpaper.state == "off") { */
119 | /* wallpaper.state = "on" */
120 | /* } else { */
121 | /* wallpaper.state = "off" */
122 | /* } */
123 | /* } */
124 |
125 | BusyIndicator {
126 | running: wallpaper.state == "busy"
127 | /* running: false */
128 | anchors.centerIn: parent
129 | }
130 |
131 | Row {
132 | opacity: wallpaper.state == "on" ? 1 : 0
133 | visible: opacity == 0 ? false : true
134 | spacing: units.smallSpacing
135 |
136 | Behavior on opacity {
137 | OpacityAnimator {
138 | duration: units.longDuration
139 | easing.type: Easing.InOutQuad
140 | }
141 | }
142 |
143 | anchors {
144 | /* horizontalCenter: wallpaper.horizontalCenter */
145 | centerIn: parent
146 | }
147 | WButton {
148 | id: wb_refresh
149 | objectName: "wb_refresh"
150 | text: i18n("Refresh wallpaper")
151 | anchors {
152 | /* horizontalCenter: wallpaper.horizontalCenter */
153 | /* centerIn: wallpaper */
154 | }
155 | iconSource: ':/artworks/refresh.svg'
156 | /* opacity: wallpaper.state == "on" ? 1 : 0 */
157 | onClicked: {
158 | /* wallpaper.state = "busy" */
159 | }
160 | }
161 | WButton {
162 | id: wb_generate
163 | objectName: "wb_generate"
164 | text: i18n("Generate colors based on wallpaper")
165 | iconSource: ':/artworks/gen-colors.svg'
166 | onClicked: {
167 | wallpaper.state = "generated"
168 | }
169 | }
170 | }
171 |
172 | Row {
173 | id: cuw_row
174 | objectName: "cuw_row"
175 | opacity: wallpaper.state == "generated" ? 1 : 0
176 | visible: opacity == 0 ? false : true
177 | spacing: units.smallSpacing
178 |
179 | signal cuw_clicked(string color)
180 |
181 | Behavior on opacity {
182 | OpacityAnimator {
183 | duration: units.longDuration
184 | /* easing.type: Easing.InOutQuad */
185 | }
186 | }
187 | anchors {
188 | centerIn: parent
189 | }
190 |
191 | ColorUnitW {
192 | objectName: "cuw"
193 | inner_color: "white"
194 | }
195 | ColorUnitW {
196 | objectName: "cuw"
197 | inner_color: "white"
198 | }
199 | ColorUnitW {
200 | objectName: "cuw"
201 | inner_color: "white"
202 | }
203 | ColorUnitW {
204 | objectName: "cuw"
205 | inner_color: "white"
206 | }
207 |
208 | }
209 | }
210 |
211 |
212 | PlasmaExtras.DescriptiveLabel {
213 | id: label
214 | /* text: 'testttttt' */
215 | anchors {
216 | top: wallpaper.bottom
217 | topMargin: units.smallSpacing
218 | left: parent.left
219 | right: parent.right
220 | }
221 | horizontalAlignment: Text.AlignHCenter
222 | verticalAlignment: Text.AlignTop
223 | /* wrapMode: Text.WordWrap */
224 | /* font.underline: root.activeFocus */
225 | }
226 |
227 | }
228 |
--------------------------------------------------------------------------------
/src/kcm_colorful.cpp:
--------------------------------------------------------------------------------
1 | #include "kcm_colorful.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 |
22 |
23 | K_PLUGIN_FACTORY(KCMColorfulFactory, registerPlugin();)
24 | //K_EXPORT_PLUGIN(KCMColorfulFactory("kcm_colorful"))
25 |
26 |
27 |
28 | KCMColorful::KCMColorful(QWidget *parent, const QVariantList &args)
29 | : KCModule(parent)
30 | {
31 | KAboutData* aboutData = new KAboutData(QStringLiteral("kcm-colorful"), i18n("Colorful"), QLatin1String(PROJECT_VERSION));
32 | aboutData->setShortDescription(i18n("Make your KDE Plasma colorful"));
33 | aboutData->setLicense(KAboutLicense::GPL_V2);
34 | aboutData->setHomepage(QStringLiteral("https://github.com/IsoaSFlus/kcm-colorful"));
35 | aboutData->addAuthor(QStringLiteral("IsoaSFlus"), i18n("Author"), QStringLiteral("me@isoasflus.com"));
36 | setAboutData(aboutData);
37 | QVBoxLayout *vb;
38 | vb = new QVBoxLayout(this);
39 |
40 | root_qml = new QQuickWidget;
41 | kdeclarative = new KDeclarative::KDeclarative();
42 | kdeclarative->setTranslationDomain(QStringLiteral("kcm_colorful"));
43 | kdeclarative->setDeclarativeEngine(root_qml->engine());
44 | kdeclarative->setupContext();
45 | root_qml->setSource(QUrl(QStringLiteral("qrc:/qml/main.qml")));
46 | root_qml->setResizeMode(QQuickWidget::SizeRootObjectToView);
47 |
48 | vb->addWidget(root_qml);
49 | setLayout(vb);
50 |
51 | set_wp_view();
52 |
53 | helper = new QProcess(this);
54 | QObject::connect(helper, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(loadExtractedColors()));
55 |
56 | QQuickItem *object = root_qml->rootObject();
57 | QQuickItem *wb_generate = object->findChild(QStringLiteral("wb_generate"));
58 | QQuickItem *wb_refresh = object->findChild(QStringLiteral("wb_refresh"));
59 | QQuickItem *cuw_row = object->findChild(QStringLiteral("cuw_row"));
60 | QList gv = object->findChildren(QStringLiteral("grid_view"));
61 | QObject::connect(wb_generate, SIGNAL(clicked()), this, SLOT(runHelper()));
62 | QObject::connect(wb_refresh, SIGNAL(clicked()), this, SLOT(set_wp_view()));
63 | QObject::connect(cuw_row, SIGNAL(cuw_clicked(QString)), this, SLOT(apply_color(QString)));
64 | QObject::connect(gv[0], SIGNAL(cu_clicked(QString)), this, SLOT(apply_color(QString)));
65 | QObject::connect(gv[1], SIGNAL(cu_clicked(QString)), this, SLOT(apply_color(QString)));
66 |
67 | readConfig();
68 | }
69 |
70 | KCMColorful::~KCMColorful()
71 | {
72 | saveConfig();
73 | delete root_qml;
74 | delete kdeclarative;
75 | }
76 |
77 | void KCMColorful::readConfig()
78 | {
79 | KSharedConfigPtr cfg;
80 | cfg = KSharedConfig::openConfig();
81 | KConfigGroup kcg(cfg, "KCMColorful");
82 | // kcg.writeEntry(QStringLiteral("test"), QStringLiteral("test"));
83 | auto out = kcg.readEntry(QStringLiteral("RecentColors"), QStringLiteral(""));
84 | recent_colors = out.split(QStringLiteral(","), QString::SkipEmptyParts);
85 | out = kcg.readEntry(QStringLiteral("UserColors"), QStringLiteral(""));
86 | user_colors = out.split(QStringLiteral(","), QString::SkipEmptyParts);
87 | cfg->sync();
88 | cfg->markAsClean();
89 |
90 | for (auto c = recent_colors.rbegin(); c != recent_colors.rend(); ++c) {
91 | addColorGV1(*c);
92 | }
93 | QList gv = root_qml->rootObject()->findChildren(QStringLiteral("grid_view"));
94 | QVariant color_code;
95 | for (auto c : user_colors) {
96 | color_code = c;
97 | QMetaObject::invokeMethod(gv[1], "add_color",
98 | Q_ARG(QVariant, color_code));
99 | }
100 | }
101 |
102 | void KCMColorful::saveConfig()
103 | {
104 | QList gv = root_qml->rootObject()->findChildren(QStringLiteral("grid_view"));
105 | QVariant returnedValue1;
106 | QVariant returnedValue2;
107 | QMetaObject::invokeMethod(gv[0], "get_colors",
108 | Q_RETURN_ARG(QVariant, returnedValue1));
109 | QMetaObject::invokeMethod(gv[1], "get_colors",
110 | Q_RETURN_ARG(QVariant, returnedValue2));
111 |
112 | KSharedConfigPtr cfg;
113 | cfg = KSharedConfig::openConfig();
114 | // qDebug() << cfg->groupList();
115 | KConfigGroup kcg(cfg, "KCMColorful");
116 | kcg.writeEntry(QStringLiteral("RecentColors"), returnedValue1);
117 | kcg.writeEntry(QStringLiteral("UserColors"), returnedValue2);
118 | cfg->sync();
119 | cfg->markAsClean();
120 | }
121 |
122 | void KCMColorful::addColorGV1(QString color)
123 | {
124 | // QList gv_model = root_qml->rootObject()->findChildren(QStringLiteral("gv_model"));
125 | QList gv = root_qml->rootObject()->findChildren(QStringLiteral("grid_view"));
126 | QVariant color_code(color);
127 | QVariant returnedValue;
128 | QMetaObject::invokeMethod(gv[0], "prepend_color",
129 | Q_RETURN_ARG(QVariant, returnedValue),
130 | Q_ARG(QVariant, color_code));
131 | }
132 |
133 | void KCMColorful::set_wp_view()
134 | {
135 | QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.plasmashell"),
136 | QStringLiteral("/PlasmaShell"),
137 | QStringLiteral("org.kde.PlasmaShell"),
138 | QStringLiteral("evaluateScript"));
139 | message.setArguments({
140 | QStringLiteral("var d = desktops();\
141 | d[0].currentConfigGroup = Array(\"Wallpaper\", \"org.kde.image\", \"General\");\
142 | a = d[0].readConfig(\"Image\");a.a()")
143 | });
144 |
145 | auto rep = QDBusConnection::sessionBus().call(message);
146 | QRegularExpression re(QStringLiteral(".*(file://.+) is not a function.*"));
147 | auto match = re.match(rep.arguments()[0].toString());
148 | if (match.hasMatch()) {
149 | current_wallpaper = match.captured(1);
150 | qDebug() << current_wallpaper;
151 | extracted_flag = false;
152 | QQuickItem *wp = root_qml->rootObject()->findChild(QStringLiteral("wp_view"));
153 | wp->setProperty("source", current_wallpaper);
154 | }
155 |
156 | // QProcess p;
157 | // p.start(QStringLiteral("bash"), QStringList() << QStringLiteral("-c") <<
158 | // QStringLiteral("qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript \"var d = desktops();\
159 | // d[0].currentConfigGroup = Array(\\\"Wallpaper\\\", \\\"org.kde.image\\\", \\\"General\\\");\
160 | // a = d[0].readConfig(\\\"Image\\\");a.a()\" | sed -n 's/.*\\(file:\\/\\/.*\\) is not a function.*/\\1/p'"));
161 | // p.waitForFinished();
162 | // QByteArray stdout = p.readAll();
163 | // stdout.chop(1);
164 |
165 | }
166 |
167 | void KCMColorful::runHelper()
168 | {
169 | if (!extracted_flag) {
170 | helper->start(QStringLiteral("kcmcolorfulhelper"), QStringList() << QStringLiteral("--kcm") << QStringLiteral("-p") << current_wallpaper.mid(7));
171 | // QQuickItem *object = root_qml->rootObject();
172 | QQuickItem *wp = root_qml->rootObject()->findChild(QStringLiteral("wp_view"));
173 | wp->setProperty("state", QStringLiteral("busy"));
174 | } else {
175 | loadExtractedColors();
176 | }
177 | }
178 |
179 | void KCMColorful::loadExtractedColors()
180 | {
181 | if (!extracted_flag) {
182 | int i = 0;
183 | QByteArray stdout(helper->readAll());
184 | stdout.chop(1);
185 | colors = QString::fromUtf8(stdout).split(QStringLiteral(","), QString::SkipEmptyParts);
186 | QList cuw = root_qml->rootObject()->findChildren(QStringLiteral("cuw"));
187 | for (auto c : colors) {
188 | cuw[i++]->setProperty("inner_color", c);
189 | }
190 | extracted_flag = true;
191 | }
192 | QQuickItem *wp = root_qml->rootObject()->findChild(QStringLiteral("wp_view"));
193 | wp->setProperty("state", QStringLiteral("generated"));
194 | }
195 |
196 | void KCMColorful::apply_color(const QString &c)
197 | {
198 | qDebug() << c;
199 | QProcess::startDetached(QStringLiteral("kcmcolorfulhelper"), QStringList() << QStringLiteral("-c") << c);
200 | addColorGV1(c);
201 | }
202 | #include "kcm_colorful.moc"
203 |
--------------------------------------------------------------------------------
/src/helper/mmcq.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include "mmcq.h"
7 |
8 |
9 | MMCQ::MMCQ(QString file, bool debug_flag, bool kcm_flag)
10 | {
11 |
12 | QImage i(file);
13 | if (i.isNull()) {
14 | qDebug() << "ERROR: Invalid image file!"; //Invalid image file.
15 | exit(1);
16 | }
17 | img = new QImage(i.convertToFormat(QImage::Format_RGBA8888));
18 | h = img->height();
19 | w = img->width();
20 | this->debug_flag = debug_flag;
21 | this->kcm_flag = kcm_flag;
22 | }
23 |
24 | MMCQ::~MMCQ()
25 | {
26 | delete img;
27 | }
28 |
29 | QList MMCQ::get_palette(int color_count, int quality)
30 | {
31 | pixels.clear();
32 | histo.clear();
33 | QList ret;
34 | for (int i = 0; i < w; i = i + quality)
35 | for (int j = 0; j < h; j++) {
36 | if (qAlpha(img->pixel(i, j)) >= 125) {
37 | if (qRed(img->pixel(i, j)) <= 250 && qGreen(img->pixel(i, j)) <= 250 && qBlue(img->pixel(i, j)) <= 250) {
38 | pixels.push_back(img->pixel(i, j));
39 | }
40 | }
41 | }
42 |
43 | auto colors = quantize(color_count);
44 | for (const auto &c : colors) {
45 | ret.push_back(get_vbox_avg(c));
46 | }
47 | return ret;
48 | }
49 |
50 | int MMCQ::get_color_index(int r, int g, int b)
51 | {
52 | return (r << (2 * sigbits)) + (g << sigbits) + b;
53 | }
54 |
55 | int MMCQ::get_vbox_color_sum(VBox v)
56 | {
57 | int npix = 0;
58 | int index = 0;
59 | for (int i = v.r1; i <= v.r2; i++)
60 | for (int j = v.g1; j <= v.g2; j++)
61 | for (int k = v.b1; k <= v.b2; k++) {
62 | index = get_color_index(i, j, k);
63 | npix += histo[index];
64 | }
65 | return npix;
66 | }
67 |
68 | void MMCQ::calc_histo()
69 | {
70 | int index = 0;
71 | for (unsigned int i = 0; i < pixels.size(); i++) {
72 | index = get_color_index(qRed(pixels[i]) >> rshift, qGreen(pixels[i]) >> rshift, qBlue(pixels[i]) >> rshift);
73 | histo[index]++;
74 | }
75 |
76 | }
77 |
78 | VBox MMCQ::gen_vbox()
79 | {
80 | int rval, gval, bval;
81 | int rmin = 1000000;
82 | int rmax = 0;
83 | int gmin = 1000000;
84 | int gmax = 0;
85 | int bmin = 1000000;
86 | int bmax = 0;
87 | for (unsigned int i = 0; i < pixels.size(); i++) {
88 | rval = qRed(pixels[i]) >> rshift;
89 | gval = qGreen(pixels[i]) >> rshift;
90 | bval = qBlue(pixels[i]) >> rshift;
91 |
92 | rmin = std::min(rval, rmin);
93 | rmax = std::max(rval, rmax);
94 | gmin = std::min(gval, gmin);
95 | gmax = std::max(gval, gmax);
96 | bmin = std::min(bval, bmin);
97 | bmax = std::max(bval, bmax);
98 | }
99 |
100 | VBox vbox(rmin, rmax, gmin, gmax, bmin, bmax);
101 | return vbox;
102 | }
103 |
104 | std::vector MMCQ::do_median_cut(VBox v)
105 | {
106 | std::vector ret;
107 |
108 | if (get_vbox_color_sum(v) == 1) {
109 | ret.push_back(v);
110 | return ret;
111 | }
112 |
113 | std::vector side;
114 | side.push_back(v.r2 - v.r1);
115 | side.push_back(v.g2 - v.g1);
116 | side.push_back(v.b2 - v.b1);
117 |
118 | auto max_side = std::max_element(side.begin(), side.end());
119 |
120 | int sub_sum = 0;
121 | int total = 0;
122 | std::unordered_map partial_sum;
123 | int index = 0;
124 | int dim1 = 0;
125 | int dim2 = 0;
126 |
127 | if (*max_side == side[0]) {
128 | dim1 = v.r1;
129 | dim2 = v.r2;
130 | for (int i = v.r1; i <= v.r2; i++) {
131 | for (int j = v.g1; j <= v.g2; j++)
132 | for (int k = v.b1; k <= v.b2; k++) {
133 | index = get_color_index(i, j, k);
134 | sub_sum += histo[index];
135 | }
136 | total += sub_sum;
137 | partial_sum[i] = total;
138 | }
139 | } else if (*max_side == side[1]) {
140 | dim1 = v.g1;
141 | dim2 = v.g2;
142 | for (int i = v.g1; i <= v.g2; i++) {
143 | for (int j = v.r1; j <= v.r2; j++)
144 | for (int k = v.b1; k <= v.b2; k++) {
145 | index = get_color_index(i, j, k);
146 | sub_sum += histo[index];
147 | }
148 | total += sub_sum;
149 | partial_sum[i] = total;
150 | }
151 | } else {
152 | dim1 = v.b1;
153 | dim2 = v.b2;
154 | for (int i = v.b1; i <= v.b2; i++) {
155 | for (int j = v.r1; j <= v.r2; j++)
156 | for (int k = v.g1; k <= v.g2; k++) {
157 | index = get_color_index(i, j, k);
158 | sub_sum += histo[index];
159 | }
160 | total += sub_sum;
161 | partial_sum[i] = total;
162 | }
163 | }
164 |
165 |
166 | for (int i = dim1; i <= dim2; i++) {
167 | if (partial_sum[i] > (total / 2)) {
168 | int left = i - dim1;
169 | int right = dim2 - i;
170 | int d2 = dim1;
171 | if (left <= right) {
172 | if ((dim2 - 1) > (i + (right / 2))) {
173 | d2 = i + (right / 2);
174 | } else {
175 | d2 = dim2 -1;
176 | }
177 | } else {
178 | if ((dim1) < (i - 1 - (left / 2))) {
179 | d2 = i - 1 - (left / 2);
180 | } else {
181 | d2 = dim1;
182 | }
183 | }
184 |
185 | int count2 = 0;
186 | while (!partial_sum[d2]) {
187 | d2++;
188 | count2 = total - partial_sum[d2];
189 | }
190 | while ((count2 == 0) && partial_sum[d2]) {
191 | d2--;
192 | count2 = total - partial_sum[d2];
193 | }
194 |
195 | VBox v1 = v;
196 | VBox v2 = v;
197 | if (*max_side == side[0]) {
198 | v1.r2 = d2;
199 | v2.r1 = d2 + 1;
200 | } else if (*max_side == side[1]) {
201 | v1.g2 = d2;
202 | v2.g1 = d2 + 1;
203 | } else {
204 | v1.b2 = d2;
205 | v2.b1 = d2 + 1;
206 | }
207 | ret.push_back(v1);
208 | ret.push_back(v2);
209 | return ret;
210 | }
211 | }
212 | return ret;
213 | }
214 |
215 | QColor MMCQ::get_vbox_avg(VBox v)
216 | {
217 | int ntot = 0;
218 | int mult = 1 << (8 - sigbits);
219 | int r_sum = 0;
220 | int g_sum = 0;
221 | int b_sum = 0;
222 | int r_avg = 0;
223 | int g_avg = 0;
224 | int b_avg = 0;
225 |
226 | int index = 0;
227 | int hval = 0;
228 | for (int i = v.r1; i <= v.r2; i++)
229 | for (int j = v.g1; j <= v.g2; j++)
230 | for (int k = v.b1; k <= v.b2; k++) {
231 | index = get_color_index(i, j, k);
232 | hval = histo[index];
233 | ntot += hval;
234 | r_sum += hval * (i + 0.5) * mult;
235 | g_sum += hval * (j + 0.5) * mult;
236 | b_sum += hval * (k + 0.5) * mult;
237 | }
238 | if (ntot) {
239 | r_avg = int(r_sum / ntot);
240 | g_avg = int(g_sum / ntot);
241 | b_avg = int(b_sum / ntot);
242 | } else {
243 | r_avg = int(mult * (v.r1 + v.r2 + 1) / 2);
244 | g_avg = int(mult * (v.g1 + v.g2 + 1) / 2);
245 | b_avg = int(mult * (v.b1 + v.b2 + 1) / 2);
246 | }
247 |
248 | QColor c(r_avg, g_avg, b_avg);
249 | return c;
250 | }
251 |
252 | std::vector MMCQ::quantize(int max_color)
253 | {
254 | std::vector ret;
255 | calc_histo();
256 |
257 | auto vbox = gen_vbox();
258 |
259 | auto cmp1 = [&](VBox left, VBox right) {
260 | auto left_val = get_vbox_color_sum(left);
261 | auto right_val = get_vbox_color_sum(right);
262 | return left_val < right_val;
263 | };
264 | std::priority_queue, decltype(cmp1)> pq1(cmp1);
265 | pq1.push(vbox);
266 |
267 | quantize_iter(pq1, max_color * fract_by_populations);
268 |
269 | auto cmp2 = [&](VBox left, VBox right) {
270 | auto left_val = get_vbox_color_sum(left);
271 | auto right_val = get_vbox_color_sum(right);
272 | left_val = left_val * (left.r2 - left.r1) * (left.g2 - left.g1) * (left.b2 - left.b1);
273 | right_val = right_val * (right.r2 - right.r1) * (right.g2 - right.g1) * (right.b2 - right.b1);
274 | return left_val < right_val;
275 | };
276 | std::priority_queue, decltype(cmp2)> pq2(cmp2);
277 | while (!pq1.empty()) {
278 | pq2.push(pq1.top());
279 | pq1.pop();
280 | }
281 | quantize_iter(pq2, max_color - pq2.size() + 1);
282 |
283 | while (!pq2.empty()) {
284 | ret.push_back(pq2.top());
285 | pq2.pop();
286 | }
287 | return ret;
288 | }
289 |
290 | template
291 | void MMCQ::quantize_iter(T &t, int target)
292 | {
293 | int n_color = 1;
294 | int i = 0;
295 | while (i < max_iter) {
296 |
297 | auto v = t.top();
298 | t.pop();
299 | if (!get_vbox_color_sum(v)) {
300 | t.push(v);
301 | i++;
302 | continue;
303 | }
304 | auto vboxes = do_median_cut(v);
305 | if (vboxes.empty()) {
306 | return;
307 | }
308 | t.push(vboxes[0]);
309 | if (vboxes.size() > 1) {
310 | t.push(vboxes[1]);
311 | n_color++;
312 | }
313 |
314 | if (n_color >= target) {
315 | return;
316 | }
317 |
318 | if (i > max_iter) {
319 | qDebug() << "meet max";
320 | return;
321 | }
322 | i++;
323 | }
324 | }
325 |
326 |
327 | VBox::VBox()
328 | {
329 | r1 = 0;
330 | g1 = 0;
331 | b1 = 0;
332 | r2 = 0;
333 | g2 = 0;
334 | b2 = 0;
335 | }
336 |
337 | VBox::VBox(int r1, int r2, int g1, int g2, int b1, int b2)
338 | {
339 | this->r1 = r1;
340 | this->g1 = g1;
341 | this->b1 = b1;
342 | this->r2 = r2;
343 | this->g2 = g2;
344 | this->b2 = b2;
345 | }
346 |
347 | VBox::~VBox()
348 | {
349 |
350 | }
351 |
352 |
353 |
--------------------------------------------------------------------------------
/src/helper/colordata.h:
--------------------------------------------------------------------------------
1 | #ifndef _COLORDATA
2 | #define _COLORDATA
3 |
4 | const int colordata[256][3] = {{247, 172, 188},
5 | {222, 171, 138},
6 | {129, 121, 54},
7 | {68, 70, 147},
8 | {239, 91, 156},
9 | {254, 220, 189},
10 | {127, 117, 34},
11 | {43, 68, 144},
12 | {254, 238, 237},
13 | {244, 121, 32},
14 | {128, 117, 44},
15 | {42, 92, 170},
16 | {240, 91, 114},
17 | {144, 90, 61},
18 | {135, 132, 59},
19 | {34, 75, 143},
20 | {241, 91, 108},
21 | {143, 75, 46},
22 | {114, 105, 48},
23 | {0, 58, 108},
24 | {248, 171, 166},
25 | {135, 72, 31},
26 | {69, 73, 38},
27 | {16, 43, 106},
28 | {246, 156, 159},
29 | {95, 60, 35},
30 | {46, 58, 31},
31 | {66, 106, 179},
32 | {245, 143, 152},
33 | {107, 71, 60},
34 | {77, 79, 54},
35 | {70, 72, 95},
36 | {202, 134, 135},
37 | {250, 167, 85},
38 | {183, 186, 107},
39 | {78, 114, 184},
40 | {243, 145, 169},
41 | {250, 178, 123},
42 | {178, 210, 53},
43 | {24, 29, 75},
44 | {189, 103, 88},
45 | {245, 130, 32},
46 | {92, 122, 41},
47 | {26, 41, 51},
48 | {215, 19, 69},
49 | {132, 57, 0},
50 | {190, 215, 66},
51 | {18, 26, 42},
52 | {214, 79, 68},
53 | {144, 93, 29},
54 | {127, 184, 14},
55 | {12, 33, 43},
56 | {217, 58, 73},
57 | {138, 93, 25},
58 | {163, 207, 98},
59 | {106, 109, 169},
60 | {179, 66, 74},
61 | {140, 83, 27},
62 | {118, 145, 73},
63 | {88, 94, 170},
64 | {199, 105, 104},
65 | {130, 104, 88},
66 | {109, 131, 70},
67 | {73, 78, 143},
68 | {187, 80, 93},
69 | {100, 73, 43},
70 | {120, 163, 85},
71 | {175, 180, 219},
72 | {152, 113, 101},
73 | {174, 102, 66},
74 | {171, 200, 139},
75 | {155, 149, 201},
76 | {172, 103, 103},
77 | {86, 69, 45},
78 | {116, 144, 93},
79 | {105, 80, 161},
80 | {151, 60, 63},
81 | {150, 88, 42},
82 | {205, 230, 199},
83 | {111, 96, 170},
84 | {178, 44, 70},
85 | {112, 86, 40},
86 | {29, 149, 63},
87 | {134, 120, 146},
88 | {167, 50, 74},
89 | {74, 49, 19},
90 | {119, 172, 152},
91 | {145, 133, 151},
92 | {170, 54, 61},
93 | {65, 47, 31},
94 | {0, 125, 101},
95 | {111, 109, 133},
96 | {237, 25, 65},
97 | {132, 85, 56},
98 | {132, 191, 150},
99 | {89, 76, 109},
100 | {242, 101, 34},
101 | {142, 116, 55},
102 | {69, 185, 124},
103 | {105, 77, 159},
104 | {210, 85, 61},
105 | {105, 84, 27},
106 | {34, 90, 31},
107 | {111, 89, 156},
108 | {180, 83, 75},
109 | {213, 197, 159},
110 | {54, 116, 89},
111 | {133, 82, 161},
112 | {239, 65, 54},
113 | {205, 154, 91},
114 | {0, 121, 71},
115 | {84, 48, 68},
116 | {198, 60, 38},
117 | {205, 154, 91},
118 | {64, 131, 94},
119 | {99, 67, 79},
120 | {243, 113, 92},
121 | {179, 109, 65},
122 | {43, 100, 71},
123 | {125, 88, 134},
124 | {167, 87, 59},
125 | {223, 148, 100},
126 | {0, 88, 49},
127 | {64, 28, 68},
128 | {170, 33, 22},
129 | {183, 111, 64},
130 | {0, 108, 84},
131 | {71, 45, 86},
132 | {182, 69, 51},
133 | {173, 139, 61},
134 | {55, 88, 48},
135 | {69, 34, 74},
136 | {181, 67, 52},
137 | {222, 163, 44},
138 | {39, 77, 61},
139 | {65, 20, 69},
140 | {133, 63, 4},
141 | {209, 146, 63},
142 | {55, 88, 48},
143 | {75, 47, 61},
144 | {132, 2, 40},
145 | {200, 132, 0},
146 | {39, 52, 43},
147 | {64, 46, 76},
148 | {122, 23, 35},
149 | {195, 126, 0},
150 | {101, 194, 148},
151 | {199, 126, 181},
152 | {160, 57, 57},
153 | {195, 126, 0},
154 | {115, 185, 162},
155 | {234, 102, 166},
156 | {138, 46, 59},
157 | {224, 134, 26},
158 | {114, 186, 167},
159 | {241, 115, 172},
160 | {142, 69, 63},
161 | {255, 206, 123},
162 | {0, 83, 68},
163 | {255, 255, 251},
164 | {143, 75, 74},
165 | {252, 175, 23},
166 | {18, 46, 41},
167 | {255, 254, 249},
168 | {137, 47, 27},
169 | {186, 132, 72},
170 | {41, 48, 71},
171 | {246, 245, 236},
172 | {107, 44, 37},
173 | {137, 106, 69},
174 | {0, 174, 157},
175 | {217, 214, 195},
176 | {115, 58, 49},
177 | {118, 98, 76},
178 | {80, 138, 136},
179 | {209, 199, 183},
180 | {84, 33, 29},
181 | {109, 88, 38},
182 | {112, 161, 159},
183 | {242, 234, 218},
184 | {120, 51, 30},
185 | {255, 194, 14},
186 | {80, 183, 193},
187 | {211, 215, 212},
188 | {83, 38, 31},
189 | {253, 185, 51},
190 | {0, 166, 172},
191 | {153, 157, 156},
192 | {241, 90, 34},
193 | {211, 198, 166},
194 | {120, 205, 209},
195 | {161, 163, 166},
196 | {180, 83, 60},
197 | {199, 162, 82},
198 | {0, 135, 146},
199 | {157, 144, 135},
200 | {132, 51, 31},
201 | {222, 198, 116},
202 | {148, 214, 218},
203 | {138, 140, 142},
204 | {244, 122, 85},
205 | {182, 153, 104},
206 | {175, 223, 228},
207 | {116, 120, 124},
208 | {241, 90, 34},
209 | {193, 161, 115},
210 | {94, 124, 133},
211 | {124, 133, 119},
212 | {243, 112, 75},
213 | {219, 206, 143},
214 | {118, 190, 204},
215 | {114, 119, 123},
216 | {218, 118, 91},
217 | {255, 212, 0},
218 | {144, 215, 236},
219 | {119, 120, 123},
220 | {200, 93, 68},
221 | {255, 212, 0},
222 | {0, 154, 214},
223 | {79, 85, 85},
224 | {174, 80, 57},
225 | {255, 230, 0},
226 | {20, 91, 125},
227 | {108, 76, 73},
228 | {106, 52, 39},
229 | {240, 220, 112},
230 | {17, 38, 79},
231 | {86, 54, 36},
232 | {143, 75, 56},
233 | {252, 241, 110},
234 | {123, 191, 234},
235 | {62, 65, 69},
236 | {142, 62, 31},
237 | {222, 203, 0},
238 | {51, 163, 220},
239 | {60, 54, 69},
240 | {243, 108, 33},
241 | {203, 197, 71},
242 | {34, 143, 189},
243 | {70, 69, 71},
244 | {180, 83, 42},
245 | {110, 107, 65},
246 | {36, 104, 162},
247 | {19, 12, 14},
248 | {183, 112, 79},
249 | {89, 96, 50},
250 | {37, 112, 161},
251 | {40, 31, 29},
252 | {222, 119, 63},
253 | {82, 95, 66},
254 | {37, 133, 166},
255 | {47, 39, 29},
256 | {201, 153, 121},
257 | {95, 93, 70},
258 | {27, 49, 94},
259 | {29, 22, 38}};
260 | #endif
261 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 |
294 | Copyright (C)
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | , 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------
/src/helper/kcmcolorfulhelper.cpp:
--------------------------------------------------------------------------------
1 | #include "kcmcolorfulhelper.h"
2 | #include "colordata.h"
3 | #include "mmcq.h"
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | KcmColorfulHelper::KcmColorfulHelper(QStringList args, QObject *parent) : QObject(parent)
17 | {
18 | QTime time = QTime::currentTime();
19 | qsrand(static_cast(time.msec()));
20 | mConfig = KSharedConfig::openConfig(QStringLiteral("kdeglobals"));
21 |
22 | if (args[4] == "true") {
23 | debug_flag = true;
24 | }
25 | if (args[5] == "true") {
26 | kcm_flag = true;
27 | }
28 | bool ok = false;
29 | paletteNum = args[2].toInt(&ok);
30 | if (ok == true) {
31 | if (paletteNum < 1 || paletteNum > 16) {
32 | paletteNum = 8;
33 | }
34 | } else {
35 | paletteNum = 8;
36 | }
37 | ok = false;
38 | selectNum = args[6].toInt(&ok);
39 | if (ok != true) {
40 | selectNum = 1;
41 | }
42 | if (args[0] == QString("kcmcolorful-NOPIC")) {
43 | if (args[1] != QString("kcmcolorful-NOCOLOR")) {
44 | c = new QColor(args[1]);
45 | run_type = run_type | 0x02u;
46 | } else {
47 | run_type = run_type & (~0x02u);
48 | }
49 | } else {
50 | wallpaperFilePath = args[0];
51 | mmcq = new MMCQ(wallpaperFilePath, debug_flag, kcm_flag);
52 | if (args[3] == "true") {
53 | setWallpaper(args[0]);
54 | }
55 | run_type = run_type | 0x02u;
56 | }
57 |
58 | ok = false;
59 | theme_opacity = args[7].toDouble(&ok);
60 | run_type = run_type | 0x01u;
61 | if (ok != true) {
62 | theme_opacity = 0.6;
63 | run_type = run_type & (~0x01u);
64 | }
65 |
66 | // genCSName();
67 | // getPrevCSName();
68 | // readDefaultCS();
69 | }
70 |
71 | KcmColorfulHelper::~KcmColorfulHelper()
72 | {
73 | delete c;
74 | delete mmcq;
75 | }
76 |
77 | void KcmColorfulHelper::run()
78 | {
79 | // for theme color
80 | if ((run_type & 0x02u) != 0) {
81 | if (mmcq != nullptr) {
82 | palette = mmcq->get_palette(paletteNum);
83 | palette_16 = mmcq->get_palette(16);
84 | calcColor();
85 | }
86 | int i = 1;
87 | if (kcm_flag == true) {
88 | QStringList colors;
89 | while (i <= 4) {
90 | colors << color_refine((pt_and_color.cend() - i).value()).name();
91 | if (pt_and_color.cend() - i == pt_and_color.cbegin()) {
92 | break;
93 | }
94 | i++;
95 | }
96 | for (auto color : colors) {
97 | std::cout << color.toStdString() << ",";
98 | }
99 | std::cout << std::endl;
100 | } else {
101 | if (!c) {
102 | while (i <= 4) {
103 | auto it = pt_and_color.cend() - i;
104 | QColor color = it.value();
105 | color = color_refine(color);
106 | if (selectNum == i) {
107 | c = new QColor(color);
108 | }
109 | qDebug().noquote() << QString("Candidate: %4, %1, %2, %3 \033[48;2;%1;%2;%3m \033[0m").arg(QString::number(color.red()), QString::number(color.green()), QString::number(color.blue()), QString::number(it.key()));
110 | if (it == pt_and_color.cbegin()) {
111 | c = new QColor(color);
112 | break;
113 | }
114 | i++;
115 | }
116 | qDebug().noquote() << QString("Choose: %1, %2, %3 \033[48;2;%1;%2;%3m \033[0m").arg(QString::number(c->red()), QString::number(c->green()), QString::number(c->blue()));
117 | }
118 | readTemplateCS();
119 | // changeColorScheme(tConfig);
120 | changeColorSchemeB();
121 | save();
122 | mConfig->markAsClean();
123 | tConfig->markAsClean();
124 | }
125 | }
126 | // for theme opacity
127 | if ((run_type & 0x01u) != 0) {
128 | changeThemeOpacity();
129 | }
130 | }
131 |
132 | void KcmColorfulHelper::getPrevCSName()
133 | {
134 | KSharedConfigPtr cfg = KSharedConfig::openConfig(QStringLiteral("kdeglobals"));
135 | KConfigGroup groupOut(cfg, "General");
136 | prevColorSchemeName = groupOut.readEntry("ColorScheme");
137 | }
138 |
139 | void KcmColorfulHelper::readTemplateCS()
140 | {
141 | QString tName;
142 | if (isDarkTheme()) {
143 | tName = "ColorfulDark";
144 | } else {
145 | tName = "ColorfulLight";
146 | }
147 |
148 | QString schemeFile;
149 |
150 | schemeFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "color-schemes/" + tName + ".colors");
151 | QFile file(schemeFile);
152 |
153 | if (!file.exists()) {
154 | schemeFile = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)
155 | + "/color-schemes/" + "BreezeIso.colors";
156 | }
157 | debug_flag ? qDebug().noquote() << schemeFile : qDebug();
158 | tConfig = KSharedConfig::openConfig(schemeFile);
159 | }
160 |
161 | void KcmColorfulHelper::changeColorScheme()
162 | {
163 | KConfigGroup group(mConfig, "Colors:View");
164 | // qDebug() << group.readEntry("ForegroundNormal");
165 |
166 | group.writeEntry("ForegroundNormal", addJitter(group.readEntry("ForegroundNormal")));
167 | group.writeEntry("DecorationHover", *c);
168 |
169 |
170 | // KConfigGroup groupWMTheme(config, "WM");
171 | KConfigGroup groupWMOut(mConfig, "WM");
172 |
173 | QStringList colorItemListWM;
174 | colorItemListWM << "activeBackground"
175 | << "activeForeground"
176 | << "inactiveBackground"
177 | << "inactiveForeground";
178 | // << "activeBlend"
179 | // << "inactiveBlend";
180 |
181 | QVector defaultWMColors;
182 | defaultWMColors << *c
183 | << QColor(239,240,241)
184 | << *c
185 | << QColor(189,195,199)
186 | /* << QColor(255,255,255)
187 | << QColor(75,71,67)*/;
188 |
189 | int i = 0;
190 | for (const QString &coloritem : colorItemListWM)
191 | {
192 | groupWMOut.writeEntry(coloritem, defaultWMColors.value(i));
193 | ++i;
194 | }
195 | }
196 |
197 | void KcmColorfulHelper::changeColorSchemeB()
198 | {
199 | KConfigGroup group(mConfig, "Colors:View");
200 | group.writeEntry("ForegroundLink", *c);
201 | group.writeEntry("DecorationHover", *c);
202 | KConfigGroup groupWM(mConfig, "WM");
203 | groupWM.writeEntry("activeBackground", *c);
204 | groupWM.writeEntry("inactiveBackground", *c);
205 | }
206 |
207 | void KcmColorfulHelper::changeColorScheme(KSharedConfigPtr config)
208 | {
209 | // // store colorscheme name in global settings
210 | // mConfig = KSharedConfig::openConfig(QStringLiteral("kdeglobals"));
211 | // KConfigGroup groupOut(mConfig, "General");
212 | // qDebug() << groupOut.readEntry("ColorScheme");
213 | // groupOut.writeEntry("ColorScheme", colorSchemeName);
214 |
215 | QStringList colorItemList;
216 | colorItemList << "BackgroundNormal"
217 | << "BackgroundAlternate"
218 | << "ForegroundNormal"
219 | << "ForegroundInactive"
220 | << "ForegroundActive"
221 | << "ForegroundLink"
222 | << "ForegroundVisited"
223 | << "ForegroundNegative"
224 | << "ForegroundNeutral"
225 | << "ForegroundPositive"
226 | << "DecorationFocus"
227 | << "DecorationHover";
228 |
229 | QStringList colorSetGroupList;
230 | colorSetGroupList << "Colors:View"
231 | << "Colors:Window"
232 | << "Colors:Button"
233 | << "Colors:Selection"
234 | << "Colors:Tooltip"
235 | << "Colors:Complementary";
236 |
237 | QList colorSchemes;
238 |
239 | colorSchemes.append(KColorScheme(QPalette::Active, KColorScheme::View, config));
240 | colorSchemes.append(KColorScheme(QPalette::Active, KColorScheme::Window, config));
241 | colorSchemes.append(KColorScheme(QPalette::Active, KColorScheme::Button, config));
242 | colorSchemes.append(KColorScheme(QPalette::Active, KColorScheme::Selection, config));
243 | colorSchemes.append(KColorScheme(QPalette::Active, KColorScheme::Tooltip, config));
244 | colorSchemes.append(KColorScheme(QPalette::Active, KColorScheme::Complementary, config));
245 |
246 | for (int i = 0; i < colorSchemes.length(); ++i)
247 | {
248 | KConfigGroup group(mConfig, colorSetGroupList.value(i));
249 | group.writeEntry("BackgroundNormal", addJitter(colorSchemes[i].background(KColorScheme::NormalBackground).color()));
250 | group.writeEntry("BackgroundAlternate", colorSchemes[i].background(KColorScheme::AlternateBackground).color());
251 | group.writeEntry("ForegroundNormal", addJitter(colorSchemes[i].foreground(KColorScheme::NormalText).color()));
252 | group.writeEntry("ForegroundInactive", colorSchemes[i].foreground(KColorScheme::InactiveText).color());
253 | group.writeEntry("ForegroundActive", colorSchemes[i].foreground(KColorScheme::ActiveText).color());
254 | group.writeEntry("ForegroundLink", colorSchemes[i].foreground(KColorScheme::LinkText).color());
255 | group.writeEntry("ForegroundVisited", colorSchemes[i].foreground(KColorScheme::VisitedText).color());
256 | group.writeEntry("ForegroundNegative", colorSchemes[i].foreground(KColorScheme::NegativeText).color());
257 | group.writeEntry("ForegroundNeutral", colorSchemes[i].foreground(KColorScheme::NeutralText).color());
258 | group.writeEntry("ForegroundPositive", colorSchemes[i].foreground(KColorScheme::PositiveText).color());
259 | group.writeEntry("DecorationFocus", colorSchemes[i].decoration(KColorScheme::FocusColor).color());
260 | if (i == 0) {
261 | group.writeEntry("DecorationHover", *c);
262 | } else {
263 | group.writeEntry("DecorationHover", colorSchemes[i].decoration(KColorScheme::HoverColor).color());
264 | }
265 | }
266 |
267 | KConfigGroup groupWMTheme(config, "WM");
268 | KConfigGroup groupWMOut(mConfig, "WM");
269 |
270 | QStringList colorItemListWM;
271 | colorItemListWM << "activeBackground"
272 | << "activeForeground"
273 | << "inactiveBackground"
274 | << "inactiveForeground"
275 | << "activeBlend"
276 | << "inactiveBlend";
277 |
278 | QVector defaultWMColors;
279 | defaultWMColors << *c
280 | << colorSchemes[1].foreground(KColorScheme::NormalText).color()
281 | << *c
282 | << colorSchemes[1].foreground(KColorScheme::NormalText).color()
283 | << QColor(255,255,255)
284 | << QColor(75,71,67);
285 |
286 | int i = 0;
287 | for (const QString &coloritem : colorItemListWM)
288 | {
289 | groupWMOut.writeEntry(coloritem, defaultWMColors.value(i));
290 | ++i;
291 | }
292 |
293 | QStringList groupNameList;
294 | groupNameList << "ColorEffects:Inactive" << "ColorEffects:Disabled";
295 |
296 | QStringList effectList;
297 | effectList << "Enable"
298 | << "ChangeSelectionColor"
299 | << "IntensityEffect"
300 | << "IntensityAmount"
301 | << "ColorEffect"
302 | << "ColorAmount"
303 | << "Color"
304 | << "ContrastEffect"
305 | << "ContrastAmount";
306 |
307 | for (const QString &groupName : groupNameList)
308 | {
309 |
310 | KConfigGroup groupEffectOut(mConfig, groupName);
311 | KConfigGroup groupEffectTheme(config, groupName);
312 |
313 | for (const QString &effect : effectList) {
314 | groupEffectOut.writeEntry(effect, groupEffectTheme.readEntry(effect));
315 | }
316 | }
317 | }
318 |
319 | void KcmColorfulHelper::save()
320 | {
321 | mConfig->sync();
322 |
323 | // KConfig cfg(QStringLiteral("kcmdisplayrc"), KConfig::NoGlobals);
324 | // KConfigGroup displayGroup(&cfg, "X11");
325 |
326 | // displayGroup.writeEntry("exportKDEColors", true);
327 |
328 | // cfg.sync();
329 |
330 | // QSettings* settings = new QSettings(QLatin1String("Trolltech"));
331 | // KSharedConfigPtr kglobalcfg = KSharedConfig::openConfig( "kdeglobals" );
332 | // KConfigGroup kglobals(kglobalcfg, "KDE");
333 | // QPalette newPal = KColorScheme::createApplicationPalette(kglobalcfg);
334 | // applyQtColors(kglobalcfg, *settings, newPal);
335 | // delete settings;
336 | // runRdb(KRdbExportQtColors | KRdbExportGtkTheme | KRdbExportColors);
337 |
338 |
339 | QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KGlobalSettings"),
340 | QStringLiteral("org.kde.KGlobalSettings"),
341 | QStringLiteral("notifyChange"));
342 | message.setArguments({
343 | 0, //previous KGlobalSettings::PaletteChanged. This is now private API in khintsettings
344 | 0 //unused in palette changed but needed for the DBus signature
345 | });
346 | QDBusConnection::sessionBus().send(message);
347 |
348 | // QDBusMessage message_2 = QDBusMessage::createSignal(QStringLiteral("/KWin"), QStringLiteral("org.kde.KWin"), QStringLiteral("reloadConfig"));
349 | // QDBusConnection::sessionBus().send(message_2);
350 |
351 | // QThread::sleep(1);
352 | // QDBusConnection::sessionBus().send(message_2);
353 | }
354 |
355 | void KcmColorfulHelper::genCSName()
356 | {
357 | colorSchemeName = "" + QUuid::createUuid().toString(QUuid::WithoutBraces).mid(0, 6);
358 | }
359 |
360 | void KcmColorfulHelper::saveCSFile()
361 | {
362 |
363 | QString newpath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)
364 | + "/color-schemes/";
365 | QProcess::execute(QString("bash -c \"rm '%1Colorful-*'\"").arg(newpath));
366 | QDir dir;
367 | dir.mkpath(newpath);
368 | newpath += colorSchemeName + ".colors";
369 |
370 |
371 | KConfig *config = mConfig->copyTo(newpath);
372 | // mConfig->markAsClean();
373 | // m_config->reparseConfiguration();
374 | KConfigGroup groupA(config, "General");
375 | groupA.writeEntry("Name", colorSchemeName);
376 |
377 | KConfigGroup group(config, "Colors:View");
378 | group.writeEntry("DecorationHover", *c);
379 |
380 |
381 | // KConfigGroup groupWMTheme(config, "WM");
382 | KConfigGroup groupWMOut(config, "WM");
383 |
384 | QStringList colorItemListWM;
385 | colorItemListWM << "activeBackground"
386 | << "activeForeground"
387 | << "inactiveBackground"
388 | << "inactiveForeground";
389 | // << "activeBlend"
390 | // << "inactiveBlend";
391 |
392 | QVector defaultWMColors;
393 | defaultWMColors << *c
394 | << QColor(239,240,241)
395 | << *c
396 | << QColor(189,195,199)
397 | /* << QColor(255,255,255)
398 | << QColor(75,71,67)*/;
399 |
400 | int i = 0;
401 | for (const QString &coloritem : colorItemListWM)
402 | {
403 | groupWMOut.writeEntry(coloritem, defaultWMColors.value(i));
404 | ++i;
405 | }
406 |
407 |
408 | // sync it and delete pointer
409 | config->sync();
410 | // changeColorScheme(config);
411 | delete config;
412 | KSharedConfigPtr rConfig = KSharedConfig::openConfig(newpath);
413 | changeColorScheme(rConfig);
414 |
415 | }
416 |
417 | QColor KcmColorfulHelper::addJitter(QColor color)
418 | {
419 | return QColor(color.red() + (qrand()%5 - 2), color.green() + (qrand()%5 - 2), color.blue() + (qrand()%5 - 2));
420 | }
421 |
422 | bool KcmColorfulHelper::isDarkTheme()
423 | {
424 | if (c->red() < 66 && c->green() < 66 && c->blue() < 80) {
425 | return true;
426 | } else {
427 | return false;
428 | }
429 | }
430 |
431 | void KcmColorfulHelper::calcColor()
432 | {
433 | double pt = 0;
434 | double pt_val = 0;
435 | double pt_sat = 0;
436 | double pt_hue = 0;
437 | double hue = 0;
438 | double sat = 0;
439 | double val = 0;
440 | double A = 0;
441 | int i = 0;
442 | int j = 0;
443 |
444 | double weight_of_order[8] = {1, 1, 1, 0.95, 0.9, 0.8, 0.7, 0.6};
445 | QList colors;
446 |
447 | // QList::iterator it;
448 | i = 0;
449 | for (auto it = palette.begin(); it != palette.end() && (it - palette.begin()) < 8; ++it) {
450 | colors << *it;
451 | i++;
452 | }
453 | for (auto it = palette_16.begin(); it != palette_16.end() && (it - palette_16.begin()) < 8; ++it) {
454 | colors << *it;
455 | }
456 |
457 | j = 0;
458 | for (auto color : colors) {
459 | pt = 0;
460 | pt_val = 0;
461 | pt_sat = 0;
462 | pt_hue = 0;
463 | val = color.value();
464 | sat = color.saturation();
465 | hue = color.hue();
466 |
467 | A = 220.0 + (0.137 * (255.0 - sat));
468 | if (val < A) {
469 | pt_val = 80.0 - ((A - val) / A * 80.0);
470 | } else {
471 | pt_val = 80.0 + ((val - A) / (255.0 - A) * 20.0);
472 | }
473 |
474 | if (sat < 70) {
475 | pt_sat = 100.0 - ((70.0 - sat) / 70.0 * 100.0);
476 | } else if (sat > 220) {
477 | pt_sat = 100.0 - ((sat - 220.0) / 35.0 * 100.0);
478 | } else {
479 | pt_sat = 100;
480 | }
481 |
482 | if (hue > 159 && hue < 196) {
483 | if (hue < 180) {
484 | pt_hue = 100.0 - (50.0 * (hue - 159.0) / 21.0);
485 | } else {
486 | pt_hue = 100.0 - (50.0 * (196.0 - hue) / 16.0);
487 | }
488 | } else {
489 | pt_hue = 100;
490 | }
491 |
492 | pt = (pt_val + pt_sat + pt_hue) / 3;
493 | pt = weight_of_order[j] * pt;
494 |
495 | pt_and_color.insert(pt, color);
496 | debug_flag ? qDebug().noquote() << QString("%1, %2, %3 \033[48;2;%1;%2;%3m \033[0m %5, %6, %7, weight: %4").arg(QString::number(color.red()), QString::number(color.green()), QString::number(color.blue()), QString::number(pt), QString::number(pt_val), QString::number(pt_sat), QString::number(pt_hue)) : qDebug();
497 | j++;
498 | if (j >= i) {
499 | debug_flag ? qDebug().noquote() << "================" : qDebug();
500 | j = 0;
501 | i = 114514;
502 | }
503 | }
504 | }
505 |
506 | void KcmColorfulHelper::setWallpaper(QString pic)
507 | {
508 | QProcess::execute("qdbus", QStringList() << "org.kde.plasmashell" << "/PlasmaShell" << "org.kde.PlasmaShell.evaluateScript" << QString("var a = desktops();\
509 | for(i = 0; i < a.length; i++){\
510 | d = a[i];d.wallpaperPlugin = \"org.kde.image\";\
511 | d.currentConfigGroup = Array(\"Wallpaper\", \"org.kde.image\", \"General\");\
512 | d.writeConfig(\"Image\", \"file://%1\");\
513 | d.writeConfig(\"FillMode\", 2);\
514 | d.writeConfig(\"Color\", \"#000\");\
515 | }").arg(QFileInfo(pic).canonicalFilePath()));
516 | }
517 |
518 | QColor KcmColorfulHelper::color_refine(QColor color)
519 | {
520 | double A = 220.0 + (0.137 * (255.0 - color.saturation()));
521 | debug_flag ? qDebug() << A : qDebug();
522 | if (color.value() < A) {
523 | if ((A - color.value()) <= 80) {
524 | color.setHsv(color.hue(), color.saturation(), static_cast(A));
525 | } else if (((A - color.value()) > 80) && ((A - color.value()) <= 130)) {
526 | // qDebug() << (((0.5 + (0.5 * ((color.value() - (A - 130)) / 50))) * (A - color.value())) + color.value());
527 | color.setHsv(color.hue(), color.saturation(), static_cast(((0.5 + (0.5 * ((color.value() - (A - 130)) / 50))) * (A - color.value())) + color.value()));
528 | } else {
529 | color.setHsv(color.hue(), color.saturation(), static_cast(((A - color.value()) / 2) + color.value()));
530 | }
531 | }
532 | return color;
533 | }
534 |
535 | void KcmColorfulHelper::changeThemeOpacity()
536 | {
537 | auto edit_svg = [](QString file_name, double opacity) {
538 | QFile f(file_name);
539 | if (!f.open(QIODevice::ReadWrite | QIODevice::Text))
540 | return;
541 | QString svg_text;
542 | svg_text = f.readAll();
543 | f.resize(0);
544 | QTextStream out(&f);
545 | svg_text.replace(QRegularExpression("([^-]+opacity[:\\s]+)[.0-9]+([^>]+?ColorScheme-ViewHover)"), "\\1" + QString::number(opacity) + "\\2");
546 | out << svg_text;
547 | f.flush();
548 | f.close();
549 | };
550 |
551 | QStringList svg_files;
552 | svg_files = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "plasma/desktoptheme/Colorful/metadata.desktop");
553 | qDebug() << svg_files;
554 |
555 | if (svg_files.length() != 0) {
556 | if (svg_files[0].contains(".local/share")) {
557 | QFileInfo info(svg_files[0]);
558 | edit_svg(info.canonicalPath() + "/dialogs/background.svg", theme_opacity);
559 | edit_svg(info.canonicalPath() + "/widgets/panel-background.svg", theme_opacity);
560 | edit_svg(info.canonicalPath() + "/widgets/tooltip.svg", theme_opacity);
561 | } else {
562 | QDir dir;
563 | QString base_dir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
564 | // qDebug() << base_dir;
565 | if (!QFile::exists(base_dir + "/.local/share/plasma")) {
566 | dir.mkpath(base_dir + "/.local/share/plasma");
567 | }
568 | if (!QFile::exists(base_dir + "/.local/share/plasma/desktoptheme")) {
569 | dir.mkpath(base_dir + "/.local/share/plasma/desktoptheme");
570 | }
571 | QFileInfo info(svg_files[0]);
572 | QProcess::execute("cp \"" + info.canonicalPath() + "\" \"" + base_dir + "/.local/share/plasma/desktoptheme/Colorful\" -rf");
573 | QString new_location = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "plasma/desktoptheme/Colorful/metadata.desktop");
574 | if (new_location.contains(".local/share")) {
575 | QFileInfo new_info(new_location);
576 | edit_svg(new_info.canonicalPath() + "/dialogs/background.svg", theme_opacity);
577 | edit_svg(new_info.canonicalPath() + "/widgets/panel-background.svg", theme_opacity);
578 | edit_svg(new_info.canonicalPath() + "/widgets/tooltip.svg", theme_opacity);
579 | } else {
580 | qDebug() << "Copy theme files failed!";
581 | }
582 | }
583 | }
584 | }
585 |
--------------------------------------------------------------------------------