diff --git a/CMake b/CMake index 1f7811c..ca5cd26 160000 --- a/CMake +++ b/CMake @@ -1 +1 @@ -Subproject commit 1f7811cfb9bf9fa8de4fcbd26f356cf5df07ef36 +Subproject commit ca5cd26e5b765d8fb2a0f5bddec72dcc247ce036 diff --git a/CMakeLists.txt b/CMakeLists.txt index 211efa7..685b368 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2018-2025 QuasarApp. +# Copyright (C) 2018-2026 QuasarApp. # Distributed under the lgplv3 software license, see the accompanying # Everyone is permitted to copy and distribute verbatim copies # of this license document, but changing it is not allowed. @@ -31,6 +31,8 @@ qt_standard_project_setup() qt_policy(SET QTP0001 NEW) qt_policy(SET QTP0004 NEW) + + add_subdirectory(ViewSolutions) if (VIEWSOLUTIONS_EXAMPLES ) diff --git a/ViewSolutions/CMakeLists.txt b/ViewSolutions/CMakeLists.txt index 6b52190..390b722 100644 --- a/ViewSolutions/CMakeLists.txt +++ b/ViewSolutions/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2018-2025 QuasarApp. +# Copyright (C) 2018-2026 QuasarApp. # Distributed under the lgplv3 software license, see the accompanying # Everyone is permitted to copy and distribute verbatim copies # of this license document, but changing it is not allowed. @@ -21,6 +21,14 @@ file(GLOB SOURCE_CPP ) +file(GLOB SHADERS_CPP + RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" + + "shaders/*.frag" + "shaders/*.vert" + +) + file(GLOB_RECURSE SOURCE_ASSETS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "assets/*" @@ -34,6 +42,13 @@ file(GLOB_RECURSE MODULE_QML_FILES qt_add_library(${CURRENT_PROJECT} ${SOURCE_CPP}) +# available under qrc:/uieffects/shaders/shaderName.frag.qsb +qt6_add_shaders(${CURRENT_PROJECT} "uieffects" + PREFIX + "/uieffects" + FILES + ${SHADERS_CPP} +) qt_add_qml_module(${CURRENT_PROJECT} URI ViewSolutions diff --git a/ViewSolutions/ViewSolutions/ActivityPage.qml b/ViewSolutions/ViewSolutions/ActivityPage.qml index 225b465..d122f30 100644 --- a/ViewSolutions/ViewSolutions/ActivityPage.qml +++ b/ViewSolutions/ViewSolutions/ActivityPage.qml @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/ViewSolutions/ActivityProcessor.qml b/ViewSolutions/ViewSolutions/ActivityProcessor.qml index 8630fa6..0d2ce56 100644 --- a/ViewSolutions/ViewSolutions/ActivityProcessor.qml +++ b/ViewSolutions/ViewSolutions/ActivityProcessor.qml @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. @@ -203,7 +203,7 @@ Page { } else if (component.status === Component.Error) { // Error Handling - console.log("Error loading component:", component.errorString()); + console.error("Error loading component:", component.errorString()); } } @@ -237,7 +237,7 @@ Page { } else if (component.status === Component.Error) { // Error Handling - console.log("Error loading component:", component.errorString()); + console.error("Error loading component:", component.errorString()); } } diff --git a/ViewSolutions/ViewSolutions/ActivityProcessorHeader.qml b/ViewSolutions/ViewSolutions/ActivityProcessorHeader.qml index c7b3aca..a32be45 100644 --- a/ViewSolutions/ViewSolutions/ActivityProcessorHeader.qml +++ b/ViewSolutions/ViewSolutions/ActivityProcessorHeader.qml @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/ViewSolutions/BasePopUp.qml b/ViewSolutions/ViewSolutions/BasePopUp.qml index 8e4c950..be8dc16 100644 --- a/ViewSolutions/ViewSolutions/BasePopUp.qml +++ b/ViewSolutions/ViewSolutions/BasePopUp.qml @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2024 QuasarApp. + * Copyright (C) 2018-2026 QuasarApp. * Distributed under the GPLv3 software license, see the accompanying * Everyone is permitted to copy and distribute verbatim copies * of this license document, but changing it is not allowed. diff --git a/ViewSolutions/ViewSolutions/DragDelegate.qml b/ViewSolutions/ViewSolutions/DragDelegate.qml index 062b14d..c6fa6f0 100644 --- a/ViewSolutions/ViewSolutions/DragDelegate.qml +++ b/ViewSolutions/ViewSolutions/DragDelegate.qml @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2025-2025 QuasarApp. +//# Copyright (C) 2025-2026 QuasarApp. //# Distributed under the lgplv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/ViewSolutions/Extendable.qml b/ViewSolutions/ViewSolutions/Extendable.qml new file mode 100644 index 0000000..342358c --- /dev/null +++ b/ViewSolutions/ViewSolutions/Extendable.qml @@ -0,0 +1,83 @@ +//# +//# Copyright (C) 2025-2026 QuasarApp. +//# Distributed under the GPLv3 software license, see the accompanying +//# Everyone is permitted to copy and distribute verbatim copies +//# of this license document, but changing it is not allowed. +//# + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Control { + + id: root + + property alias extendableWidget: extendetArea.contentItem + property alias mainWidget: mainButton.contentItem + // see GridLayout + property alias layoutDirection: columnLayout.layoutDirection + property alias flow: columnLayout.flow + + property alias extended: extendetArea.visible + property int animationDuration: 600 + + contentItem: GridLayout { + id: columnLayout + columnSpacing: 0 + rowSpacing: 0 + + Control { + Layout.alignment: Qt.AlignCenter + Layout.maximumWidth: root.implicitWidth - root.rightPadding - root.leftPadding + padding: 0 + id: mainButton + + + Behavior on implicitHeight { + enabled: root.flow !== GridLayout.LeftToRight + + NumberAnimation { + easing.type: Easing.OutExpo + duration: root.animationDuration + } + } + + Behavior on implicitWidth { + enabled: root.flow === GridLayout.LeftToRight + NumberAnimation { + easing.type: Easing.OutExpo + duration: root.animationDuration + } + } + } + + + Control { + id: extendetArea + clip: true + visible: false + padding: 0 + Layout.alignment: Qt.AlignCenter + Layout.maximumWidth: root.implicitWidth - root.rightPadding - root.leftPadding + + Behavior on implicitHeight { + enabled: root.flow !== GridLayout.LeftToRight + + NumberAnimation { + easing.type: Easing.OutExpo + duration: root.animationDuration + } + } + + Behavior on implicitWidth { + enabled: root.flow === GridLayout.LeftToRight + NumberAnimation { + easing.type: Easing.OutExpo + duration: root.animationDuration + } + } + + } + } +} diff --git a/ViewSolutions/ViewSolutions/FadeEffect.qml b/ViewSolutions/ViewSolutions/FadeEffect.qml new file mode 100644 index 0000000..2a2f1b3 --- /dev/null +++ b/ViewSolutions/ViewSolutions/FadeEffect.qml @@ -0,0 +1,23 @@ +//# +//# Copyright (C) 2025-2026 QuasarApp. +//# Distributed under the GPLv3 software license, see the accompanying +//# Everyone is permitted to copy and distribute verbatim copies +//# of this license document, but changing it is not allowed. +//# + + +import QtQuick + +// this effect make fade effect for left and right side of the item +// +ShaderEffect { + property real leftFadePx: 25; + property real rightFadePx: 25; + property real leftFadePaddingPx: 2; + property real rightFadePaddingPx: 2; + + required property real widthSource; + + fragmentShader: "qrc:/uieffects/shaders/fade.frag.qsb" + vertexShader: "qrc:/uieffects/shaders/fade.vert.qsb" +} diff --git a/ViewSolutions/ViewSolutions/FlickablePane.qml b/ViewSolutions/ViewSolutions/FlickablePane.qml index e465ab4..89a13e8 100644 --- a/ViewSolutions/ViewSolutions/FlickablePane.qml +++ b/ViewSolutions/ViewSolutions/FlickablePane.qml @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2025-2025 QuasarApp. +//# Copyright (C) 2025-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/ViewSolutions/IconOverlay.qml b/ViewSolutions/ViewSolutions/IconOverlay.qml index 75f8a2c..989d766 100644 --- a/ViewSolutions/ViewSolutions/IconOverlay.qml +++ b/ViewSolutions/ViewSolutions/IconOverlay.qml @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2025-2025 QuasarApp. +//# Copyright (C) 2025-2026 QuasarApp. //# Distributed under the lgplv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/ViewSolutions/ImageView.qml b/ViewSolutions/ViewSolutions/ImageView.qml index 0c01aec..f16b046 100644 --- a/ViewSolutions/ViewSolutions/ImageView.qml +++ b/ViewSolutions/ViewSolutions/ImageView.qml @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. @@ -16,6 +16,7 @@ AbstractButton { id: root property string source: "" property alias imagesource: sourceImg + property alias imagEffect: imgEffect property int radius: 16 property real power: 1.0 @@ -28,6 +29,8 @@ AbstractButton { property color selectedColor: Material.accent property color hoverColor: Material.accent property alias contentData: content.contentItem + property alias contentPadding: content.padding + Connections { target: sourceImg @@ -121,6 +124,8 @@ AbstractButton { source: Image { id: sourceImg source: root.source + mipmap: false + sourceSize: Qt.size(imgEffect.width, imgEffect.height) clip: true fillMode: Image.PreserveAspectCrop @@ -197,7 +202,8 @@ AbstractButton { MouseArea { acceptedButtons: Qt.NoButton - hoverEnabled: true; + hoverEnabled: root.power > 0; + enabled: root.power > 0; onExited: { privateData.ry = 0 diff --git a/ViewSolutions/ViewSolutions/Metrix.qml b/ViewSolutions/ViewSolutions/Metrix.qml deleted file mode 100644 index b3d2adc..0000000 --- a/ViewSolutions/ViewSolutions/Metrix.qml +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2018-2024 QuasarApp. - * Distributed under the GPLv3 software license, see the accompanying - * Everyone is permitted to copy and distribute verbatim copies - * of this license document, but changing it is not allowed. -*/ - -import QtQuick -import QtQuick.Window -import QtQuick.Controls.Material -import QtQuick.Controls - -Item { - readonly property int pointCount: 100; - readonly property real mm: Screen.pixelDensity - readonly property real sm: 10 * mm - readonly property real dsm: Math.sqrt(Math.pow(Screen.desktopAvailableWidth, 2) + Math.pow(Screen.desktopAvailableHeight, 2)) / sm - readonly property real pt: getfactor(dsm) * sm - readonly property real controlPtMaterial: Material.buttonHeight - readonly property real gamePt: (width < height) ? width / pointCount : height / pointCount; - - function getfactor(dsm) { - if ( dsm < 70) { - return 1 - } else if (dsm < 140) { - return 2; - } else - return 4; - } - - anchors.fill: parent; -} diff --git a/ViewSolutions/ViewSolutions/NotificationForm.qml b/ViewSolutions/ViewSolutions/NotificationForm.qml index 26f60b9..e132579 100644 --- a/ViewSolutions/ViewSolutions/NotificationForm.qml +++ b/ViewSolutions/ViewSolutions/NotificationForm.qml @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2024 QuasarApp. + * Copyright (C) 2018-2026 QuasarApp. * Distributed under the GPLv3 software license, see the accompanying * Everyone is permitted to copy and distribute verbatim copies * of this license document, but changing it is not allowed. diff --git a/ViewSolutions/ViewSolutions/NotificationServiceView.qml b/ViewSolutions/ViewSolutions/NotificationServiceView.qml index 1fc37a4..2aac1f0 100644 --- a/ViewSolutions/ViewSolutions/NotificationServiceView.qml +++ b/ViewSolutions/ViewSolutions/NotificationServiceView.qml @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2024 QuasarApp. + * Copyright (C) 2018-2026 QuasarApp. * Distributed under the GPLv3 software license, see the accompanying * Everyone is permitted to copy and distribute verbatim copies * of this license document, but changing it is not allowed. @@ -18,45 +18,41 @@ Item { readonly property var history: model.history - Metrix { - id: metrix - } - NotificationForm { id: notyfyView - titleText : msg.title(); - text: (msg)? msg.text(): ""; - img: (msg && msg.img().length)? msg.img(): getDefaultImage((msg)? msg.type(): 0); - type: (msg)? msg.type(): 0; + titleText : root.msg.title(); + text: (root.msg)? root.msg.text(): ""; + img: (root.msg && root.msg.img().length)? root.msg.img(): getDefaultImage((root.msg)? root.msg.type(): 0); + type: (root.msg)? root.msg.type(): 0; x: parent.width - width - margin; y: margin; - width: Math.min(6 * metrix.pt, root.width); + width: Math.min(440, root.width); } YesNoQuestion { id: questionMsgBox - titleText : qst.title(); - text: (qst)? qst.text(): ""; - img: (qst && qst.img().length)? qst.img(): defImg; + titleText : root.qst.title(); + text: (root.qst)? root.qst.text(): ""; + img: (root.qst && root.qst.img().length)? root.qst.img(): defImg; type: 0; x: parent.width / 2 - width / 2; y: parent.height / 2 - height / 2; - width: Math.min(6 * metrix.pt, root.width); + width: Math.min(440, root.width); onAccepted: { - if (model) { - model.questionComplete(true, qst.type()) + if (root.model) { + root.model.questionComplete(true, root.qst.type()) } } onRejected: { - if (model) { - model.questionComplete(false, qst.type()) + if (root.model) { + root.model.questionComplete(false, root.qst.type()) } } } @@ -83,7 +79,7 @@ Item { } Connections { - target: model + target: root.model function onSigShowHistory() { history.open() } diff --git a/ViewSolutions/ViewSolutions/SlideShow.qml b/ViewSolutions/ViewSolutions/SlideShow.qml index 2ced886..ebd1dd2 100644 --- a/ViewSolutions/ViewSolutions/SlideShow.qml +++ b/ViewSolutions/ViewSolutions/SlideShow.qml @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2025-2025 QuasarApp. +//# Copyright (C) 2025-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/ViewSolutions/StackText.qml b/ViewSolutions/ViewSolutions/StackText.qml new file mode 100644 index 0000000..ce300f8 --- /dev/null +++ b/ViewSolutions/ViewSolutions/StackText.qml @@ -0,0 +1,88 @@ +//# +//# Copyright (C) 2025-2026 QuasarApp. +//# Distributed under the GPLv3 software license, see the accompanying +//# Everyone is permitted to copy and distribute verbatim copies +//# of this license document, but changing it is not allowed. +//# + +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import ViewSolutions +import QtQuick.Effects + +Control { + id: root + padding: 24 + + required property var guiTokens + property alias text: model.fullText; + property alias delimiter: model.delimiter + property alias delegate: contentList.delegate + readonly property bool isFinished: contentList.currentIndex >= contentList.count - 1 + + function next() { + if (nextButton.visible) { + nextButton.click() + } + } + + contentItem: ColumnLayout { + ListView { + id: contentList + currentIndex: 0 + interactive: false + // snapMode: ListView.SnapOneItem + boundsBehavior:Flickable.StopAtBounds + Layout.fillWidth: true + Layout.fillHeight: true + + model: StackTextModel { + id: model; + + onFullTextChanged: { + contentList.currentIndex = 0; + } + } + } + + ToolButton { + Layout.alignment: Qt.AlignHCenter + + + id: nextButton + text: qsTr("Next") + visible: contentList.count > 1 && contentList.currentIndex < contentList.count - 1 + opacity: visible + + Behavior on opacity { + NumberAnimation { + easing.type: Easing.InOutQuad + duration: 300 + } + } + + font: root.font + + onClicked: { + if (contentList.currentIndex + 1 >= contentList.count) { + contentList.currentIndex = 0; + return; + } + contentList.currentIndex = contentList.currentIndex + 1; + } + + layer.enabled: true + layer.effect: MultiEffect { + shadowBlur: 1.0 + shadowEnabled: true + shadowColor: root.guiTokens.color_accent_primary + shadowScale: 1.0 + } + + } + } + +} diff --git a/ViewSolutions/ViewSolutions/ViewPortDelegatBase.qml b/ViewSolutions/ViewSolutions/ViewPortDelegatBase.qml index 50a9ddf..94a2482 100644 --- a/ViewSolutions/ViewSolutions/ViewPortDelegatBase.qml +++ b/ViewSolutions/ViewSolutions/ViewPortDelegatBase.qml @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/ViewSolutions/ViewPortGradientPage.qml b/ViewSolutions/ViewSolutions/ViewPortGradientPage.qml index 7e11a0b..bcad04b 100644 --- a/ViewSolutions/ViewSolutions/ViewPortGradientPage.qml +++ b/ViewSolutions/ViewSolutions/ViewPortGradientPage.qml @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/ViewSolutions/ViewPortPage.qml b/ViewSolutions/ViewSolutions/ViewPortPage.qml index ed33051..0fb27e2 100644 --- a/ViewSolutions/ViewSolutions/ViewPortPage.qml +++ b/ViewSolutions/ViewSolutions/ViewPortPage.qml @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/ViewSolutions/ViewPortStaticGradientPage.qml b/ViewSolutions/ViewSolutions/ViewPortStaticGradientPage.qml index 9856f04..cd321e4 100644 --- a/ViewSolutions/ViewSolutions/ViewPortStaticGradientPage.qml +++ b/ViewSolutions/ViewSolutions/ViewPortStaticGradientPage.qml @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/ViewSolutions/ViewPortStaticPage.qml b/ViewSolutions/ViewSolutions/ViewPortStaticPage.qml index 919e077..689a707 100644 --- a/ViewSolutions/ViewSolutions/ViewPortStaticPage.qml +++ b/ViewSolutions/ViewSolutions/ViewPortStaticPage.qml @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/ViewSolutions/ViewSolutionsControl.qml b/ViewSolutions/ViewSolutions/ViewSolutionsControl.qml index 0cc0080..89d12ef 100644 --- a/ViewSolutions/ViewSolutions/ViewSolutionsControl.qml +++ b/ViewSolutions/ViewSolutions/ViewSolutionsControl.qml @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/ViewSolutions/YesNoQuestion.qml b/ViewSolutions/ViewSolutions/YesNoQuestion.qml index 2439bed..36fe76c 100644 --- a/ViewSolutions/ViewSolutions/YesNoQuestion.qml +++ b/ViewSolutions/ViewSolutions/YesNoQuestion.qml @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2024 QuasarApp. + * Copyright (C) 2018-2026 QuasarApp. * Distributed under the GPLv3 software license, see the accompanying * Everyone is permitted to copy and distribute verbatim copies * of this license document, but changing it is not allowed. diff --git a/ViewSolutions/shaders/fade.frag b/ViewSolutions/shaders/fade.frag new file mode 100644 index 0000000..d913d8f --- /dev/null +++ b/ViewSolutions/shaders/fade.frag @@ -0,0 +1,28 @@ +#version 440 +layout(location = 0) in vec2 coord; +layout(location = 0) out vec4 fragColor; +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + + float leftFadePx; + float rightFadePx; + + float leftFadePaddingPx; + float rightFadePaddingPx; + + float widthSource; +}; +layout(binding = 1) uniform sampler2D source; + +void main() { + vec4 tex = texture(source, coord); + + float leftFade = max(0.0, min(1.0, (widthSource * coord.x - leftFadePaddingPx) / leftFadePx)); + + float rightFade = max(0.0, min(1.0, (widthSource * (1 - coord.x) - rightFadePaddingPx) / rightFadePx)); + + float alpha = leftFade * rightFade; + + fragColor = tex * alpha * qt_Opacity ; +} diff --git a/ViewSolutions/shaders/fade.vert b/ViewSolutions/shaders/fade.vert new file mode 100644 index 0000000..9e9ae3f --- /dev/null +++ b/ViewSolutions/shaders/fade.vert @@ -0,0 +1,14 @@ +#version 440 +layout(location = 0) in vec4 qt_Vertex; +layout(location = 1) in vec2 qt_MultiTexCoord0; +layout(location = 0) out vec2 coord; +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; +}; + + +void main() { + coord = qt_MultiTexCoord0; + gl_Position = qt_Matrix * qt_Vertex; +} diff --git a/ViewSolutions/src/avatargenerator.cpp b/ViewSolutions/src/avatargenerator.cpp index 21c8680..07e78ee 100644 --- a/ViewSolutions/src/avatargenerator.cpp +++ b/ViewSolutions/src/avatargenerator.cpp @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2025-2025 QuasarApp. +//# Copyright (C) 2025-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/src/avatargenerator.h b/ViewSolutions/src/avatargenerator.h index 846fbc7..1af6875 100644 --- a/ViewSolutions/src/avatargenerator.h +++ b/ViewSolutions/src/avatargenerator.h @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2025-2025 QuasarApp. +//# Copyright (C) 2025-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/src/basehashmodel.h b/ViewSolutions/src/basehashmodel.h index 9f7cdd8..79bd6e6 100644 --- a/ViewSolutions/src/basehashmodel.h +++ b/ViewSolutions/src/basehashmodel.h @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. @@ -43,11 +43,12 @@ class BaseHashModel: public QAbstractListModel { public: + BaseHashModel(QObject* parent = nullptr): QAbstractListModel(parent) { } - int rowCount(const QModelIndex &parent) const override { + int rowCount(const QModelIndex &) const override { return m_data.size(); } @@ -114,6 +115,10 @@ class BaseHashModel: public QAbstractListModel return {}; } + DATA get(const KEY& key) { + return m_data.value(key); + } + const QHash& dateList() const { return m_data; } diff --git a/ViewSolutions/src/baselistmodel.h b/ViewSolutions/src/baselistmodel.h index 9ea68af..b16b519 100644 --- a/ViewSolutions/src/baselistmodel.h +++ b/ViewSolutions/src/baselistmodel.h @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/src/colorpicker.cpp b/ViewSolutions/src/colorpicker.cpp index cf61f75..b099d0b 100644 --- a/ViewSolutions/src/colorpicker.cpp +++ b/ViewSolutions/src/colorpicker.cpp @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. @@ -20,7 +20,7 @@ QColor ColorPicker::pick(int x, int y, const QImage &img) const { return img.pixelColor(x, y); } -QColor ColorPicker::pick(const QImage &img, int density) const { +QColor ColorPicker::pick(const QImage &img, int density, bool alpha) const { int stepX = img.width() / density; int stepY = img.height() / density; @@ -33,33 +33,54 @@ QColor ColorPicker::pick(const QImage &img, int density) const { G = 0, B = 0; + int count = 0; + for (int x = stepX - 1; x < img.width(); x += stepX) { for (int y = stepY - 1; y < img.height(); y += stepY) { int pixel = img.pixel(x, y); - A += (pixel & 0xFF000000) >> 24; - R += (pixel & 0x00FF0000) >> 16; - G += (pixel & 0x0000FF00) >> 8; - B += pixel & 0x000000FF; + int Atmp = (pixel & 0xFF000000) >> 24; + + if (Atmp > 0) { + A += Atmp; + + R += (pixel & 0x00FF0000) >> 16; + G += (pixel & 0x0000FF00) >> 8; + B += pixel & 0x000000FF; + + count++; + } + + } } - int count = density * density; + if (count <= 0) { + return QColor::fromRgb(0); + } + + if (!alpha) { + return QColor::fromRgba((255 << 24) | + ((R / count) << 16) | + ((G / count) << 8) | + B / count); + } + return QColor::fromRgba(((A / count) << 24) | ((R / count) << 16) | ((G / count) << 8) | B / count); } -QColor ColorPicker::pick(const QString &img) const { +QColor ColorPicker::pick(const QString &img, bool alpha) const { if (img.left(3).compare("qrc") == 0) { - return pick(QImage(img.right(img.size() - 3))); + return pick(QImage(img.right(img.size() - 3)), 5, alpha); } if (img.left(5).compare("file:") == 0) { - return pick(QImage(img.right(img.size() - 5))); + return pick(QImage(img.right(img.size() - 5)), 5, alpha); } - return pick(QImage(img)); + return pick(QImage(img), 5, alpha); } } diff --git a/ViewSolutions/src/colorpicker.h b/ViewSolutions/src/colorpicker.h index cc05f2e..cd58f6f 100644 --- a/ViewSolutions/src/colorpicker.h +++ b/ViewSolutions/src/colorpicker.h @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. @@ -36,14 +36,14 @@ class VIEWSOLUTION_EXPORT ColorPicker * @param density Count of checked pixels on one plane and planes count, default 5. * @return General color of image. */ - QColor pick(const QImage &img, int density = 5) const; + QColor pick(const QImage &img, int density = 5, bool alpha = true) const; /** * @brief pick This is override function for qml. * @param img Path to image. * @return General color of image. */ - QColor pick(const QString &img) const; + QColor pick(const QString &img, bool alpha = true) const; }; } diff --git a/ViewSolutions/src/historynotificationsmodel.cpp b/ViewSolutions/src/historynotificationsmodel.cpp index 4718007..a799c26 100644 --- a/ViewSolutions/src/historynotificationsmodel.cpp +++ b/ViewSolutions/src/historynotificationsmodel.cpp @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. @@ -23,15 +23,23 @@ QVariant HistoryNotificationsModel::data(const QModelIndex &index, int role) con if(index.row() < 0 || index.row() >= notificationsList.count()) return QVariant(); + auto& value = notificationsList.at(index.row()); + switch (role) { case Icon: - return notificationsList.at(index.row()).img(); + return value.img(); case Title: - return notificationsList.at(index.row()).title(); + return value.title(); case Message: - return notificationsList.at(index.row()).text(); + return value.text(); case Type: - return notificationsList.at(index.row()).type(); + return value.type(); + case Time: + return value.getTime(); + case FilterHuck0: + return value.filterHuck0(); + case FilterHuck1: + return value.filterHuck1(); default: break; } @@ -44,6 +52,10 @@ QHash HistoryNotificationsModel::roleNames() const { roles[Title] = "title"; roles[Message] = "text"; roles[Type] = "type"; + roles[Time] = "msgTime"; + roles[FilterHuck0] = "filterHuck0"; + roles[FilterHuck1] = "filterHuck1"; + return roles; } diff --git a/ViewSolutions/src/historynotificationsmodel.h b/ViewSolutions/src/historynotificationsmodel.h index 12315a8..b104488 100644 --- a/ViewSolutions/src/historynotificationsmodel.h +++ b/ViewSolutions/src/historynotificationsmodel.h @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. @@ -20,7 +20,10 @@ class VIEWSOLUTION_EXPORT HistoryNotificationsModel : public QAbstractListModel Icon = Qt::UserRole + 1, Title, Message, - Type + Type, + Time, + FilterHuck0, + FilterHuck1 }; public: diff --git a/ViewSolutions/src/iguitokensmodel.cpp b/ViewSolutions/src/iguitokensmodel.cpp index 2f8cbd6..eed19d4 100644 --- a/ViewSolutions/src/iguitokensmodel.cpp +++ b/ViewSolutions/src/iguitokensmodel.cpp @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2024-2025 QuasarApp. +//# Copyright (C) 2024-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/src/iguitokensmodel.h b/ViewSolutions/src/iguitokensmodel.h index d7da1b5..b8cc061 100644 --- a/ViewSolutions/src/iguitokensmodel.h +++ b/ViewSolutions/src/iguitokensmodel.h @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2024-2025 QuasarApp. +//# Copyright (C) 2024-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/src/imodel.cpp b/ViewSolutions/src/imodel.cpp index da45be7..3c506b2 100644 --- a/ViewSolutions/src/imodel.cpp +++ b/ViewSolutions/src/imodel.cpp @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/src/imodel.h b/ViewSolutions/src/imodel.h index 92b1a7c..c4710c9 100644 --- a/ViewSolutions/src/imodel.h +++ b/ViewSolutions/src/imodel.h @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/src/listviewmodel.cpp b/ViewSolutions/src/listviewmodel.cpp index e4cfbf5..26c3195 100644 --- a/ViewSolutions/src/listviewmodel.cpp +++ b/ViewSolutions/src/listviewmodel.cpp @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/src/listviewmodel.h b/ViewSolutions/src/listviewmodel.h index e5653b6..6e88bdd 100644 --- a/ViewSolutions/src/listviewmodel.h +++ b/ViewSolutions/src/listviewmodel.h @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/src/modelstorage.cpp b/ViewSolutions/src/modelstorage.cpp index 8f3e95a..6059790 100644 --- a/ViewSolutions/src/modelstorage.cpp +++ b/ViewSolutions/src/modelstorage.cpp @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/src/modelstorage.h b/ViewSolutions/src/modelstorage.h index 305a27d..4197fa7 100644 --- a/ViewSolutions/src/modelstorage.h +++ b/ViewSolutions/src/modelstorage.h @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. diff --git a/ViewSolutions/src/notificationdata.cpp b/ViewSolutions/src/notificationdata.cpp index 68443c6..2b3ba71 100644 --- a/ViewSolutions/src/notificationdata.cpp +++ b/ViewSolutions/src/notificationdata.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2025 QuasarApp. + * Copyright (C) 2018-2026 QuasarApp. * Distributed under the GPLv3 software license, see the accompanying * Everyone is permitted to copy and distribute verbatim copies * of this license document, but changing it is not allowed. @@ -10,12 +10,14 @@ namespace ViewSolutions { NotificationData::NotificationData(const QString &title, const QString &text, - const QString &img, int type) { + const QString &img, + int type) { _text = text; _title = title; _img = img; _type = type; + _time = time(0); } QString NotificationData::text() const { @@ -42,7 +44,8 @@ bool NotificationData::operator ==(const NotificationData &righ) { return _title == righ._title && _text == righ._text && _img == righ._img && - _type == righ._type; + _type == righ._type && + _time == righ._time; } bool NotificationData::operator !=(const NotificationData &righ) { @@ -65,6 +68,31 @@ QString NotificationData::getDefaultImage(const int code) const { } } +int NotificationData::getTime() const +{ + return _time; +} + +void NotificationData::setTime(int newTime) { + _time = newTime; +} + +int NotificationData::filterHuck0() const { + return _filterHuck0; +} + +void NotificationData::setFilterHuck0(int newFilterHuck0) { + _filterHuck0 = newFilterHuck0; +} + +int NotificationData::filterHuck1() const { + return _filterHuck1; +} + +void NotificationData::setFilterHuck1(int newFilterHuck1) { + _filterHuck1 = newFilterHuck1; +} + int NotificationData::type() const { return _type; } diff --git a/ViewSolutions/src/notificationdata.h b/ViewSolutions/src/notificationdata.h index 7b2f07b..48b070d 100644 --- a/ViewSolutions/src/notificationdata.h +++ b/ViewSolutions/src/notificationdata.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2024 QuasarApp. + * Copyright (C) 2018-2026 QuasarApp. * Distributed under the GPLv3 software license, see the accompanying * Everyone is permitted to copy and distribute verbatim copies * of this license document, but changing it is not allowed. @@ -26,11 +26,14 @@ class VIEWSOLUTION_EXPORT NotificationData */ enum Type { /// This is message for general notification. - Normal, + Normal = 0, /// This is warning notification. Warning = 1, /// This is critical error notifications. Error = 2, + + /// This is user defined type of message. + Custom = 3, }; explicit NotificationData(const QString& title = "", @@ -84,6 +87,15 @@ class VIEWSOLUTION_EXPORT NotificationData bool operator ==(const NotificationData &righ); bool operator !=(const NotificationData &righ); + int getTime() const; + void setTime(int newTime); + + int filterHuck0() const; + void setFilterHuck0(int newFilterHuck0); + + int filterHuck1() const; + void setFilterHuck1(int newFilterHuck1); + private: QString getDefaultImage(const int code) const; @@ -91,6 +103,9 @@ class VIEWSOLUTION_EXPORT NotificationData QString _img; QString _title; int _type; + int _time = 0; + int _filterHuck0 = 0; + int _filterHuck1 = 0; }; } diff --git a/ViewSolutions/src/notificationservice.cpp b/ViewSolutions/src/notificationservice.cpp index 29fe707..803b94b 100644 --- a/ViewSolutions/src/notificationservice.cpp +++ b/ViewSolutions/src/notificationservice.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2024 QuasarApp. + * Copyright (C) 2018-2026 QuasarApp. * Distributed under the GPLv3 software license, see the accompanying * Everyone is permitted to copy and distribute verbatim copies * of this license document, but changing it is not allowed. @@ -117,14 +117,45 @@ void NotificationService::showHistory() { emit sigShowHistory(); } +void NotificationService::notificationHiden() { + setUiIsDisplay(false); +} + int NotificationService::notificationsCount() const { return _history->rowCount({}); } - QString ViewSolutions::NotificationService::modelId() const { return "NotificationService"; } +bool NotificationService::uiIsDisplay() const { + return _uiIsDisplay && time(0) - _lastDisplayTime < _uiTimeOut; +} + +void NotificationService::setUiIsDisplay(bool newUiIsDisplay) { + if (_uiIsDisplay == newUiIsDisplay) + return; + + if (_uiIsDisplay) { + _lastDisplayTime = time(0); + } + + _uiIsDisplay = newUiIsDisplay; + emit uiIsDisplayChanged(); +} + +void NotificationService::setHistory(const QList &historyList) { + _history->setHistory(historyList); +} + +int NotificationService::uiTimeOut() const { + return _uiTimeOut; +} + +void NotificationService::setUiTimeOut(int newUiTimeOut) { + _uiTimeOut = newUiTimeOut; +} + } diff --git a/ViewSolutions/src/notificationservice.h b/ViewSolutions/src/notificationservice.h index d954141..39c94d9 100644 --- a/ViewSolutions/src/notificationservice.h +++ b/ViewSolutions/src/notificationservice.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2024 QuasarApp. + * Copyright (C) 2018-2026 QuasarApp. * Distributed under the GPLv3 software license, see the accompanying * Everyone is permitted to copy and distribute verbatim copies * of this license document, but changing it is not allowed. @@ -32,12 +32,16 @@ class VIEWSOLUTION_EXPORT NotificationService: public QObject, public iModel Q_PROPERTY(NotificationData notify READ notify NOTIFY notifyChanged) Q_PROPERTY(NotificationData question READ question NOTIFY questionChanged) + Q_PROPERTY(bool uiIsDisplay READ uiIsDisplay WRITE setUiIsDisplay NOTIFY uiIsDisplayChanged FINAL) Q_PROPERTY(QObject* history READ history NOTIFY notifyChanged) Q_PROPERTY(int notificationsCount READ notificationsCount NOTIFY countNotificationsChanged) public: + explicit NotificationService(QObject *ptr = nullptr); + ~NotificationService(); + /** * @brief Notify This method return data of the last notify message. * @return return data of the last notify message. @@ -131,18 +135,48 @@ class VIEWSOLUTION_EXPORT NotificationService: public QObject, public iModel Q_INVOKABLE void showHistory(); + /** + * @brief notificationHiden this method should invoked every time when the current notification is hiden, automaticaly or by user. + */ + Q_INVOKABLE void notificationHiden(); + /** * @brief notificationsCount - This method used for return count of history notifications. * @return count of history notifications. */ Q_INVOKABLE int notificationsCount() const; - ~NotificationService(); // iModel interface public: QString modelId() const override; + /** + * @brief uiIsDisplay this method return true if notify service is display now. + * @return true if notify service is display now. + */ + bool uiIsDisplay() const; + + /** + * @brief setUiIsDisplay this method used for set notify service display state. + * @param newUiIsDisplay - new display state. + */ + void setUiIsDisplay(bool newUiIsDisplay); + + /** + * @brief setHistory this method used for set history list. + * @param historyList - list of history notifications. + */ + void setHistory(const QList &historyList); + + + /** + * @brief uiTimeOut this is maximu time that notify service can be loked fo display. + * @return + */ + int uiTimeOut() const; + void setUiTimeOut(int newUiTimeOut); + signals: /** * @brief notifyChanged This signal emited whet the notificator (Ths object) received a new notification message. @@ -168,14 +202,19 @@ class VIEWSOLUTION_EXPORT NotificationService: public QObject, public iModel void countNotificationsChanged(); + void uiIsDisplayChanged(); + private: - explicit NotificationService(QObject *ptr = nullptr); QHash _listners; NotificationData _question; NotificationData _notify; + bool _uiIsDisplay = false; + int _uiTimeOut = 60; + int _lastDisplayTime = 0; + HistoryNotificationsModel* _history = nullptr; diff --git a/ViewSolutions/src/qmlcolorpicker.cpp b/ViewSolutions/src/qmlcolorpicker.cpp index 06bbe5b..03ebe11 100644 --- a/ViewSolutions/src/qmlcolorpicker.cpp +++ b/ViewSolutions/src/qmlcolorpicker.cpp @@ -1,6 +1,6 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. @@ -40,7 +40,7 @@ QColor QMLColorPicker::pick(const QString &img) const { return {}; } - QColor responce = ColorPicker::pick(textureFacrory->image()); + QColor responce = ColorPicker::pick(textureFacrory->image(), 5, _alpha); delete textureFacrory; @@ -48,15 +48,15 @@ QColor QMLColorPicker::pick(const QString &img) const { } if (provider->imageType() == QQmlImageProviderBase::Texture) { - return ColorPicker::pick(provider->requestTexture(url, nullptr, {})->image()); + return ColorPicker::pick(provider->requestTexture(url, nullptr, {})->image(), 5, _alpha); } if (provider->imageType() == QQmlImageProviderBase::Pixmap) { - return ColorPicker::pick(provider->requestPixmap(url, nullptr, {}).toImage()); + return ColorPicker::pick(provider->requestPixmap(url, nullptr, {}).toImage(), 5, _alpha); } if (provider->imageType() == QQmlImageProviderBase::Image) { - return ColorPicker::pick(provider->requestImage(url, nullptr, {})); + return ColorPicker::pick(provider->requestImage(url, nullptr, {}), 5, _alpha); } return {}; @@ -64,11 +64,24 @@ QColor QMLColorPicker::pick(const QString &img) const { } - return ColorPicker::pick(img); + return ColorPicker::pick(img, _alpha); } QString QMLColorPicker::modelId() const { return "ColorPicker"; } +bool QMLColorPicker::alpha() const +{ + return _alpha; +} + +void QMLColorPicker::setAlpha(bool newAlpha) +{ + if (_alpha == newAlpha) + return; + _alpha = newAlpha; + emit alphaChanged(); +} + } diff --git a/ViewSolutions/src/qmlcolorpicker.h b/ViewSolutions/src/qmlcolorpicker.h index 3cf8c4d..e518d20 100644 --- a/ViewSolutions/src/qmlcolorpicker.h +++ b/ViewSolutions/src/qmlcolorpicker.h @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. @@ -20,6 +20,8 @@ namespace ViewSolutions { class VIEWSOLUTION_EXPORT QMLColorPicker : public QObject, public iModel, private ColorPicker { Q_OBJECT + Q_PROPERTY(bool alpha READ alpha WRITE setAlpha NOTIFY alphaChanged FINAL) + public: explicit QMLColorPicker(QObject *parent = nullptr); @@ -37,6 +39,25 @@ class VIEWSOLUTION_EXPORT QMLColorPicker : public QObject, public iModel, privat */ QString modelId() const override; + /** + * @brief alpha the alpha swith display color picer mod to alpha mode. in this mode picker will calculate alpha channel also with RGB hannels. + * set to false to disable calculate alpha hannel. + * @return + */ + bool alpha() const; + + /** + * @brief setAlpha set new value of alpha mode. + * @param newAlpha new value + */ + void setAlpha(bool newAlpha); + +signals: + void alphaChanged(); + +private: + bool _alpha = true; + }; } diff --git a/ViewSolutions/src/stacktextmodel.cpp b/ViewSolutions/src/stacktextmodel.cpp new file mode 100644 index 0000000..27a258d --- /dev/null +++ b/ViewSolutions/src/stacktextmodel.cpp @@ -0,0 +1,66 @@ +//# +//# Copyright (C) 2025-2026 QuasarApp. +//# Distributed under the GPLv3 software license, see the accompanying +//# Everyone is permitted to copy and distribute verbatim copies +//# of this license document, but changing it is not allowed. +//# + +#include "stacktextmodel.h" + +StackTextModel::StackTextModel() {} + +QString StackTextModel::fullText() const { + return _fullText; +} + +void StackTextModel::setFullText(const QString &newFullText) { + if (_fullText == newFullText) + return; + _fullText = newFullText; + updateText(); + emit fullTextChanged(); +} + +QString StackTextModel::delimiter() const { + return _delimiter.pattern(); +} + +void StackTextModel::setDelimiter(const QString &newDelimiter) { + if (_delimiter.pattern() == newDelimiter) + return; + _delimiter.setPattern(newDelimiter); + updateText(); + emit delimiterChanged(); +} + +void StackTextModel::updateText() { + QStringList lines; + QString line; + + int delimeterIdx = _fullText.indexOf(_delimiter); + int lastIdx = -1; + while (delimeterIdx >= 0) { + line = _fullText.mid(lastIdx + 1, delimeterIdx - lastIdx); + lastIdx = delimeterIdx; + delimeterIdx = _fullText.indexOf(_delimiter, lastIdx + 1); + + if (line.size()) { + lines += line; + } + + } + + // take last string. + line = _fullText.mid(lastIdx + 1, delimeterIdx); + if (line.size()) { + lines += line; + } + + setStringList(lines); +} + +QHash StackTextModel::roleNames() const { + QHash roles; + roles[Qt::DisplayRole] = "display"; + return roles; +} diff --git a/ViewSolutions/src/stacktextmodel.h b/ViewSolutions/src/stacktextmodel.h new file mode 100644 index 0000000..9f8c403 --- /dev/null +++ b/ViewSolutions/src/stacktextmodel.h @@ -0,0 +1,73 @@ +//# +//# Copyright (C) 2025-2026 QuasarApp. +//# Distributed under the GPLv3 software license, see the accompanying +//# Everyone is permitted to copy and distribute verbatim copies +//# of this license document, but changing it is not allowed. +//# + + +#ifndef STACKTEXTMODEL_H +#define STACKTEXTMODEL_H + +#include +#include +#include "viewsolutions_global.h" + +/** + * @brief The StackTextModel class is model that contains stack text lines. + * This model split full text into lines by delimiter. + */ +class VIEWSOLUTION_EXPORT StackTextModel: public QStringListModel +{ + Q_OBJECT + + Q_PROPERTY(QString fullText READ fullText WRITE setFullText NOTIFY fullTextChanged FINAL) + Q_PROPERTY(QString delimiter READ delimiter WRITE setDelimiter NOTIFY delimiterChanged FINAL) + +public: + StackTextModel(); + + // QAbstractItemModel interface + + /** + * @brief fullText returns full text from all lines. + * @return full text from all lines. + */ + QString fullText() const; + void setFullText(const QString &newFullText); + + /** + * @brief delimiter returns delimiter that used to split fullText into lines. + * @return delimiter that used to split fullText into lines. + * @default is "\n" + */ + QString delimiter() const; + + /** + * @brief setDelimiter sets new delimiter for split fullText into lines. + * @param newDelimiter new delimiter for split fullText into lines. + */ + void setDelimiter(const QString &newDelimiter); + QHash roleNames() const override; + +protected: + + /** + * @brief updateText updates internal model data from fullText and delimiter. + */ + virtual void updateText(); + +signals: + void fullTextChanged(); + void delimiterChanged(); + +private: + + QString _fullText; + QRegularExpression _delimiter = QRegularExpression("([.?!;]+)"); + + // QAbstractItemModel interface +public: +}; + +#endif // STACKTEXTMODEL_H diff --git a/ViewSolutions/src/viewsolutions.cpp b/ViewSolutions/src/viewsolutions.cpp index 3eb58c8..eec0101 100644 --- a/ViewSolutions/src/viewsolutions.cpp +++ b/ViewSolutions/src/viewsolutions.cpp @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed. @@ -13,6 +13,7 @@ #include #include #include +#include namespace ViewSolutions { QSharedPointer init(QQmlEngine *engine) { @@ -32,12 +33,15 @@ QSharedPointer init(QQmlEngine *engine) { root->setContextProperty("modelsStorage", storage.get()); auto&& picker = QSharedPointer::create(); + picker->setAlpha(false); storage->addModel(picker); // to-do - remove root->setContextProperty("colorPicker", picker.get()); - qRegisterMetaType("VariantListModel"); + qmlRegisterType("ViewSolutions", 1, 0, "VariantListModel"); + qmlRegisterType("ViewSolutions", 1, 0, "StackTextModel"); + return storage; } diff --git a/ViewSolutions/src/viewsolutions.h b/ViewSolutions/src/viewsolutions.h index acb0f65..dde5500 100644 --- a/ViewSolutions/src/viewsolutions.h +++ b/ViewSolutions/src/viewsolutions.h @@ -1,5 +1,5 @@ //# -//# Copyright (C) 2020-2025 QuasarApp. +//# Copyright (C) 2020-2026 QuasarApp. //# Distributed under the GPLv3 software license, see the accompanying //# Everyone is permitted to copy and distribute verbatim copies //# of this license document, but changing it is not allowed.