From e7caa0b8ef29ae700600981a6f759e6272d641c3 Mon Sep 17 00:00:00 2001 From: miruka Date: Fri, 27 Dec 2019 08:19:56 -0400 Subject: [PATCH 1/3] Use a C++ implementation of hsluv --- .gitmodules | 3 +++ harmonyqml.pro | 6 ++++-- requirements.txt | 1 - src/backend/backend.py | 8 -------- src/gui/Utils.qml | 4 +--- src/utils.cpp | 9 +++++++++ src/utils.h | 6 ++++-- submodules/hsluv-c | 1 + 8 files changed, 22 insertions(+), 16 deletions(-) create mode 160000 submodules/hsluv-c diff --git a/.gitmodules b/.gitmodules index 0a9396c4..1ebe1231 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "submodules/RadialBarDemo"] path = submodules/RadialBarDemo url = https://github.com/mirukan/RadialBarDemo/ +[submodule "submodules/hsluv-c"] + path = submodules/hsluv-c + url = https://github.com/hsluv/hsluv-c diff --git a/harmonyqml.pro b/harmonyqml.pro index 4727e347..afd51bae 100644 --- a/harmonyqml.pro +++ b/harmonyqml.pro @@ -13,9 +13,11 @@ QRC_FILE = $$BUILD_DIR/resources.qrc RESOURCES += $$QRC_FILE HEADERS += src/utils.h src/clipboard.h \ - submodules/RadialBarDemo/radialbar.h + submodules/RadialBarDemo/radialbar.h \ + submodules/hsluv-c/src/hsluv.h SOURCES += src/main.cpp src/utils.cpp src/clipboard.cpp \ - submodules/RadialBarDemo/radialbar.cpp + submodules/RadialBarDemo/radialbar.cpp \ + submodules/hsluv-c/src/hsluv.c TARGET = harmonyqml diff --git a/requirements.txt b/requirements.txt index 273cd1ec..64fffe07 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ -hsluv == 0.0.2 Pillow >= 5.4.1, < 6 pymediainfo >= 4.1, < 5 cairosvg >= 2.4.2, < 3 diff --git a/src/backend/backend.py b/src/backend/backend.py index 829667cf..94e81a87 100644 --- a/src/backend/backend.py +++ b/src/backend/backend.py @@ -7,7 +7,6 @@ import traceback from pathlib import Path from typing import Any, DefaultDict, Dict, List, Optional, Tuple -import hsluv from appdirs import AppDirs import nio @@ -245,13 +244,6 @@ class Backend: # General functions - @staticmethod - def hsluv(hue: int, saturation: int, lightness: int) -> List[float]: - """Convert HSLuv (0-360, 0-100, 0-100) to RGB (0-1, 0-1, 0-1) color.""" - - return hsluv.hsluv_to_rgb([hue, saturation, lightness]) - - async def load_settings(self) -> tuple: """Return parsed user config files.""" diff --git a/src/gui/Utils.qml b/src/gui/Utils.qml index 629fb148..14cd543c 100644 --- a/src/gui/Utils.qml +++ b/src/gui/Utils.qml @@ -91,9 +91,7 @@ QtObject { function hsluv(hue, saturation, lightness, alpha=1.0) { - hue = numberWrapAt(hue, 360) - let rgb = py.callSync("hsluv", [hue, saturation, lightness]) - return Qt.rgba(rgb[0], rgb[1], rgb[2], alpha) + return CppUtils.hsluv(hue, saturation, lightness, alpha) } diff --git a/src/utils.cpp b/src/utils.cpp index 1ecef39d..ceb5aec6 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -2,10 +2,12 @@ // Function implementations of the Utils class, see the utils.h file. +#include #include #include #include "utils.h" +#include "../submodules/hsluv-c/src/hsluv.h" Utils::Utils() { @@ -23,3 +25,10 @@ QString Utils::formattedBytes(qint64 bytes, int precision) { QString Utils::uuid() { return QUuid::createUuid().toString(QUuid::WithoutBraces); } + + +QColor Utils::hsluv(qreal hue, qreal saturation, qreal luv, qreal alpha) { + double red, green, blue; + hsluv2rgb(hue, saturation, luv, &red, &green, &blue); + return QColor::fromRgbF(red, green, blue, alpha); +} diff --git a/src/utils.h b/src/utils.h index 9c6cbb94..95750957 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,13 +1,14 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // The Utils class exposes various useful functions for QML that aren't -// normally provided by Qt. +// provided by the `Qt` object. #ifndef UTILS_H #define UTILS_H -#include +#include #include +#include class Utils : public QObject { @@ -20,6 +21,7 @@ public: public slots: QString formattedBytes(qint64 bytes, int precision = 2); QString uuid(); + QColor hsluv(qreal hue, qreal saturation, qreal luv, qreal alpha = 1.0); private: QLocale m_locale; diff --git a/submodules/hsluv-c b/submodules/hsluv-c new file mode 160000 index 00000000..9e9be32d --- /dev/null +++ b/submodules/hsluv-c @@ -0,0 +1 @@ +Subproject commit 9e9be32d6010cad484a7b12b1a3d19c6cf4c1353 From f34d2a1c6d54639e1ad9205d8250996c08a99abf Mon Sep 17 00:00:00 2001 From: miruka Date: Fri, 27 Dec 2019 08:58:24 -0400 Subject: [PATCH 2/3] Turn CppUtils into a Singleton --- src/gui/Pages/Chat/FileTransfer/Transfer.qml | 1 + src/gui/Pages/Chat/Timeline/EventFile.qml | 1 + src/gui/PythonBridge/PythonBridge.qml | 1 + src/gui/Utils.qml | 1 + src/main.cpp | 12 +++++++++++- 5 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/gui/Pages/Chat/FileTransfer/Transfer.qml b/src/gui/Pages/Chat/FileTransfer/Transfer.qml index cbe3e960..9cd64e02 100644 --- a/src/gui/Pages/Chat/FileTransfer/Transfer.qml +++ b/src/gui/Pages/Chat/FileTransfer/Transfer.qml @@ -2,6 +2,7 @@ import QtQuick 2.12 import QtQuick.Layouts 1.12 +import CppUtils 0.1 import "../../../Base" HColumnLayout { diff --git a/src/gui/Pages/Chat/Timeline/EventFile.qml b/src/gui/Pages/Chat/Timeline/EventFile.qml index 4267deb7..3015dd58 100644 --- a/src/gui/Pages/Chat/Timeline/EventFile.qml +++ b/src/gui/Pages/Chat/Timeline/EventFile.qml @@ -2,6 +2,7 @@ import QtQuick 2.12 import QtQuick.Layouts 1.12 +import CppUtils 0.1 import "../../../Base" HTile { diff --git a/src/gui/PythonBridge/PythonBridge.qml b/src/gui/PythonBridge/PythonBridge.qml index 14f72571..565d28bd 100644 --- a/src/gui/PythonBridge/PythonBridge.qml +++ b/src/gui/PythonBridge/PythonBridge.qml @@ -2,6 +2,7 @@ import QtQuick 2.12 import io.thp.pyotherside 1.5 +import CppUtils 0.1 Python { id: py diff --git a/src/gui/Utils.qml b/src/gui/Utils.qml index 14cd543c..1750ed7f 100644 --- a/src/gui/Utils.qml +++ b/src/gui/Utils.qml @@ -1,6 +1,7 @@ // SPDX-License-Identifier: LGPL-3.0-or-later import QtQuick 2.12 +import CppUtils 0.1 QtObject { function makeObject(urlComponent, parent=null, properties={}, diff --git a/src/main.cpp b/src/main.cpp index a3f19573..66ca27f5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,9 +39,19 @@ int main(int argc, char *argv[]) { // Add our custom non-visual `QObject `s as properties. // Their attributes and methods will be accessing like normal QML objects. - objectContext->setContextProperty("CppUtils", new Utils()); + /* objectContext->setContextProperty("CppUtils", new Utils()); */ objectContext->setContextProperty("Clipboard", new Clipboard()); + + qmlRegisterSingletonType( + "CppUtils", 0, 1, "CppUtils", + [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * { + Q_UNUSED(engine) + Q_UNUSED(scriptEngine) + return new Utils(); + } + ); + // Register our custom visual items that will be importable from QML, // e.g. `import RadialBar 1.0` qmlRegisterType("RadialBar", 1, 0, "RadialBar"); From a1256cf20a0832bbc9ca86f1cc50f7553626ad88 Mon Sep 17 00:00:00 2001 From: miruka Date: Fri, 27 Dec 2019 09:06:42 -0400 Subject: [PATCH 3/3] Turn Clipboard into a singleton --- src/gui/Base/HSelectableLabelContainer.qml | 1 + src/gui/GlobalShortcuts.qml | 1 + src/gui/MainPane/AccountDelegate.qml | 1 + src/gui/MainPane/RoomDelegate.qml | 1 + src/gui/Pages/Chat/Composer.qml | 1 + .../Pages/Chat/RoomPane/MemberDelegate.qml | 1 + src/gui/Pages/Chat/Timeline/EventDelegate.qml | 1 + src/main.cpp | 24 +++++++++++++------ 8 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/gui/Base/HSelectableLabelContainer.qml b/src/gui/Base/HSelectableLabelContainer.qml index 3f45bd3c..82e481d9 100644 --- a/src/gui/Base/HSelectableLabelContainer.qml +++ b/src/gui/Base/HSelectableLabelContainer.qml @@ -1,6 +1,7 @@ // SPDX-License-Identifier: LGPL-3.0-or-later import QtQuick 2.12 +import Clipboard 0.1 FocusScope { signal deselectAll() diff --git a/src/gui/GlobalShortcuts.qml b/src/gui/GlobalShortcuts.qml index 02960126..ca7e525c 100644 --- a/src/gui/GlobalShortcuts.qml +++ b/src/gui/GlobalShortcuts.qml @@ -2,6 +2,7 @@ import QtQuick 2.12 import QtQuick.Controls 2.12 +import Clipboard 0.1 import "Base" Item { diff --git a/src/gui/MainPane/AccountDelegate.qml b/src/gui/MainPane/AccountDelegate.qml index afe8a43b..409135e5 100644 --- a/src/gui/MainPane/AccountDelegate.qml +++ b/src/gui/MainPane/AccountDelegate.qml @@ -2,6 +2,7 @@ import QtQuick 2.12 import QtQuick.Layouts 1.12 +import Clipboard 0.1 import "../Base" HTileDelegate { diff --git a/src/gui/MainPane/RoomDelegate.qml b/src/gui/MainPane/RoomDelegate.qml index 0fa9d659..3899485c 100644 --- a/src/gui/MainPane/RoomDelegate.qml +++ b/src/gui/MainPane/RoomDelegate.qml @@ -2,6 +2,7 @@ import QtQuick 2.12 import QtQuick.Layouts 1.12 +import Clipboard 0.1 import "../Base" HTileDelegate { diff --git a/src/gui/Pages/Chat/Composer.qml b/src/gui/Pages/Chat/Composer.qml index 761694a7..b2979a78 100644 --- a/src/gui/Pages/Chat/Composer.qml +++ b/src/gui/Pages/Chat/Composer.qml @@ -2,6 +2,7 @@ import QtQuick 2.12 import QtQuick.Layouts 1.12 +import Clipboard 0.1 import "../../Base" import "../../Dialogs" diff --git a/src/gui/Pages/Chat/RoomPane/MemberDelegate.qml b/src/gui/Pages/Chat/RoomPane/MemberDelegate.qml index 405e3122..6b9d93fd 100644 --- a/src/gui/Pages/Chat/RoomPane/MemberDelegate.qml +++ b/src/gui/Pages/Chat/RoomPane/MemberDelegate.qml @@ -1,6 +1,7 @@ // SPDX-License-Identifier: LGPL-3.0-or-later import QtQuick 2.12 +import Clipboard 0.1 import "../../../Base" HTileDelegate { diff --git a/src/gui/Pages/Chat/Timeline/EventDelegate.qml b/src/gui/Pages/Chat/Timeline/EventDelegate.qml index 833c2501..dba68ec4 100644 --- a/src/gui/Pages/Chat/Timeline/EventDelegate.qml +++ b/src/gui/Pages/Chat/Timeline/EventDelegate.qml @@ -2,6 +2,7 @@ import QtQuick 2.12 import QtQuick.Layouts 1.12 +import Clipboard 0.1 import "../../../Base" HColumnLayout { diff --git a/src/main.cpp b/src/main.cpp index 66ca27f5..12004440 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -37,11 +37,19 @@ int main(int argc, char *argv[]) { objectContext->setContextProperty("debugMode", false); #endif - // Add our custom non-visual `QObject `s as properties. - // Their attributes and methods will be accessing like normal QML objects. - /* objectContext->setContextProperty("CppUtils", new Utils()); */ - objectContext->setContextProperty("Clipboard", new Clipboard()); - + // Register our custom non-visual QObject singletons, + // that will be importable anywhere in QML. Example: + // import Clipboard 0.1 + // ... + // Component.onCompleted: print(Clipboard.text) + qmlRegisterSingletonType( + "Clipboard", 0, 1, "Clipboard", + [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * { + Q_UNUSED(engine) + Q_UNUSED(scriptEngine) + return new Clipboard(); + } + ); qmlRegisterSingletonType( "CppUtils", 0, 1, "CppUtils", @@ -52,8 +60,10 @@ int main(int argc, char *argv[]) { } ); - // Register our custom visual items that will be importable from QML, - // e.g. `import RadialBar 1.0` + // Register our custom visual items that will be importable from QML, e.g. + // import RadialBar 1.0 + // ... + // RadialBar { ... } qmlRegisterType("RadialBar", 1, 0, "RadialBar"); // Create the QML root component by loading its file from the Qt Resource