19 Commits

Author SHA1 Message Date
Digital Artifex 6bea9b32df Added animation settings 2026-08-25 19:22:39 -04:00
Digital Artifex c8209b723a Added application settings page 2026-08-25 19:21:53 -04:00
Digital Artifex e779c8e9b1 Added apply and reset functions 2026-08-25 19:20:02 -04:00
Digital Artifex 5def93edf2 Removed unused assets 2026-08-25 19:18:55 -04:00
Digital Artifex abdd49bf52 Removed Qt completion default comment 2026-08-25 14:28:49 -04:00
Digital Artifex 871ab8a262 Added copyright block 2026-08-25 14:24:37 -04:00
Digital Artifex 3ef029aba9 Removed KOMPLEX_LOCAL_DEV define 2026-08-25 14:03:51 -04:00
Digital Artifex cf5baa0684 Cleanup unused assets and finished comments 2026-08-25 11:00:04 -04:00
Digital Artifex 2ffe0bba88 Merge pull request #1 from DigitalArtifex/dev
PackCompiler should now be much more stable and cuts down on file writes. Instead of rewriting the file for each modification, the entire process now requires just 2 file writes per shader: 1 to extract and 1 to save the compiled shader. Also, the need to expose a setting for the location to the qsb binary is no longer needed as it uses QShaderBaker directly.

It should also be a bit faster now. Instead of compiling a generic set of versions, it only compiles the safe default or system reported supported versions for both SPIR-V and GLSL, when they are present. Only caveat would be if a user were to downgrade their GPU. They would potentially need to rebuild the packs they have installed.
2026-08-25 05:23:22 -04:00
Digital Artifex b4a1e1bbf4 Renamed Controls and Kero modules 2026-08-25 04:45:09 -04:00
Digital Artifex 2fab4f209f Added private libs to get rhi class QShaderBaker 2026-08-25 04:43:35 -04:00
Digital Artifex 6541cedc67 Changed exceptions to std bases 2026-08-25 04:42:43 -04:00
Digital Artifex f3adc14a6e Reworked PackCompiler
PackCompiler now processes everything in memory to reduce file writes. Will also be able to expand error handling later
2026-08-25 04:35:15 -04:00
Digital Artifex 7b25255126 Final alpha fixes. BETA1 release 2026-08-21 07:11:31 -04:00
Digital Artifex 1aaff0cd02 Pack downloader a bit better now 2026-08-20 14:14:22 -04:00
Digital Artifex d60cdef637 Started to add pack download 2026-08-20 05:09:44 -04:00
Digital Artifex 97c9ba30f0 Changed default background color 2026-08-19 16:55:40 -04:00
Digital Artifex 6e94484fac Fixed uuid reference in pack view 2026-08-19 16:54:56 -04:00
Digital Artifex 1d87abd5af Fixed Button Box 2026-08-19 16:53:09 -04:00
62 changed files with 3378 additions and 1265 deletions
+8 -7
View File
@@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.21.1)
option(LINK_INSIGHT "Link Qt Insight Tracker library" ON) option(LINK_INSIGHT "Link Qt Insight Tracker library" ON)
option(BUILD_QDS_COMPONENTS "Build design studio components" ON) option(BUILD_QDS_COMPONENTS "Build design studio components" ON)
project(KomplexHub LANGUAGES CXX) project(KomplexHub VERSION 1.0 LANGUAGES CXX)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
@@ -21,7 +21,7 @@ set(QML_IMPORT_PATH ${QT_QML_OUTPUT_DIRECTORY}
) )
find_package( find_package(
Qt6 6.8 Qt6
REQUIRED COMPONENTS REQUIRED COMPONENTS
Core Core
Gui Gui
@@ -38,6 +38,7 @@ qt_standard_project_setup()
qt_add_executable(${CMAKE_PROJECT_NAME} qt_add_executable(${CMAKE_PROJECT_NAME}
) )
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES VERSION "1.0")
qt_add_resources(${CMAKE_PROJECT_NAME} "configuration" qt_add_resources(${CMAKE_PROJECT_NAME} "configuration"
PREFIX "/" PREFIX "/"
@@ -102,11 +103,11 @@ qt_add_resources(${CMAKE_PROJECT_NAME} "app_images"
"images/kero/kero_warning.png" "images/kero/kero_warning.png"
) )
target_compile_definitions( # target_compile_definitions(
${CMAKE_PROJECT_NAME} # ${CMAKE_PROJECT_NAME}
PUBLIC # PUBLIC
KOMPLEX_LOCAL_DEV # KOMPLEX_LOCAL_DEV
) # )
include(qds) include(qds)
+32 -3
View File
@@ -1,21 +1,50 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtQuick import QtQuick
import QtQuick.Controls 2.15 import QtQuick.Controls 2.15
import QtCore
import KomplexHub import KomplexHub
import org.kde.kirigami as Kirigami
ApplicationWindow { ApplicationWindow {
id: window
visible: true visible: true
flags: Qt.Window flags: Qt.Window
title: "KomplexHub" title: "KomplexHub"
color: "transparent" color: "transparent"
minimumWidth: 720 minimumWidth: 720
MainScreen { MainScreen
antialiasing: true {
id: mainScreen id: mainScreen
antialiasing: true
anchors.fill: parent anchors.fill: parent
} }
Settings
{
property alias x: window.x
property alias y: window.y
property alias width: window.width
property alias height: window.height
}
} }
+49 -32
View File
@@ -1,9 +1,22 @@
/* /*
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only. * Komplex Wallpaper Engine
It is supposed to be strictly declarative and only uses a subset of QML. If you edit * Copyright (C) 2026 @DigitalArtifex
this file manually, you might introduce QML code that is not supported by Qt Design Studio. * https://digitalartifex.dev - https://github.com/DigitalArtifex
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. *
*/ * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
import QtQuick.Layouts import QtQuick.Layouts
@@ -12,7 +25,8 @@ import KomplexHub.Controls
import KomplexHub.Kero import KomplexHub.Kero
import KomplexHubContent import KomplexHubContent
Rectangle { Rectangle
{
property MenuButton currentMenuButton property MenuButton currentMenuButton
property bool popup: false property bool popup: false
@@ -20,12 +34,14 @@ Rectangle {
color: palette.window color: palette.window
RowLayout { RowLayout
{
id: windowRootLayout id: windowRootLayout
anchors.fill: parent anchors.fill: parent
spacing: 0 spacing: 0
Rectangle { Rectangle
{
id: windowMenu id: windowMenu
Layout.fillWidth: false Layout.fillWidth: false
@@ -58,10 +74,12 @@ Rectangle {
selected = false selected = false
} }
Behavior on opacity { Behavior on opacity
{
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
} }
@@ -228,7 +246,7 @@ Rectangle {
{ {
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ? settings.normalAnimationDuration : 0
} }
} }
} }
@@ -266,8 +284,12 @@ Rectangle {
pageLoader.setSearchTerm() pageLoader.setSearchTerm()
} }
Behavior on preferredHeight { Behavior on preferredHeight
NumberAnimation { duration: Constants.normalAnimationDuration } {
NumberAnimation
{
duration: settings.animationsEnabled ? settings.normalAnimationDuration : 0
}
} }
} }
@@ -302,7 +324,7 @@ Rectangle {
id: pageLoaderAnimation id: pageLoaderAnimation
target: pageLoader target: pageLoader
duration: 150 duration: settings.animationsEnabled ? settings.pageChangeAnimationDuration : 0
onFinished: () => { onFinished: () => {
if(pageLoader.loading && pageLoader.opacity === 0) if(pageLoader.loading && pageLoader.opacity === 0)
@@ -381,23 +403,6 @@ Rectangle {
} }
} }
KeroBuildingAnimation
{
id: buildingOverlay
anchors.fill: parent
visible: false
}
KeroLoadingAnimation
{
id: loadingAnimation
anchors.fill: parent
visible: opacity > 0
opacity: 0
}
Connections Connections
{ {
id: popupConnection id: popupConnection
@@ -414,7 +419,6 @@ Rectangle {
currentMenuButton = homeMenubutton currentMenuButton = homeMenubutton
pageLoader.page = "pages/HomePage.qml" pageLoader.page = "pages/HomePage.qml"
searchContainer.preferredHeight = 0 searchContainer.preferredHeight = 0
loadingAnimation.opacity = 0
} }
states: [ states: [
@@ -446,4 +450,17 @@ Rectangle {
} }
] ]
Settings
{
id: settings
property bool animationsEnabled: true
//ms length of page change
property int pageChangeAnimationDuration: 250
property int pageFadeAnimationDuration: 250
property int slowAnimationDuration: 750
property int normalAnimationDuration: 250
property int fastAnimationDuration: 125
}
} }
+1
View File
@@ -17,4 +17,5 @@ qt6_add_qml_module(KomplexHubPages
"FeaturedPacksPage.qml" "FeaturedPacksPage.qml"
"FeaturedImagesPage.qml" "FeaturedImagesPage.qml"
"NewestPacksPage.qml" "NewestPacksPage.qml"
QML_FILES KomplexSettingsPage.qml
) )
+36 -3
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -24,7 +43,6 @@ Rectangle
FeaturedImagesModel FeaturedImagesModel
{ {
id: searchModel id: searchModel
//query: rootItem.query
resultsPerPage: paginator.resultsPerPage resultsPerPage: paginator.resultsPerPage
Component.onCompleted: () => nextPage() Component.onCompleted: () => nextPage()
@@ -109,7 +127,8 @@ Rectangle
Behavior on opacity { Behavior on opacity {
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
} }
@@ -117,7 +136,8 @@ Rectangle
Behavior on opacity { Behavior on opacity {
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
} }
@@ -151,4 +171,17 @@ Rectangle
resultsLayout.opacity = 1 resultsLayout.opacity = 1
rootItem.popup = false rootItem.popup = false
} }
Settings
{
id: settings
property bool animationsEnabled: true
//ms length of page change
property int pageChangeAnimationDuration: 250
property int pageFadeAnimationDuration: 250
property int slowAnimationDuration: 750
property int normalAnimationDuration: 250
property int fastAnimationDuration: 125
}
} }
+37 -2
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -109,7 +128,8 @@ Rectangle
Behavior on opacity { Behavior on opacity {
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
} }
@@ -117,7 +137,8 @@ Rectangle
Behavior on opacity { Behavior on opacity {
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
} }
@@ -136,9 +157,23 @@ Rectangle
viewMoreWallpaperPopup.authorId = packsModel.data(packsModel.index(index,0), NewestPacksModel.AuthorIdRole) viewMoreWallpaperPopup.authorId = packsModel.data(packsModel.index(index,0), NewestPacksModel.AuthorIdRole)
viewMoreWallpaperPopup.description = packsModel.data(packsModel.index(index,0), NewestPacksModel.DescriptionRole) viewMoreWallpaperPopup.description = packsModel.data(packsModel.index(index,0), NewestPacksModel.DescriptionRole)
viewMoreWallpaperPopup.thumbnail = packsModel.data(packsModel.index(index,0), NewestPacksModel.ThumbnailRole) viewMoreWallpaperPopup.thumbnail = packsModel.data(packsModel.index(index,0), NewestPacksModel.ThumbnailRole)
viewMoreWallpaperPopup.uuid = packsModel.data(packsModel.index(index,0), NewestPacksModel.UuidRole)
viewMoreWallpaperPopup.opacity = 1 viewMoreWallpaperPopup.opacity = 1
popupContainer.opacity = 1 popupContainer.opacity = 1
resultsLayout.opacity = 0 resultsLayout.opacity = 0
rootItem.popup = true rootItem.popup = true
} }
Settings
{
id: settings
property bool animationsEnabled: true
//ms length of page change
property int pageChangeAnimationDuration: 250
property int pageFadeAnimationDuration: 250
property int slowAnimationDuration: 750
property int normalAnimationDuration: 250
property int fastAnimationDuration: 125
}
} }
+36 -2
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -109,7 +128,8 @@ Rectangle
{ {
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
} }
@@ -118,7 +138,8 @@ Rectangle
{ {
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
} }
@@ -150,4 +171,17 @@ Rectangle
resultsLayout.opacity = 1 resultsLayout.opacity = 1
rootItem.popup = false rootItem.popup = false
} }
Settings
{
id: settings
property bool animationsEnabled: true
//ms length of page change
property int pageChangeAnimationDuration: 250
property int pageFadeAnimationDuration: 250
property int slowAnimationDuration: 750
property int normalAnimationDuration: 250
property int fastAnimationDuration: 125
}
} }
+142 -9
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
import QtQuick.Layouts import QtQuick.Layouts
@@ -20,6 +39,10 @@ Item
imagesModel.state === FeaturedImagesModel.Loading || imagesModel.state === FeaturedImagesModel.Loading ||
videosModel.state === FeaturedVideosModel.Loading; videosModel.state === FeaturedVideosModel.Loading;
property bool error: packsModel.state === NewestPacksModel.Error ||
imagesModel.state === FeaturedImagesModel.Error ||
videosModel.state === FeaturedVideosModel.Error;
onWidthChanged: () => onWidthChanged: () =>
{ {
packsModel.resultsPerPage = resultsPerRow packsModel.resultsPerPage = resultsPerRow
@@ -405,6 +428,15 @@ Item
visible: opacity > 0 visible: opacity > 0
opacity: 1 opacity: 1
Behavior on opacity
{
NumberAnimation
{
duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
}
}
} }
Rectangle Rectangle
@@ -426,7 +458,8 @@ Item
{ {
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
} }
@@ -442,7 +475,8 @@ Item
{ {
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
} }
@@ -458,7 +492,8 @@ Item
{ {
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
} }
@@ -467,7 +502,8 @@ Item
{ {
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
} }
@@ -486,7 +522,8 @@ Item
{ {
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
@@ -508,7 +545,8 @@ Item
{ {
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
@@ -530,7 +568,8 @@ Item
{ {
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
@@ -538,6 +577,25 @@ Item
} }
} }
ErrorView
{
id: errorView
anchors.fill: parent
opacity: 0
visible: opacity > 0.01
manager: downloadManager
Behavior on opacity
{
NumberAnimation
{
duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
}
}
}
Item Item
{ {
id: featuredLoaderItem id: featuredLoaderItem
@@ -577,6 +635,41 @@ Item
target: popupContainer target: popupContainer
opacity: 0 opacity: 0
} }
PropertyChanges
{
target: errorView
opacity: 0
}
},
State
{
name: "error"
when: homePageRoot.error
PropertyChanges
{
target: loadingAnimation
opacity: 1
}
PropertyChanges
{
target: pageArea
opacity: 0
}
PropertyChanges
{
target: popupContainer
opacity: 0
}
PropertyChanges
{
target: errorView
opacity: 1
}
}, },
State State
{ {
@@ -594,6 +687,18 @@ Item
target: pageArea target: pageArea
opacity: 1 opacity: 1
} }
PropertyChanges
{
target: errorView
opacity: 0
}
PropertyChanges
{
target: popupContainer
opacity: 0
}
}, },
State State
{ {
@@ -611,6 +716,18 @@ Item
target: loadingAnimation target: loadingAnimation
opacity: 0 opacity: 0
} }
PropertyChanges
{
target: errorView
opacity: 0
}
PropertyChanges
{
target: popupContainer
opacity: 1
}
} }
] ]
@@ -623,13 +740,15 @@ Item
NumberAnimation NumberAnimation
{ {
target: loadingAnimation target: loadingAnimation
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
property: "opacity"; property: "opacity";
} }
NumberAnimation NumberAnimation
{ {
target: pageArea target: pageArea
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
property: "opacity"; property: "opacity";
} }
} }
@@ -702,6 +821,7 @@ Item
viewMoreWallpaperPopup.description = packsModel.data(packsModel.index(index,0), NewestPacksModel.DescriptionRole) viewMoreWallpaperPopup.description = packsModel.data(packsModel.index(index,0), NewestPacksModel.DescriptionRole)
viewMoreWallpaperPopup.thumbnail = packsModel.data(packsModel.index(index,0), NewestPacksModel.ThumbnailRole) viewMoreWallpaperPopup.thumbnail = packsModel.data(packsModel.index(index,0), NewestPacksModel.ThumbnailRole)
viewMoreWallpaperPopup.name = packsModel.data(packsModel.index(index,0), NewestPacksModel.NameRole) viewMoreWallpaperPopup.name = packsModel.data(packsModel.index(index,0), NewestPacksModel.NameRole)
viewMoreWallpaperPopup.uuid = packsModel.data(packsModel.index(index,0), NewestPacksModel.UuidRole)
viewMoreWallpaperPopup.opacity = 1 viewMoreWallpaperPopup.opacity = 1
popupContainer.opacity = 1 popupContainer.opacity = 1
pageArea.opacity = 0 pageArea.opacity = 0
@@ -724,4 +844,17 @@ Item
pageArea.opacity = 1 pageArea.opacity = 1
homePageRoot.popup = false homePageRoot.popup = false
} }
Settings
{
id: settings
property bool animationsEnabled: true
//ms length of page change
property int pageChangeAnimationDuration: 250
property int pageFadeAnimationDuration: 250
property int slowAnimationDuration: 750
property int normalAnimationDuration: 250
property int fastAnimationDuration: 125
}
} }
+36 -2
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -83,7 +102,8 @@ Item
Behavior on opacity { Behavior on opacity {
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
} }
@@ -91,7 +111,8 @@ Item
Behavior on opacity { Behavior on opacity {
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
} }
@@ -125,4 +146,17 @@ Item
paginator.opacity = 1 paginator.opacity = 1
rootItem.popup = false rootItem.popup = false
} }
Settings
{
id: settings
property bool animationsEnabled: true
//ms length of page change
property int pageChangeAnimationDuration: 250
property int pageFadeAnimationDuration: 250
property int slowAnimationDuration: 750
property int normalAnimationDuration: 250
property int fastAnimationDuration: 125
}
} }
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -138,4 +157,17 @@ Rectangle {
} }
] ]
Settings
{
id: settings
property bool animationsEnabled: true
//ms length of page change
property int pageChangeAnimationDuration: 250
property int pageFadeAnimationDuration: 250
property int slowAnimationDuration: 750
property int normalAnimationDuration: 250
property int fastAnimationDuration: 125
}
} }
@@ -0,0 +1,476 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import KomplexHub
Item
{
property bool updated: updates.length > 0
property var updates: []
ColumnLayout
{
anchors.fill: parent
anchors.margins: Constants.largeMargin
Text
{
Layout.fillWidth: true
text: qsTr("Animation Settings")
font: Constants.h1Font
color: palette.text
}
Rectangle
{
Layout.fillWidth: true
Layout.preferredHeight: 320
Layout.margins: Constants.largeMargin
color: palette.base
border.color: palette.midlight
ColumnLayout
{
id: animationSettingsLayout
anchors.fill: parent
anchors.margins: Constants.largeMargin
RowLayout
{
Layout.fillWidth: true
Layout.preferredHeight: 36
CheckBox
{
Layout.preferredHeight: 36
property bool value: settings.animationsEnabled
id: animationsEnabledCheckbox
text: qsTr("Enable Animations")
font: Constants.h3Font
checked: value
onCheckStateChanged:
{
if(updates.indexOf("enable"))
{
updates.splice(updates.indexOf("enable"), 1)
}
else
{
updates.push("enable")
}
value = checked
}
}
}
Rectangle
{
Layout.fillHeight: true
Layout.fillWidth: true
color: "transparent"
Rectangle
{
anchors.centerIn: parent
anchors.right: parent.right
anchors.left: parent.left
height: 2
color: palette.midlight
}
}
RowLayout
{
Layout.fillWidth: true
Layout.preferredHeight: 36
Text
{
Layout.fillWidth: true
Layout.fillHeight: true
text: qsTr("Slow Animation Duration (Ms)")
font: Constants.h3Font
color: palette.text
verticalAlignment: Qt.AlignVCenter
}
TextField
{
property int value: settings.slowAnimationDuration
Layout.fillHeight: true
Layout.preferredWidth: 36 * 3
id: slowAnimationDurationField
inputMethodHints: Qt.ImhFormattedNumbersOnly
horizontalAlignment: Text.AlignRight
enabled: animationsEnabledCheckbox.value
text: value
onEditingFinished: () =>
{
if(updates.indexOf("slowAnimationDuration"))
{
updates.splice(updates.indexOf("slowAnimationDuration"), 1)
}
else
{
updates.push("slowAnimationDuration")
}
value = parseInt(text)
}
Keys.onPressed: (event) =>
{
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter)
{
slowAnimationDurationField.focus = false; // Unfocus the TextField
event.accepted = true; // Prevent further propagation of the key event
}
}
background: Rectangle
{
color: slowAnimationDurationField.activeFocus ? palette.base : "transparent"
border.color: slowAnimationDurationField.activeFocus ? palette.highlight : "transparent"
border.width: 1
radius: 4
anchors.fill: slowAnimationDurationField
anchors.margins: -2
}
}
}
RowLayout
{
Layout.fillWidth: true
Layout.preferredHeight: 36
Text
{
Layout.fillWidth: true
Layout.fillHeight: true
text: qsTr("Normal Animation Duration (Ms)")
font: Constants.h3Font
color: palette.text
verticalAlignment: Qt.AlignVCenter
}
TextField
{
property int value: settings.normalAnimationDuration
Layout.fillHeight: true
Layout.preferredWidth: 36 * 3
id: normalAnimationDurationField
inputMethodHints: Qt.ImhFormattedNumbersOnly
horizontalAlignment: Text.AlignRight
enabled: animationsEnabledCheckbox.value
text: value
onEditingFinished: () =>
{
if(updates.indexOf("normalAnimationDuration"))
{
updates.splice(updates.indexOf("normalAnimationDuration"), 1)
}
else
{
updates.push("normalAnimationDuration")
}
value = parseInt(text)
}
Keys.onPressed: (event) =>
{
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter)
{
normalAnimationDurationField.focus = false; // Unfocus the TextField
event.accepted = true; // Prevent further propagation of the key event
}
}
background: Rectangle
{
color: normalAnimationDurationField.activeFocus ? palette.base : "transparent"
border.color: normalAnimationDurationField.activeFocus ? palette.highlight : "transparent"
border.width: 1
radius: 4
anchors.fill: normalAnimationDurationField
anchors.margins: -2
}
}
}
RowLayout
{
Layout.fillWidth: true
Layout.preferredHeight: 36
Text
{
Layout.fillWidth: true
Layout.fillHeight: true
text: qsTr("Fast Animation Duration (Ms)")
font: Constants.h3Font
color: palette.text
verticalAlignment: Qt.AlignVCenter
}
TextField
{
property int value: settings.fastAnimationDuration
Layout.fillHeight: true
Layout.preferredWidth: 36 * 3
id: fastAnimationDurationField
inputMethodHints: Qt.ImhFormattedNumbersOnly
horizontalAlignment: Text.AlignRight
enabled: animationsEnabledCheckbox.value
text: value
onEditingFinished: () =>
{
if(updates.indexOf("normalAnimationDuration"))
{
updates.splice(updates.indexOf("normalAnimationDuration"), 1)
}
else
{
updates.push("normalAnimationDuration")
}
value = parseInt(text)
}
Keys.onPressed: (event) =>
{
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter)
{
fastAnimationDurationField.focus = false; // Unfocus the TextField
event.accepted = true; // Prevent further propagation of the key event
}
}
background: Rectangle
{
color: fastAnimationDurationField.activeFocus ? palette.base : "transparent"
border.color: fastAnimationDurationField.activeFocus ? palette.highlight : "transparent"
border.width: 1
radius: 4
anchors.fill: fastAnimationDurationField
anchors.margins: -2
}
}
}
RowLayout
{
Layout.fillWidth: true
Layout.preferredHeight: 36
Text
{
Layout.fillWidth: true
Layout.fillHeight: true
text: qsTr("Page Change Animation Duration (Ms)")
font: Constants.h3Font
color: palette.text
verticalAlignment: Qt.AlignVCenter
}
TextField
{
property int value: settings.pageChangeAnimationDuration
Layout.fillHeight: true
Layout.preferredWidth: 36 * 3
id: pageChangeAnimationDurationField
inputMethodHints: Qt.ImhFormattedNumbersOnly
horizontalAlignment: Text.AlignRight
enabled: animationsEnabledCheckbox.value
text: value
onEditingFinished: () =>
{
if(updates.indexOf("pageChangeAnimationDuration"))
{
updates.splice(updates.indexOf("pageChangeAnimationDuration"), 1)
}
else
{
updates.push("pageChangeAnimationDuration")
}
value = parseInt(text)
}
Keys.onPressed: (event) =>
{
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter)
{
pageChangeAnimationDurationField.focus = false; // Unfocus the TextField
event.accepted = true; // Prevent further propagation of the key event
}
}
background: Rectangle
{
color: pageChangeAnimationDurationField.activeFocus ? palette.base : "transparent"
border.color: pageChangeAnimationDurationField.activeFocus ? palette.highlight : "transparent"
border.width: 1
radius: 4
anchors.fill: pageChangeAnimationDurationField
anchors.margins: -2
}
}
}
RowLayout
{
Layout.fillWidth: true
Layout.preferredHeight: 36
Text
{
Layout.fillWidth: true
Layout.fillHeight: true
text: qsTr("Page Fade Animation Duration (Ms)")
font: Constants.h3Font
color: palette.text
verticalAlignment: Qt.AlignVCenter
}
TextField
{
property int value: settings.pageFadeAnimationDuration
Layout.fillHeight: true
Layout.preferredWidth: 36 * 3
id: pageFadeAnimationDurationField
inputMethodHints: Qt.ImhFormattedNumbersOnly
horizontalAlignment: Text.AlignRight
text: value
enabled: animationsEnabledCheckbox.value
onEditingFinished: () =>
{
if(updates.indexOf("pageChangeAnimationDuration"))
{
updates.splice(updates.indexOf("pageChangeAnimationDuration"), 1)
}
else
{
updates.push("pageChangeAnimationDuration")
}
value = parseInt(text)
}
Keys.onPressed: (event) =>
{
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter)
{
pageFadeAnimationDurationField.focus = false; // Unfocus the TextField
event.accepted = true; // Prevent further propagation of the key event
}
}
background: Rectangle
{
color: pageFadeAnimationDurationField.activeFocus ? palette.base : "transparent"
border.color: pageFadeAnimationDurationField.activeFocus ? palette.highlight : "transparent"
border.width: 1
radius: 4
anchors.fill: pageFadeAnimationDurationField
anchors.margins: -2
}
}
}
}
}
Item
{
Layout.fillHeight: true
Layout.fillWidth: true
}
}
Settings
{
id: settings
property bool animationsEnabled: true
//ms length of page change
property int pageChangeAnimationDuration: 250
property int pageFadeAnimationDuration: 250
property int slowAnimationDuration: 750
property int normalAnimationDuration: 250
property int fastAnimationDuration: 125
}
function apply()
{
if(updated)
{
settings.animationsEnabled = animationsEnabledCheckbox.value
settings.slowAnimationDuration = slowAnimationDurationField.value
settings.normalAnimationDuration = normalAnimationDurationField.value
settings.fastAnimationDuration = fastAnimationDurationField.value
settings.pageChangeAnimationDuration = pageChangeAnimationDurationField.value
settings.pageFadeAnimationDuration = pageFadeAnimationDurationField.value
updates.splice(0, updates.length)
}
}
function reset()
{
if(updated)
{
animationsEnabledCheckbox.value = settings.animationsEnabled
slowAnimationDurationField.value = settings.slowAnimationDuration
normalAnimationDurationField.value = settings.normalAnimationDuration
fastAnimationDurationField.value = settings.fastAnimationDuration
pageChangeAnimationDurationField.value = settings.pageChangeAnimationDuration
pageFadeAnimationDurationField.value = settings.pageFadeAnimationDuration
updates.splice(0, updates.length)
}
}
}
+47 -13
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
@@ -65,6 +84,15 @@ Item
} }
} }
} }
Behavior on opacity
{
NumberAnimation
{
duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
}
}
} }
Rectangle Rectangle
@@ -73,27 +101,20 @@ Item
anchors.fill: parent anchors.fill: parent
opacity: 0 opacity: 0
color: palette.base color: palette.base
visible: opacity > 0.01
PackView PackView
{ {
id: viewMoreWallpaperPopup id: viewMoreWallpaperPopup
anchors.fill: parent anchors.fill: parent
opacity: 0
visible: opacity > 0.01
//model: videosModel.itemModel
Behavior on opacity {
NumberAnimation
{
duration: 250
}
}
} }
Behavior on opacity { Behavior on opacity
{
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
} }
@@ -112,9 +133,22 @@ Item
viewMoreWallpaperPopup.authorId = searchModel.data(searchModel.index(index,0), PackSearchModel.AuthorIdRole) viewMoreWallpaperPopup.authorId = searchModel.data(searchModel.index(index,0), PackSearchModel.AuthorIdRole)
viewMoreWallpaperPopup.description = searchModel.data(searchModel.index(index,0), PackSearchModel.DescriptionRole) viewMoreWallpaperPopup.description = searchModel.data(searchModel.index(index,0), PackSearchModel.DescriptionRole)
viewMoreWallpaperPopup.thumbnail = searchModel.data(searchModel.index(index,0), PackSearchModel.ThumbnailRole) viewMoreWallpaperPopup.thumbnail = searchModel.data(searchModel.index(index,0), PackSearchModel.ThumbnailRole)
viewMoreWallpaperPopup.opacity = 1 viewMoreWallpaperPopup.uuid = searchModel.data(searchModel.index(index,0), PackSearchModel.UuidRole)
popupContainer.opacity = 1 popupContainer.opacity = 1
paginator.opacity = 0 paginator.opacity = 0
rootItem.popup = true rootItem.popup = true
} }
Settings
{
id: settings
property bool animationsEnabled: true
//ms length of page change
property int pageChangeAnimationDuration: 250
property int pageFadeAnimationDuration: 250
property int slowAnimationDuration: 750
property int normalAnimationDuration: 250
property int fastAnimationDuration: 125
}
} }
+32
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -90,4 +109,17 @@ Item {
} }
} }
} }
Settings
{
id: settings
property bool animationsEnabled: true
//ms length of page change
property int pageChangeAnimationDuration: 250
property int pageFadeAnimationDuration: 250
property int slowAnimationDuration: 750
property int normalAnimationDuration: 250
property int fastAnimationDuration: 125
}
} }
+49 -4
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -90,6 +109,15 @@ Rectangle
} }
} }
} }
Behavior on opacity
{
NumberAnimation
{
duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
}
}
} }
Rectangle Rectangle
@@ -107,18 +135,22 @@ Rectangle
opacity: 0 opacity: 0
visible: opacity > 0.01 visible: opacity > 0.01
Behavior on opacity { Behavior on opacity
{
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
} }
Behavior on opacity { Behavior on opacity
{
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
} }
@@ -142,4 +174,17 @@ Rectangle
resultsLayout.opacity = 0 resultsLayout.opacity = 0
rootItem.popup = true rootItem.popup = true
} }
Settings
{
id: settings
property bool animationsEnabled: true
//ms length of page change
property int pageChangeAnimationDuration: 250
property int pageFadeAnimationDuration: 250
property int slowAnimationDuration: 750
property int normalAnimationDuration: 250
property int fastAnimationDuration: 125
}
} }
+158 -19
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -11,6 +30,9 @@ import KomplexHub.Pages
Item { Item {
readonly property bool searchable: false readonly property bool searchable: false
property bool settingsUpdated: wallpaperSettingsUpdated || komplexSettingsUpdated
property bool wallpaperSettingsUpdated: wallpaperSettingsPage.updated && pageStack.currentIndex === 0
property bool komplexSettingsUpdated: komplexSettingsPage.updated && pageStack.currentIndex === 1
id: settingsPageRoot id: settingsPageRoot
@@ -29,6 +51,9 @@ Item {
TabButton { TabButton {
text: qsTr("Wallpaper") text: qsTr("Wallpaper")
} }
TabButton {
text: qsTr("Komplex")
}
TabButton { TabButton {
text: qsTr("Account") text: qsTr("Account")
} }
@@ -37,33 +62,53 @@ Item {
} }
} }
StackLayout { StackLayout
{
id: pageStack
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
currentIndex: bar.currentIndex currentIndex: bar.currentIndex
Item { Item
{
id: wallpaperTab id: wallpaperTab
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
WallpaperSettingsPage { WallpaperSettingsPage
{
id: wallpaperSettingsPage
anchors.fill: parent anchors.fill: parent
} }
} }
Item { Item
{
id: komplexTab
Layout.fillHeight: true
Layout.fillWidth: true
KomplexSettingsPage
{
id: komplexSettingsPage
anchors.fill: parent
}
}
Item
{
id: accountTab id: accountTab
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
UserProfilePage { UserProfilePage
{
anchors.fill: parent anchors.fill: parent
} }
} }
Item { Item
{
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
property string title: qsTr("Hello!") property string title: qsTr("Hello!")
@@ -78,14 +123,17 @@ Pexels")
id: keroHelloAvatarRoot id: keroHelloAvatarRoot
Rectangle { Rectangle
{
anchors.fill: parent anchors.fill: parent
color: "transparent" color: "transparent"
ColumnLayout { ColumnLayout
{
anchors.fill: parent anchors.fill: parent
KeroHelloAvatar { KeroHelloAvatar
{
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
antialiasing: true antialiasing: true
@@ -93,7 +141,8 @@ Pexels")
Item { Layout.preferredHeight: 36 } Item { Layout.preferredHeight: 36 }
Text { Text
{
Layout.fillHeight: false Layout.fillHeight: false
Layout.fillWidth: true Layout.fillWidth: true
Layout.margins: Constants.largeMargin Layout.margins: Constants.largeMargin
@@ -106,7 +155,8 @@ Pexels")
textFormat: Text.MarkdownText textFormat: Text.MarkdownText
} }
Text { Text
{
Layout.fillHeight: false Layout.fillHeight: false
Layout.fillWidth: true Layout.fillWidth: true
Layout.margins: Constants.largeMargin Layout.margins: Constants.largeMargin
@@ -121,16 +171,19 @@ Pexels")
Item { Layout.fillHeight: true } Item { Layout.fillHeight: true }
RowLayout { RowLayout
{
Layout.fillWidth: true Layout.fillWidth: true
Layout.alignment: Qt.AlignTop | Qt.AlignRight Layout.alignment: Qt.AlignTop | Qt.AlignRight
ColumnLayout { ColumnLayout
{
Layout.alignment: Qt.AlignTop | Qt.AlignRight Layout.alignment: Qt.AlignTop | Qt.AlignRight
Layout.margins: Constants.largeMargin Layout.margins: Constants.largeMargin
Layout.fillHeight: true Layout.fillHeight: true
Text { Text
{
text: qsTr("Contributors") text: qsTr("Contributors")
color: palette.text.darker() color: palette.text.darker()
font: Constants.h5Font font: Constants.h5Font
@@ -141,7 +194,8 @@ Pexels")
textFormat: Text.MarkdownText textFormat: Text.MarkdownText
} }
Text { Text
{
id: contributorText id: contributorText
text: keroHelloAvatarRoot.contributors text: keroHelloAvatarRoot.contributors
color: palette.text.darker() color: palette.text.darker()
@@ -153,12 +207,14 @@ Pexels")
} }
} }
ColumnLayout { ColumnLayout
{
Layout.alignment: Qt.AlignTop | Qt.AlignRight Layout.alignment: Qt.AlignTop | Qt.AlignRight
Layout.margins: Constants.largeMargin Layout.margins: Constants.largeMargin
Layout.fillHeight: true Layout.fillHeight: true
Text { Text
{
text: qsTr("Special Thanks") text: qsTr("Special Thanks")
color: palette.text.darker() color: palette.text.darker()
font: Constants.h5Font font: Constants.h5Font
@@ -169,7 +225,8 @@ Pexels")
textFormat: Text.MarkdownText textFormat: Text.MarkdownText
} }
Text { Text
{
id: thanksText id: thanksText
text: keroHelloAvatarRoot.thanks text: keroHelloAvatarRoot.thanks
color: palette.text.darker() color: palette.text.darker()
@@ -183,10 +240,92 @@ Pexels")
} }
} }
} }
}
}
Rectangle
{
Layout.fillWidth: true
Layout.preferredHeight: settingsUpdated ? 64 : 0
color: palette.base
border.color: palette.midlight
opacity: settingsUpdated ? 1 : 0
RowLayout
{
anchors.fill: parent
anchors.rightMargin: Constants.mediumMargin
Item
{
Layout.fillHeight: true
Layout.fillWidth: true
}
SquareButton
{
Layout.preferredHeight: 50
Layout.preferredWidth: 160
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
icon.source: "qrc:/images/icons/icons8-reply-arrow.svg"
text: qsTr("Reset")
}
SquareButton
{
Layout.preferredHeight: 50
Layout.preferredWidth: 160
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
icon.source: "qrc:/images/icons/icons8-check-mark.svg"
text: qsTr("Apply")
}
}
Behavior on opacity
{
NumberAnimation
{
duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
}
}
Behavior on height
{
NumberAnimation
{
duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
}
} }
} }
} }
}
function applyCurrentSettings()
{
if(pageStack.currentIndex === 0 && wallpaperSettingsPage.updated)
{
wallpaperSettingsPage.apply()
}
else if(pageStack.currentIndex === 1 && komplexSettingsPage.updated)
{
komplexSettingsPage.apply()
}
}
function resetCurrentSettings()
{
if(pageStack.currentIndex === 0 && wallpaperSettingsPage.updated)
{
wallpaperSettingsPage.reset()
}
else if(pageStack.currentIndex === 1 && komplexSettingsPage.updated)
{
komplexSettingsPage.reset()
}
} }
} }
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -63,4 +82,17 @@ Item {
} }
} }
} }
Settings
{
id: settings
property bool animationsEnabled: true
//ms length of page change
property int pageChangeAnimationDuration: 250
property int pageFadeAnimationDuration: 250
property int slowAnimationDuration: 750
property int normalAnimationDuration: 250
property int fastAnimationDuration: 125
}
} }
+44 -9
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -66,6 +85,15 @@ Item
} }
} }
} }
Behavior on opacity
{
NumberAnimation
{
duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
}
}
} }
Rectangle Rectangle
@@ -80,22 +108,16 @@ Item
{ {
id: viewMoreVideoPopup id: viewMoreVideoPopup
anchors.fill: parent anchors.fill: parent
visible: opacity > 0.01
opacity: 0 opacity: 0
Behavior on opacity
{
NumberAnimation
{
duration: 250
}
}
} }
Behavior on opacity Behavior on opacity
{ {
NumberAnimation NumberAnimation
{ {
duration: 250 duration: settings.animationsEnabled ?
settings.normalAnimationDuration : 0
} }
} }
} }
@@ -122,4 +144,17 @@ Item
paginator.opacity = 1 paginator.opacity = 1
rootItem.popup = false rootItem.popup = false
} }
Settings
{
id: settings
property bool animationsEnabled: true
//ms length of page change
property int pageChangeAnimationDuration: 250
property int pageFadeAnimationDuration: 250
property int slowAnimationDuration: 750
property int normalAnimationDuration: 250
property int fastAnimationDuration: 125
}
} }
+207 -48
View File
@@ -23,13 +23,29 @@
*/ */
// pragma ComponentBehavior: Bound // pragma ComponentBehavior: Bound
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Dialogs import QtQuick.Dialogs
import QtQuick.Layouts import QtQuick.Layouts
//import org.kde.kirigami as Kirigami
//import org.kde.plasma.core as PlasmaCore
import QtCore
import Qt.labs.folderlistmodel 2.15 import Qt.labs.folderlistmodel 2.15
import KomplexHub import KomplexHub
@@ -52,13 +68,9 @@ Item
id: root id: root
property alias cfg_pauseMode: pauseModeCombo.currentIndex property alias cfg_pauseMode: pauseModeCombo.currentIndex
property alias cfg_isPaused: runningCombo.checked
property alias cfg_shaderSpeed: speedSlider.value property alias cfg_shaderSpeed: speedSlider.value
property alias cfg_mouseSpeedBias: mouseBiasSlider.value property alias cfg_mouseSpeedBias: mouseBiasSlider.value
property bool cfg_infoPlasma6Preview_dismissed property alias cfg_enableMouseTracking: mouseTrackingCheckbox.checked
property bool cfg_warningResources_dismissed
property bool cfg_emergencyHelp_dismissed
property bool cfg_infoiChannelSettings_dismissed
property alias cfg_checkActiveScreen: activeScreenOnlyCheckbox.checked property alias cfg_checkActiveScreen: activeScreenOnlyCheckbox.checked
property alias cfg_excludeWindows: excludeWindows.windows property alias cfg_excludeWindows: excludeWindows.windows
property alias cfg_running: runningCombo.checked property alias cfg_running: runningCombo.checked
@@ -77,6 +89,9 @@ Item
property bool enableMouseTracking: true property bool enableMouseTracking: true
property real mouseTrackingBias: 0.5 property real mouseTrackingBias: 0.5
property bool updated: updates.length > 0
property var updates: []
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
color: "transparent" color: "transparent"
@@ -123,19 +138,17 @@ Item
currentIndex: manager.shaderPackIndex currentIndex: manager.shaderPackIndex
displayText: currentIndex === -1 ? "Custom File" : currentText.replace("_", " ").charAt(0).toUpperCase() + currentText.replace("_", " ").slice(1) displayText: currentIndex === -1 ? "Custom File" : currentText.replace("_", " ").charAt(0).toUpperCase() + currentText.replace("_", " ").slice(1)
// onCurrentTextChanged: onCurrentIndexChanged:
// { {
// root.cfg_shader_package_index = currentIndex; if(updates.indexOf("wallpaper") >= 0 && value === manager.shaderPackIndex)
{
// if (root.cfg_shader_package_index === -1) updates.slice(updates.indexOf("wallpaper"), 1)
// return; }
else
// var source = currentText {
// shaderPackModel.loadMetadata(source) updates.push("wallpaper")
// root.cfg_shader_package = "file://" + shaderPackModel.path(source) }
// } }
} }
Item { Layout.preferredHeight: Constants.smallMargin } Item { Layout.preferredHeight: Constants.smallMargin }
@@ -174,6 +187,15 @@ Item
onEditingFinished: () => onEditingFinished: () =>
{ {
value = parseInt(text) value = parseInt(text)
if(updates.indexOf("resolutionX") >= 0 && value === manager.resolutionX)
{
updates.slice(updates.indexOf("resolutionX"), 1)
}
else
{
updates.push("resolutionX")
}
} }
Keys.onPressed: (event) => Keys.onPressed: (event) =>
@@ -196,7 +218,8 @@ Item
} }
} }
Text { Text
{
text: qsTr("Y") text: qsTr("Y")
font: Constants.h3Font font: Constants.h3Font
color: palette.text color: palette.text
@@ -205,7 +228,8 @@ Item
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} }
TextField { TextField
{
property int value: manager.resolutionY property int value: manager.resolutionY
Layout.preferredHeight: 36 Layout.preferredHeight: 36
@@ -219,6 +243,15 @@ Item
onEditingFinished: () => onEditingFinished: () =>
{ {
value = parseInt(text) value = parseInt(text)
if(updates.indexOf("resolutionY") >= 0 && value === manager.resolutionY)
{
updates.slice(updates.indexOf("resolutionY"), 1)
}
else
{
updates.push("resolutionY")
}
} }
Keys.onPressed: (event) => Keys.onPressed: (event) =>
@@ -248,7 +281,8 @@ Item
{ {
Layout.fillWidth: true Layout.fillWidth: true
Text { Text
{
text: qsTr("Frame Rate") text: qsTr("Frame Rate")
font: Constants.h3Font font: Constants.h3Font
color: palette.text color: palette.text
@@ -263,7 +297,19 @@ Item
from: 1 from: 1
to: 60 to: 60
stepSize: 0.01 stepSize: 0.01
onValueChanged: frameRateField.text = String(value.toFixed(2)); onValueChanged:
{
frameRateField.text = String(value.toFixed(2));
if(updates.indexOf("frameRate") >= 0 && value === manager.targetFramerate)
{
updates.slice(updates.indexOf("frameRate"), 1)
}
else
{
updates.push("frameRate")
}
}
Component.onCompleted: () => { Component.onCompleted: () => {
value = manager.targetFramerate value = manager.targetFramerate
@@ -313,7 +359,8 @@ Item
id: speedLayout id: speedLayout
Layout.fillWidth: true Layout.fillWidth: true
Text { Text
{
text: qsTr("Shader Speed") text: qsTr("Shader Speed")
font: Constants.h3Font font: Constants.h3Font
color: palette.text color: palette.text
@@ -329,9 +376,22 @@ Item
from: -4.0 from: -4.0
to: 4.0 to: 4.0
stepSize: 0.01 stepSize: 0.01
onValueChanged: shaderSpeedField.text = String(value.toFixed(2)); onValueChanged:
{
if(updates.indexOf("shaderSpeed") >= 0 && value === manager.shaderSpeed)
{
updates.slice(updates.indexOf("shaderSpeed"), 1)
}
else
{
updates.push("shaderSpeed")
}
Component.onCompleted: () => { shaderSpeedField.text = String(value.toFixed(2));
}
Component.onCompleted: () =>
{
value = manager.shaderSpeed value = manager.shaderSpeed
} }
} }
@@ -414,7 +474,17 @@ Item
] ]
textRole: modelData textRole: modelData
//onCurrentIndexChanged: root.cfg_pauseMode = currentIndex onCurrentIndexChanged:
{
if(updates.indexOf("pauseMode") && currentIndex === manager.pauseMode)
{
updates.slice(updates.indexOf("pauseMode"), 1)
}
else
{
updates.push("pauseMode")
}
}
currentIndex: manager.pauseMode currentIndex: manager.pauseMode
} }
} }
@@ -434,7 +504,8 @@ Item
{ {
Layout.fillWidth: true Layout.fillWidth: true
Text { Text
{
text: qsTr("Excluded Windows") text: qsTr("Excluded Windows")
font: Constants.h3Font font: Constants.h3Font
color: palette.text color: palette.text
@@ -451,6 +522,15 @@ Item
onEditingFinished: () => onEditingFinished: () =>
{ {
windows = excludeWindows.text.trim().replace(/\s+/g, "").split(","); windows = excludeWindows.text.trim().replace(/\s+/g, "").split(",");
if(updates.indexOf("excludeWindows") >= 0 && windows === manager.excludedWindows)
{
updates.slice(updates.indexOf("excludeWindows"), 1)
}
else
{
updates.push("excludeWindows")
}
} }
ToolTip.visible: hovered ToolTip.visible: hovered
@@ -462,16 +542,27 @@ Item
CheckBox CheckBox
{ {
//Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", cfg_isPaused ? "Playing" : "Paused")
id: runningCombo id: runningCombo
checked: manager.running checked: manager.running
text: qsTr("Shader Is Running") text: qsTr("Shader Is Running")
onCheckedChanged:
{
if(updates.indexOf("shaderRunning") > 0 && checked === manager.running)
{
updates.slice(updates.indexOf("shaderRunning"), 1)
}
else
{
updates.push("shaderRunning")
}
}
} }
Item { Layout.preferredHeight: Constants.largeMargin } Item { Layout.preferredHeight: Constants.largeMargin }
Text { Text
{
text: qsTr("Mouse Tracking") text: qsTr("Mouse Tracking")
font: Constants.h2Font font: Constants.h2Font
color: palette.text color: palette.text
@@ -483,14 +574,15 @@ Item
{ {
Layout.fillWidth: true Layout.fillWidth: true
Text { Text
text: qsTr("Mouse Tracking Bias") {
text: qsTr("Mouse Speed Bias")
font: Constants.h3Font font: Constants.h3Font
color: palette.text color: palette.text
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
Layout.preferredHeight: 36 Layout.preferredHeight: 36
} }
//Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Mouse bias:")
Slider Slider
{ {
id: mouseBiasSlider id: mouseBiasSlider
@@ -503,6 +595,15 @@ Item
onValueChanged: () => onValueChanged: () =>
{ {
mouseBiasField.text = String(value.toFixed(2)); mouseBiasField.text = String(value.toFixed(2));
if(updates.indexOf("mouseSpeedBias") >= 0 && value === manager.mouseTrackingBias)
{
updates.slice(updates.indexOf("mouseSpeedBias"), 1)
}
else
{
updates.push("mouseSpeedBias")
}
} }
} }
TextField TextField
@@ -549,19 +650,29 @@ Item
CheckBox CheckBox
{ {
//Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", cfg_isPaused ? "Playing" : "Paused")
id: mouseTrackingCheckbox id: mouseTrackingCheckbox
checked: manager.mouseTrackingEnabled checked: manager.mouseTrackingEnabled
text: qsTr("Mouse Tracking Enabled") text: qsTr("Mouse Tracking Enabled")
onCheckedChanged:
{
if(updates.indexOf("mouseEnabled") >= 0 && currentIndex === manager.mouseTrackingEnabled)
{
updates.slice(updates.indexOf("mouseEnabled"), 1)
}
else
{
updates.push("mouseEnabled")
}
}
} }
// Button // Button
// { // {
// visible: navBar.currentIndex === 2 // visible: navBar.currentIndex === 2
// id: kofiButton // id: kofiButton
// Layout.preferredWidth: Kirigami.Units.gridUnit * 5 // Layout.preferredWidth: 4 * 5
// Layout.preferredHeight: Kirigami.Units.gridUnit * 3 // Layout.preferredHeight: 4 * 3
// contentItem: RowLayout // contentItem: RowLayout
// { // {
@@ -598,10 +709,9 @@ Item
RowLayout RowLayout
{ {
//Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Author:")
Text Text
{ {
Layout.preferredWidth: Kirigami.Units.gridUnit * 11 Layout.preferredWidth: 4 * 11
text: shaderPackModel.metadata.author text: shaderPackModel.metadata.author
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
color: palette.text color: palette.text
@@ -610,10 +720,9 @@ Item
RowLayout RowLayout
{ {
//Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Description:")
Text Text
{ {
Layout.preferredWidth: Kirigami.Units.gridUnit * 16 Layout.preferredWidth: 4 * 16
text: shaderPackModel.metadata.description text: shaderPackModel.metadata.description
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
color: palette.text color: palette.text
@@ -625,10 +734,9 @@ Item
RowLayout RowLayout
{ {
//Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "License:")
Text Text
{ {
Layout.preferredWidth: Kirigami.Units.gridUnit * 11 Layout.preferredWidth: 4 * 11
text: shaderPackModel.metadata.license text: shaderPackModel.metadata.license
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
color: palette.text color: palette.text
@@ -637,10 +745,9 @@ Item
RowLayout RowLayout
{ {
//Kirigami.FormData.label: i18nd("com.github.digitalartifex.komplex", "Version:")
Text Text
{ {
Layout.preferredWidth: Kirigami.Units.gridUnit * 11 Layout.preferredWidth: 4 * 11
text: shaderPackModel.metadata.version text: shaderPackModel.metadata.version
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
color: palette.text color: palette.text
@@ -649,4 +756,56 @@ Item
} }
} }
} }
Settings
{
id: settings
property bool animationsEnabled: true
//ms length of page change
property int pageChangeAnimationDuration: 250
property int pageFadeAnimationDuration: 250
property int slowAnimationDuration: 750
property int normalAnimationDuration: 250
property int fastAnimationDuration: 125
}
function apply()
{
if(updated)
{
manager.pauseMode = cfg_pauseMode
manager.shaderSpeed = cfg_shaderSpeed
manager.mouseTrackingBias = cfg_mouseSpeedBias
manager.mouseTrackingEnabled = cfg_enableMouseTracking
manager.onlyCheckActiveScreen = cfg_checkActiveScreen
manager.excludedWindows = cfg_excludeWindows
manager.running = cfg_running
manager.resolutionX = cfg_resolution_x
manager.resolutionY = cfg_resolution_y
manager.targetFramerate = cfg_framerate_limit
updates.splice(0, updates.length)
}
}
function reset()
{
if(updated)
{
cfg_pauseMode = manager.pauseMode
cfg_shaderSpeed = manager.shaderSpeed
cfg_mouseSpeedBias = manager.mouseTrackingBias
cfg_enableMouseTracking = manager.mouseTrackingEnabled
cfg_checkActiveScreen = manager.onlyCheckActiveScreen
cfg_excludeWindows = manager.excludedWindows
cfg_running = manager.running
cfg_resolution_x = manager.resolutionX
cfg_resolution_y = manager.resolutionY
cfg_framerate_limit = manager.targetFramerate
updates.splice(0, updates.length)
}
}
} }
+19
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
+19
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
+19 -6
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -51,12 +70,6 @@ Item
} }
} }
} }
SquareButton
{
Layout.preferredWidth: 186
Layout.fillHeight: true
text: qsTr("Set Wallpaper")
}
} }
VerticalSpacer {} VerticalSpacer {}
+51
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -164,6 +183,14 @@ Item
} }
} }
Behavior on opacity
{
NumberAnimation
{
duration: 250
}
}
states: states:
[ [
State State
@@ -294,6 +321,14 @@ Item
thumbnail: rootItem.thumbnail thumbnail: rootItem.thumbnail
opacity: 0 opacity: 0
visible: opacity > 0.01 visible: opacity > 0.01
Behavior on opacity
{
NumberAnimation
{
duration: 250
}
}
} }
CompletedView CompletedView
@@ -304,6 +339,14 @@ Item
opacity: 0 opacity: 0
visible: opacity > 0.01 visible: opacity > 0.01
manager: downloadManager manager: downloadManager
Behavior on opacity
{
NumberAnimation
{
duration: 250
}
}
} }
ErrorView ErrorView
@@ -314,6 +357,14 @@ Item
opacity: 0 opacity: 0
visible: opacity > 0.01 visible: opacity > 0.01
manager: downloadManager manager: downloadManager
Behavior on opacity
{
NumberAnimation
{
duration: 250
}
}
} }
function download() function download()
+112
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -148,6 +167,15 @@ Item
} }
} }
} }
Behavior on opacity
{
NumberAnimation
{
duration: 250
}
}
states: states:
[ [
State State
@@ -180,6 +208,64 @@ Item
} }
}, },
State State
{
name: "compiling"
when: downloadManager.state === DownloadManager.Compiling
PropertyChanges
{
target: pageView
opacity: 0
}
PropertyChanges
{
target: downloadView
opacity: 1
}
PropertyChanges
{
target: completedView
opacity: 0
}
PropertyChanges
{
target: errorView
opacity: 0
}
},
State
{
name: "installing"
when: downloadManager.state === DownloadManager.Installing
PropertyChanges
{
target: pageView
opacity: 0
}
PropertyChanges
{
target: downloadView
opacity: 1
}
PropertyChanges
{
target: completedView
opacity: 0
}
PropertyChanges
{
target: errorView
opacity: 0
}
},
State
{ {
name: "complete" name: "complete"
when: downloadManager.state === DownloadManager.Complete when: downloadManager.state === DownloadManager.Complete
@@ -278,6 +364,14 @@ Item
thumbnail: rootItem.thumbnail thumbnail: rootItem.thumbnail
opacity: 0 opacity: 0
visible: opacity > 0.01 visible: opacity > 0.01
Behavior on opacity
{
NumberAnimation
{
duration: 250
}
}
} }
CompletedView CompletedView
@@ -288,6 +382,14 @@ Item
opacity: 0 opacity: 0
visible: opacity > 0.01 visible: opacity > 0.01
manager: downloadManager manager: downloadManager
Behavior on opacity
{
NumberAnimation
{
duration: 250
}
}
} }
ErrorView ErrorView
@@ -298,10 +400,20 @@ Item
opacity: 0 opacity: 0
visible: opacity > 0.01 visible: opacity > 0.01
manager: downloadManager manager: downloadManager
Behavior on opacity
{
NumberAnimation
{
duration: 250
}
}
} }
function download() function download()
{ {
downloadManager.downloadPack(uuid) downloadManager.downloadPack(uuid)
} }
Component.onCompleted: () => downloadManager.reset()
} }
+51
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -154,6 +173,14 @@ Item
} }
} }
Behavior on opacity
{
NumberAnimation
{
duration: 250
}
}
states: states:
[ [
State State
@@ -284,6 +311,14 @@ Item
thumbnail: rootItem.thumbnail thumbnail: rootItem.thumbnail
opacity: 0 opacity: 0
visible: opacity > 0.01 visible: opacity > 0.01
Behavior on opacity
{
NumberAnimation
{
duration: 250
}
}
} }
CompletedView CompletedView
@@ -294,6 +329,14 @@ Item
opacity: 0 opacity: 0
visible: opacity > 0.01 visible: opacity > 0.01
manager: downloadManager manager: downloadManager
Behavior on opacity
{
NumberAnimation
{
duration: 250
}
}
} }
ErrorView ErrorView
@@ -304,6 +347,14 @@ Item
opacity: 0 opacity: 0
visible: opacity > 0.01 visible: opacity > 0.01
manager: downloadManager manager: downloadManager
Behavior on opacity
{
NumberAnimation
{
duration: 250
}
}
} }
function download() function download()
+4 -3
View File
@@ -13,10 +13,11 @@ qt6_add_qml_module(KomplexHubModule
RESOURCE_PREFIX "/qt/qml" RESOURCE_PREFIX "/qt/qml"
QML_FILES QML_FILES
"Constants.qml" "Constants.qml"
"EventListModel.qml"
"EventListSimulator.qml"
"WallpaperModelData.qml"
) )
set_target_properties(KomplexHubModule PROPERTIES VERSION "1.0")
add_subdirectory("Controls") add_subdirectory("Controls")
add_subdirectory("Kero") add_subdirectory("Kero")
+20 -5
View File
@@ -1,8 +1,27 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
pragma Singleton pragma Singleton
import QtQuick import QtQuick
import QtQuick.Studio.Application import QtQuick.Studio.Application
QtObject { QtObject
{
readonly property int width: 1920 readonly property int width: 1920
readonly property int height: 1080 readonly property int height: 1080
@@ -62,8 +81,4 @@ QtObject {
readonly property int slowAnimationDuration: 750 readonly property int slowAnimationDuration: 750
readonly property int normalAnimationDuration: 250 readonly property int normalAnimationDuration: 250
readonly property int fastAnimationDuration: 125 readonly property int fastAnimationDuration: 125
property StudioApplication application: StudioApplication {
fontPath: Qt.resolvedUrl("../KomplexHubContent/" + relativeFontDirectory)
}
} }
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Effects import QtQuick.Effects
+3 -2
View File
@@ -1,8 +1,8 @@
### This file is automatically generated by Qt Design Studio. ### This file is automatically generated by Qt Design Studio.
### Do not change ### Do not change
qt_add_library(KomplexHubModule_Controls STATIC) qt_add_library(KomplexHubControls STATIC)
qt6_add_qml_module(KomplexHubModule_Controls qt6_add_qml_module(KomplexHubControls
URI "KomplexHub.Controls" URI "KomplexHub.Controls"
VERSION 1.0 VERSION 1.0
RESOURCE_PREFIX "/qt/qml" RESOURCE_PREFIX "/qt/qml"
@@ -22,3 +22,4 @@ qt6_add_qml_module(KomplexHubModule_Controls
"BackgroundImage.qml" "BackgroundImage.qml"
) )
#set_target_properties(KomplexHubControls PROPERTIES VERSION "1.0")
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
+19
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
+19
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
+18 -5
View File
@@ -1,9 +1,22 @@
/* /*
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only. * Komplex Wallpaper Engine
It is supposed to be strictly declarative and only uses a subset of QML. If you edit * Copyright (C) 2026 @DigitalArtifex
this file manually, you might introduce QML code that is not supported by Qt Design Studio. * https://digitalartifex.dev - https://github.com/DigitalArtifex
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. *
*/ * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
+19
View File
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Shapes import QtQuick.Shapes
import QtQuick.Effects import QtQuick.Effects
@@ -1,3 +1,22 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtCore
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
-12
View File
@@ -1,12 +0,0 @@
import QtQuick
ListModel {
id: eventListModel
ListElement {
eventId: "enterPressed"
eventDescription: "Emitted when pressing the enter button"
shortcut: "Return"
parameters: "Enter"
}
}
-22
View File
@@ -1,22 +0,0 @@
import QtQuick
import QtQuick.Studio.EventSimulator
import QtQuick.Studio.EventSystem
QtObject {
id: simulator
property bool active: true
property Timer __timer: Timer {
id: timer
interval: 100
onTriggered: {
EventSimulator.show()
}
}
Component.onCompleted: {
EventSystem.init(Qt.resolvedUrl("EventListModel.qml"))
if (simulator.active)
timer.start()
}
}
+3 -2
View File
@@ -1,5 +1,5 @@
qt_add_library(KomplexHubModule_Kero STATIC) qt_add_library(KomplexHubKero STATIC)
qt6_add_qml_module(KomplexHubModule_Kero qt6_add_qml_module(KomplexHubKero
URI "KomplexHub.Kero" URI "KomplexHub.Kero"
VERSION 1.0 VERSION 1.0
RESOURCE_PREFIX "/qt/qml" RESOURCE_PREFIX "/qt/qml"
@@ -14,3 +14,4 @@ qt6_add_qml_module(KomplexHubModule_Kero
"KeroHeader.qml" "KeroHeader.qml"
"KeroSuccessAvatar.qml" "KeroSuccessAvatar.qml"
) )
#set_target_properties(KomplexHubKero PROPERTIES VERSION "1.0")
@@ -1,3 +1,21 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -1,3 +1,21 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
+18
View File
@@ -1,3 +1,21 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
+18
View File
@@ -1,3 +1,21 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtQuick import QtQuick
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
import QtQuick.Layouts import QtQuick.Layouts
+18
View File
@@ -1,3 +1,21 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -1,3 +1,21 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -1,3 +1,21 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -1,3 +1,21 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
+19 -1
View File
@@ -1,3 +1,21 @@
/*
* Komplex Wallpaper Engine
* Copyright (C) 2026 @DigitalArtifex
* https://digitalartifex.dev - https://github.com/DigitalArtifex
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
@@ -6,7 +24,7 @@ import KomplexHub
Item { Item {
property string title: qsTr("Warning") property string title: qsTr("Warning")
property string description: qsTr("Kero noticed there might be an issue") property string description: qsTr("Kero noticed there might be an issue")
property color color: palette.window property color color: "transparent"
id: keroWarningAvatarRoot id: keroWarningAvatarRoot
-67
View File
@@ -1,67 +0,0 @@
import QtQuick
import QtQuick.Controls
ListModel {
ListElement {
author: "Wizmart"
name: "Some cool name 1"
description: "This is not a real wallpaper or person"
thumbnail: ""
uuid: "{aafd-311-afaa}"
url: ""
}
ListElement {
author: "Wizmart"
name: "Some cool name 2"
description: "This is not a real wallpaper or person"
thumbnail: ""
uuid: "{aafd-311-afaa}"
url: ""
}
ListElement {
author: "Wizmart"
name: "Some cool name 3"
description: "This is not a real wallpaper or person"
thumbnail: ""
uuid: "{aafd-311-afaa}"
url: ""
}
ListElement {
author: "Wizmart"
name: "Some cool name 4"
description: "This is not a real wallpaper or person"
thumbnail: ""
uuid: "{aafd-311-afaa}"
url: ""
}
ListElement {
author: "Wizmart"
name: "Some cool name 5"
description: "This is not a real wallpaper or person"
thumbnail: ""
uuid: "{aafd-311-afaa}"
url: ""
}
ListElement {
author: "Wizmart"
name: "Some cool name 6"
description: "This is not a real wallpaper or person"
thumbnail: ""
uuid: "{aafd-311-afaa}"
url: ""
}
ListElement {
author: "Wizmart"
name: "Some cool name 7"
description: "This is not a real wallpaper or person"
thumbnail: ""
uuid: "{aafd-311-afaa}"
url: ""
}
}
+34 -2
View File
@@ -1,8 +1,34 @@
find_package(
Qt6
REQUIRED COMPONENTS
Core
Gui
GuiPrivate
Widgets
Qml
Quick
QuickControls2
QuickTimeline
ShaderTools
ShaderToolsPrivate
Concurrent
)
find_package(
OpenGL REQUIRED COMPONENTS OpenGL
)
find_package(
Vulkan REQUIRED COMPONENTS glslang SPIRV-Tools
)
add_library( add_library(
KomplexHubPlugin KomplexHubPlugin
STATIC STATIC
) )
set_target_properties(KomplexHubPlugin PROPERTIES VERSION "1.0")
qt_add_qml_module( qt_add_qml_module(
KomplexHubPlugin KomplexHubPlugin
URI URI
@@ -62,6 +88,7 @@ qt_add_qml_module(
common/qwallet.cpp common/qwallet.cpp
usermodel.h usermodel.h
usermodel.cpp usermodel.cpp
SOURCES
) )
target_compile_definitions( target_compile_definitions(
@@ -73,8 +100,13 @@ target_compile_definitions(
add_subdirectory(3rdparty/qtkeychain) add_subdirectory(3rdparty/qtkeychain)
target_link_libraries(KomplexHubPlugin PRIVATE target_link_libraries(KomplexHubPlugin PRIVATE
Qt${QT_VERSION_MAJOR}::Core Qt6::Core
Qt${QT_VERSION_MAJOR}::Gui Qt6::Concurrent
Qt6::Gui
Qt6::GuiPrivate
Qt6::ShaderTools
Qt6::ShaderToolsPrivate
Vulkan::Vulkan
qt6keychain qt6keychain
) )
+178 -17
View File
@@ -19,36 +19,197 @@
#ifndef EXCEPTIONS_H #ifndef EXCEPTIONS_H
#define EXCEPTIONS_H #define EXCEPTIONS_H
#include <QString> #include <QString>
#include <exception> #include <string>
#include <filesystem>
#include "komplex_global.h" #include "komplex_global.h"
struct KOMPLEX_EXPORT Exception : std::exception struct KOMPLEX_EXPORT network_exception : std::ios_base::failure
{ {
explicit Exception(const QString &message, quint16 errorCode = 0) network_exception(const std::string &message, const std::string &details, const std::error_code &code) :
: std::exception(), message(message), errorCode(errorCode){} details(details),
std::ios_base::failure(message, code) { }
const QString message; network_exception(const std::string &message, const std::error_code &code) :
const quint16 errorCode; std::ios_base::failure(message, code) { }
network_exception(const QString &message, const QString &details, const std::error_code &code) :
details(details.toStdString()),
std::ios_base::failure(message.toStdString(), code) { }
network_exception(const QString &message, const int code = errno) :
std::ios_base::failure
(
message.toStdString(),
std::error_code
(
code,
std::system_category()
)
) { }
const std::string details;
}; };
struct KOMPLEX_EXPORT NetworkException : Exception struct KOMPLEX_EXPORT file_exception : std::filesystem::filesystem_error
{ {
NetworkException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {} file_exception(const std::string &message, const std::string &details, const std::error_code &code) :
details(details),
std::filesystem::filesystem_error(message, code) { }
file_exception(const std::string &message, const std::error_code &code) :
std::filesystem::filesystem_error(message, code) { }
file_exception(const std::string &message, const int code = errno) :
std::filesystem::filesystem_error
(
message,
std::error_code
(
code,
std::system_category()
)
) { }
file_exception(const std::string &message, const std::string &details, const int code = errno) :
details(details),
std::filesystem::filesystem_error
(
message,
std::error_code
(
code,
std::system_category()
)
) { }
const std::string details;
}; };
struct KOMPLEX_EXPORT FileException : Exception
struct KOMPLEX_EXPORT sql_exception : std::ios_base::failure
{ {
FileException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {} sql_exception(const std::string &message, const std::string &details, const std::error_code &code) :
details(details),
std::ios_base::failure(message, code) { }
sql_exception(const std::string &message, const std::error_code &code) :
std::ios_base::failure(message, code) { }
sql_exception(const std::string &message, const int code = errno) :
std::ios_base::failure
(
message,
std::error_code
(
code,
std::system_category()
)
) { }
const std::string details;
}; };
struct KOMPLEX_EXPORT SqlException : Exception
struct KOMPLEX_EXPORT wallet_exception : std::ios_base::failure
{ {
SqlException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {} wallet_exception(const std::string &message, const std::string &details, const std::error_code &code) :
details(details),
std::ios_base::failure(message, code) { }
wallet_exception(const std::string &message, const std::error_code &code) :
std::ios_base::failure(message, code) { }
wallet_exception(const std::string &message, const std::string &details, const int code = errno) :
details(details),
std::ios_base::failure
(
message,
std::error_code
(
code,
std::system_category()
)
) { }
wallet_exception(const std::string &message, const int code = errno) :
std::ios_base::failure
(
message,
std::error_code
(
code,
std::system_category()
)
) { }
const std::string details;
}; };
struct KOMPLEX_EXPORT WalletException : Exception
struct KOMPLEX_EXPORT process_exception : std::runtime_error
{ {
WalletException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {} process_exception(const std::string &message, const std::string &details, const std::error_code &code) :
details(details),
code(code),
std::runtime_error(message) { }
process_exception(const std::string &message, const std::error_code &code) :
code(code),
std::runtime_error(message) { }
process_exception(const std::string &message, const int code = errno) :
code
(
std::error_code
(
code,
std::system_category()
)
),
std::runtime_error
(
message
) { }
process_exception(const std::string &message, const std::string &details, const int code = errno) :
details(details),
code
(
std::error_code
(
code,
std::system_category()
)
),
std::runtime_error (message) { }
const std::string details;
const std::error_code code;
}; };
struct KOMPLEX_EXPORT ShaderCompilerException : Exception
namespace shader
{ {
ShaderCompilerException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {} struct KOMPLEX_EXPORT logic_error : std::logic_error
}; {
logic_error(const std::string &message, const std::string &details, const std::error_code &code) :
details(details),
code(code),
std::logic_error(message) { }
logic_error(const std::string &message, const std::error_code &code) :
code(code),
std::logic_error(message) { }
logic_error(const std::string &message, const std::string &details = {}, const int code = errno) :
code
(
std::error_code
(
code,
std::system_category()
)
),
std::logic_error(message) { }
const std::string details;
const std::error_code code;
};
}
#endif // EXCEPTIONS_H #endif // EXCEPTIONS_H
+13 -4
View File
@@ -1,5 +1,6 @@
#include "qwallet.h" #include "qwallet.h"
#include "../3rdparty/qtkeychain/qtkeychain/keychain.h" #include "../3rdparty/qtkeychain/qtkeychain/keychain.h"
#include "common/exceptions.h"
auto QWallet::read(const QString &service, const QString &key) const -> QFuture<QByteArray> auto QWallet::read(const QString &service, const QString &key) const -> QFuture<QByteArray>
{ {
@@ -29,7 +30,11 @@ auto QWallet::read(const QString &service, const QString &key) const -> QFuture<
else else
{ {
m_errorString = qPrintable(j->errorString()); m_errorString = qPrintable(j->errorString());
throw std::exception(); throw wallet_exception
(
QStringLiteral("Wallet read error").toStdString(),
errorString().toStdString()
);
} }
loop.quit(); loop.quit();
@@ -65,11 +70,15 @@ auto QWallet::write(const QString &service, const QString &key, const QByteArray
this, this,
[this, key, &loop, &success](QKeychain::Job *job) [this, key, &loop, &success](QKeychain::Job *job)
{ {
auto j = static_cast<QKeychain::ReadPasswordJob*>(job); auto j = static_cast<QKeychain::WritePasswordJob*>(job);
if (j->error() != QKeychain::NoError) if (j->error() != QKeychain::NoError)
{ {
setErrorString(qPrintable(j->errorString())); setErrorString(qPrintable(j->errorString()));
throw std::exception(); throw wallet_exception
(
QStringLiteral("Wallet write error").toStdString(),
errorString().toStdString()
);
} }
loop.quit(); loop.quit();
@@ -102,7 +111,7 @@ auto QWallet::remove(const QString &service, const QString &key) -> QFuture<void
this, this,
[this, key, &loop, &value](QKeychain::Job *job) [this, key, &loop, &value](QKeychain::Job *job)
{ {
auto j = static_cast<QKeychain::ReadPasswordJob*>(job); auto j = static_cast<QKeychain::DeletePasswordJob*>(job);
if (j->error() != QKeychain::NoError) if (j->error() != QKeychain::NoError)
{ {
m_errorString = qPrintable(j->errorString()); m_errorString = qPrintable(j->errorString());
+149 -58
View File
@@ -105,6 +105,7 @@ auto DownloadManager::downloadImage(const QString &author, const QString &author
metadata.setDescription(description); metadata.setDescription(description);
metadata.setName(QStringLiteral("Pexels Image (%1)").arg(id)); metadata.setName(QStringLiteral("Pexels Image (%1)").arg(id));
metadata.setSource(QStringLiteral("./images/%1").arg(result.fileName())); metadata.setSource(QStringLiteral("./images/%1").arg(result.fileName()));
metadata.setId(id);
QUrl packUri QUrl packUri
( (
@@ -129,7 +130,7 @@ auto DownloadManager::downloadImage(const QString &author, const QString &author
if(!packDirectory.mkpath(packUri.toLocalFile())) if(!packDirectory.mkpath(packUri.toLocalFile()))
{ {
throw FileException(QStringLiteral("Could not create directory")); throw file_exception(QStringLiteral("Could not create directory").toStdString());
} }
packDirectory.mkdir(QStringLiteral("images")); packDirectory.mkdir(QStringLiteral("images"));
@@ -147,7 +148,7 @@ auto DownloadManager::downloadImage(const QString &author, const QString &author
if(!packFile.open(QFile::ReadWrite)) if(!packFile.open(QFile::ReadWrite))
{ {
setError(QStringLiteral("File Error"), packFile.errorString()); setError(QStringLiteral("File Error"), packFile.errorString());
throw FileException(packFile.errorString()); throw file_exception(packFile.errorString().toStdString());
} }
QByteArray data = metadata.json().toJson(QJsonDocument::Indented); QByteArray data = metadata.json().toJson(QJsonDocument::Indented);
@@ -155,7 +156,7 @@ auto DownloadManager::downloadImage(const QString &author, const QString &author
if(packFile.write(data) != data.length()) if(packFile.write(data) != data.length())
{ {
setError(QStringLiteral("File Error"), packFile.errorString()); setError(QStringLiteral("File Error"), packFile.errorString());
throw FileException(packFile.errorString()); throw file_exception(packFile.errorString().toStdString());
} }
packFile.close(); packFile.close();
@@ -187,18 +188,26 @@ auto DownloadManager::downloadImage(const QString &author, const QString &author
) )
.onFailed .onFailed
( (
[this] (const NetworkException &e) [this] (const std::filesystem::filesystem_error &e)
{ {
reset(); reset();
setError(QStringLiteral("Network Exception %1").arg(QString::number(e.errorCode)), e.message); setError(QStringLiteral("Network Exception %1").arg(QString::number(e.code().value())), e.what());
} }
) )
.onFailed .onFailed
( (
[this] (const FileException &e) [this] (const std::logic_error &e)
{ {
reset(); reset();
setError(QStringLiteral("File Exception %1").arg(QString::number(e.errorCode)), e.message); setError(QStringLiteral("Logic Exception %1"), e.what());
}
)
.onFailed
(
[this] (const std::exception &e)
{
reset();
setError(QStringLiteral("Logic Exception %1"), e.what());
} }
) )
.onFailed .onFailed
@@ -230,11 +239,14 @@ auto DownloadManager::downloadVideo(const QString &author, const QString &author
( (
[this, author, id](QUrl result) -> QUrl [this, author, id](QUrl result) -> QUrl
{ {
setState(Installing);
ShaderPack metadata; ShaderPack metadata;
metadata.setAuthor(author); metadata.setAuthor(author);
metadata.setType(ShaderPack::Video); metadata.setType(ShaderPack::Video);
metadata.setName(QStringLiteral("Pexels Video (%1)").arg(id)); metadata.setName(QStringLiteral("Pexels Video (%1)").arg(id));
metadata.setSource(QStringLiteral("./videos/%1").arg(result.fileName())); metadata.setSource(QStringLiteral("./videos/%1").arg(result.fileName()));
metadata.setId(id);
QUrl packUri QUrl packUri
( (
@@ -272,7 +284,7 @@ auto DownloadManager::downloadVideo(const QString &author, const QString &author
if(!packFile.open(QFile::ReadWrite)) if(!packFile.open(QFile::ReadWrite))
{ {
setError(QStringLiteral("File Error"), packFile.errorString()); setError(QStringLiteral("File Error"), packFile.errorString());
throw FileException(packFile.errorString()); throw file_exception(packFile.errorString().toStdString());
} }
QByteArray data = metadata.json().toJson(QJsonDocument::Compact); QByteArray data = metadata.json().toJson(QJsonDocument::Compact);
@@ -280,7 +292,7 @@ auto DownloadManager::downloadVideo(const QString &author, const QString &author
if(packFile.write(data) != data.length()) if(packFile.write(data) != data.length())
{ {
setError(QStringLiteral("File Error"), packFile.errorString()); setError(QStringLiteral("File Error"), packFile.errorString());
throw FileException(packFile.errorString()); throw file_exception(packFile.errorString().toStdString());
} }
packFile.close(); packFile.close();
@@ -312,18 +324,26 @@ auto DownloadManager::downloadVideo(const QString &author, const QString &author
) )
.onFailed .onFailed
( (
[this] (const NetworkException &e) [this] (const std::filesystem::filesystem_error &e)
{ {
reset(); reset();
setError(QStringLiteral("Network Exception %1").arg(QString::number(e.errorCode)), e.message); setError(QStringLiteral("Network Exception %1").arg(QString::number(e.code().value())), e.what());
} }
) )
.onFailed .onFailed
( (
[this] (const FileException &e) [this] (const std::logic_error &e)
{ {
reset(); reset();
setError(QStringLiteral("File Exception %1").arg(QString::number(e.errorCode)), e.message); setError(QStringLiteral("Logic Exception %1"), e.what());
}
)
.onFailed
(
[this] (const std::exception &e)
{
reset();
setError(QStringLiteral("Logic Exception %1"), e.what());
} }
) )
.onFailed .onFailed
@@ -350,15 +370,18 @@ auto DownloadManager::downloadPack(const QString &id) -> void
QNetworkRequest request(downloadUrl); QNetworkRequest request(downloadUrl);
request.setRawHeader(QByteArray("uuid"), id.toUtf8()); request.setRawHeader(QByteArray("uuid"), id.toUtf8());
QString tempFile(QString("%1.tar.gz").arg(id));
setState(Downloading);
QFuture<QUrl> downloadUri = download(request, id, Post); QFuture<QUrl> downloadUri = download(request, id, Post, tempFile);
downloadUri downloadUri
.then .then
( (
[this](QUrl result) -> QUrl [this](QUrl result) -> QUrl
{ {
return m_compiler->process(result).result(); setState(Compiling);
return m_compiler->build(result);
} }
) )
.then .then
@@ -378,31 +401,44 @@ auto DownloadManager::downloadPack(const QString &id) -> void
) )
.onCanceled .onCanceled
( (
[this]() [this, tempFile]()
{ {
QFile::remove(QStringLiteral("/tmp/") + tempFile);
reset(); reset();
} }
) )
.onFailed .onFailed
( (
[this] (const NetworkException &e) [this, tempFile] (const std::filesystem::filesystem_error &e)
{ {
QFile::remove(QStringLiteral("/tmp/") + tempFile);
reset(); reset();
setError(QStringLiteral("Network Exception %1").arg(QString::number(e.errorCode)), e.message); setError(QStringLiteral("Network Exception %1").arg(QString::number(e.code().value())), e.what());
} }
) )
.onFailed .onFailed
( (
[this] (const FileException &e) [this, tempFile] (const shader::logic_error &e)
{ {
QFile::remove(QStringLiteral("/tmp/") + tempFile);
reset(); reset();
setError(QStringLiteral("File Exception %1").arg(QString::number(e.errorCode)), e.message); setError(e.what(), QString::fromStdString(e.details));
} }
) )
.onFailed .onFailed
( (
[this] () [this, tempFile] (const std::exception &e)
{ {
QFile::remove(QStringLiteral("/tmp/") + tempFile);
reset();
setError(QStringLiteral("Exception %1"), e.what());
}
)
.onFailed
(
[this, tempFile] ()
{
QFile::remove(QStringLiteral("/tmp/") + tempFile);
reset(); reset();
setError(QStringLiteral("Unknown Exception"), QString()); setError(QStringLiteral("Unknown Exception"), QString());
} }
@@ -496,14 +532,11 @@ auto DownloadManager::setDownloadProgress(qreal progress) -> void
auto DownloadManager::install(const QUrl &uri) noexcept(false) -> QUrl auto DownloadManager::install(const QUrl &uri) noexcept(false) -> QUrl
{ {
if(!uri.isLocalFile()) validateUri(uri);
{
throw FileException(QStringLiteral("URI is not a local file"));
}
QDir tempDirectory(uri.toLocalFile()); QDir tempDirectory(uri.toLocalFile());
QUrl installLocation = QStringLiteral("%1/.local/share/komplex/packs/%2").arg QUrl installLocation = QStringLiteral("file://%1/.local/share/komplex/packs/%2").arg
( (
QStandardPaths::writableLocation(QStandardPaths::HomeLocation), QStandardPaths::writableLocation(QStandardPaths::HomeLocation),
tempDirectory.dirName() tempDirectory.dirName()
@@ -525,43 +558,47 @@ auto DownloadManager::install(const QUrl &uri) noexcept(false) -> QUrl
if(!m_moveProcess.waitForStarted(3000)) if(!m_moveProcess.waitForStarted(3000))
{ {
qWarning() << QStringLiteral("Could not start copy process: %1").arg(m_moveProcess.readAllStandardError()); qWarning() << QStringLiteral("Could not start copy process: %1").arg(m_moveProcess.readAllStandardError());
throw FileException(QStringLiteral("Could not start install process")); throw file_exception(QStringLiteral("Could not start install process").toStdString());
} }
if(!m_moveProcess.waitForFinished()) if(!m_moveProcess.waitForFinished())
{ {
qWarning() << QStringLiteral("Copy process took longer than expected (>30s)"); qWarning() << QStringLiteral("Copy process took longer than expected (>30s)");
throw FileException(QStringLiteral("Install process took longer than expected (>30s)")); throw file_exception(QStringLiteral("Install process took longer than expected (>30s)").toStdString());
} }
return installLocation; return installLocation;
} }
auto DownloadManager::download(const QNetworkRequest &request, const QString &id, RequestType type) -> QFuture<QUrl> auto DownloadManager::download(const QNetworkRequest &request, const QString &id, RequestType type, const QString &filename) -> QFuture<QUrl>
{ {
return QtConcurrent::run return QtConcurrent::run
( (
[this, request, id, type]() -> QUrl [this, request, id, type, _filename = filename]() -> QUrl
{ {
QEventLoop loop; QEventLoop loop;
QString filename = id; QString filename = _filename;
if(filename.isEmpty()) if(filename.isEmpty() && !request.url().fileName().isEmpty())
{ {
filename = QUuid::createUuidV7().toString(); filename = request.url().fileName();
}
else if(filename.isEmpty())
{
filename = id;
} }
QUrl downloadUri = QStringLiteral("file://%1/%2").arg QUrl downloadUri = QStringLiteral("file://%1/%2").arg
( (
QStandardPaths::writableLocation(QStandardPaths::TempLocation), QStandardPaths::writableLocation(QStandardPaths::TempLocation),
request.url().fileName() filename
); );
auto manager = CoreServices::networkAccessManager().toStrongRef(); auto manager = CoreServices::networkAccessManager().toStrongRef();
if(manager == nullptr) if(manager == nullptr)
{ {
throw NetworkException throw network_exception
{ {
QStringLiteral("Network Manager reference has already been deleted") QStringLiteral("Network Manager reference has already been deleted")
}; };
@@ -571,20 +608,20 @@ auto DownloadManager::download(const QNetworkRequest &request, const QString &id
if(downloadFile.exists() && !downloadFile.remove()) if(downloadFile.exists() && !downloadFile.remove())
{ {
throw FileException(downloadFile.errorString()); throw file_exception(downloadFile.errorString().toStdString());
} }
QNetworkReply *reply = nullptr; QNetworkReply *reply = nullptr;
switch(type) switch(type)
{ {
case Post: case Post:
reply = manager->post(request, nullptr); reply = manager->post(request, nullptr);
break; break;
default: default:
case Get: case Get:
reply = manager->get(request, nullptr); reply = manager->get(request, nullptr);
break; break;
} }
QObject::connect QObject::connect
@@ -596,7 +633,7 @@ auto DownloadManager::download(const QNetworkRequest &request, const QString &id
{ {
loop.quit(); loop.quit();
throw NetworkException throw network_exception
( (
QStringLiteral("Network Error %1").arg QStringLiteral("Network Error %1").arg
( (
@@ -624,17 +661,34 @@ auto DownloadManager::download(const QNetworkRequest &request, const QString &id
reply, reply,
&QNetworkReply::readyRead, &QNetworkReply::readyRead,
this, this,
[this, downloadUri, reply]() [this, downloadUri]()
{ {
QMutexLocker locker(&m_fileMutex);
QFile downloadFile(downloadUri.toLocalFile()); QFile downloadFile(downloadUri.toLocalFile());
if(!downloadFile.open(QFile::ReadWrite | QFile::Append)) if(!downloadFile.open(QFile::ReadWrite | QFile::Append))
{ {
throw FileException(QStringLiteral("Could not open temp file location")); throw file_exception(QStringLiteral("Could not open temp file location").toStdString());
}
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
if(reply == nullptr)
{
throw std::system_error
{
std::error_code
(
ENOENT,
std::system_category()
),
QStringLiteral("Reply is not a qobject").toStdString()
};
} }
quint64 bytes = reply->bytesAvailable(); quint64 bytes = reply->bytesAvailable();
quint64 bytesWritten = downloadFile.write(reply->readAll()/*bytes)*/); QByteArray data = reply->readAll();
quint64 bytesWritten = downloadFile.write(data/*bytes)*/);
downloadFile.close(); downloadFile.close();
} }
@@ -660,29 +714,61 @@ auto DownloadManager::download(const QNetworkRequest &request, const QString &id
); );
} }
auto DownloadManager::validateUri(const QUrl &uri) noexcept(false) -> void
{
if(!uri.isValid() || !uri.isLocalFile())
{
throw std::filesystem::filesystem_error
(
QStringLiteral("URI %1 is not a local file uri").arg
(
uri.toString()
).toStdString(),
std::error_code
(
ENOENT,
std::system_category()
)
);
}
}
auto DownloadManager::readShaderToyEntry(const QUrl &uri) noexcept(false) -> ShaderToyEntry auto DownloadManager::readShaderToyEntry(const QUrl &uri) noexcept(false) -> ShaderToyEntry
{ {
if(!uri.isLocalFile()) validateUri(uri);
{
throw FileException(QStringLiteral("URI is not a local file"));
}
QDir packDir(uri.toLocalFile()); QDir packDir(uri.toLocalFile());
if(!packDir.exists(QStringLiteral("pack.json"))) if(!packDir.exists(QStringLiteral("pack.json")))
{ {
throw FileException(QStringLiteral("Pack file not found")); throw std::filesystem::filesystem_error
(
QStringLiteral("Pack file not found").arg
(
uri.toString()
).toStdString(),
std::error_code
(
ENOENT,
std::system_category()
)
);
} }
QFile packFile(packDir.absoluteFilePath(QStringLiteral("pack.json"))); QFile packFile(packDir.absoluteFilePath(QStringLiteral("pack.json")));
if(!packFile.open(QFile::ReadOnly)) if(!packFile.open(QFile::ReadOnly))
{ {
throw FileException throw std::filesystem::filesystem_error
( (
QStringLiteral("Could not open pack file: %1").arg QStringLiteral("Could not open pack file").arg
( (
packFile.errorString() uri.toString()
).toStdString(),
std::error_code
(
errno,
std::system_category()
) )
); );
} }
@@ -694,11 +780,16 @@ auto DownloadManager::readShaderToyEntry(const QUrl &uri) noexcept(false) -> Sha
if(jsonError.error != QJsonParseError::NoError) if(jsonError.error != QJsonParseError::NoError)
{ {
throw FileException throw std::filesystem::filesystem_error
( (
QStringLiteral("Could parse pack file: %1").arg QStringLiteral("URI %1 is not a local file uri").arg
( (
jsonError.errorString() uri.toString()
).toStdString(),
std::error_code
(
EIO,
std::system_category()
) )
); );
} }
+3 -1
View File
@@ -143,8 +143,9 @@ signals:
private: private:
auto compile(const QUrl &uri) noexcept(false) -> QUrl; auto compile(const QUrl &uri) noexcept(false) -> QUrl;
auto install(const QUrl &uri) noexcept(false) -> QUrl; auto install(const QUrl &uri) noexcept(false) -> QUrl;
auto download(const QNetworkRequest &request, const QString &id, RequestType type = Get) -> QFuture<QUrl>; auto download(const QNetworkRequest &request, const QString &id, RequestType type = Get, const QString &filename = QString()) -> QFuture<QUrl>;
auto readShaderToyEntry(const QUrl &uri) noexcept(false) -> ShaderToyEntry; auto readShaderToyEntry(const QUrl &uri) noexcept(false) -> ShaderToyEntry;
auto validateUri(const QUrl &uri) noexcept(false) -> void;
QString m_lastInstalledFile; QString m_lastInstalledFile;
@@ -159,6 +160,7 @@ private:
State m_state; State m_state;
QMutex m_downloadMutex; QMutex m_downloadMutex;
QMutex m_fileMutex;
PackCompiler *m_compiler = nullptr; PackCompiler *m_compiler = nullptr;
+1 -1
View File
@@ -249,7 +249,7 @@ auto InstalledPackManager::setState(State state) -> void
auto InstalledPackManager::resetState() -> void auto InstalledPackManager::resetState() -> void
{ {
setState(Idle); // TODO: Adapt to use your actual default value setState(Idle);
} }
auto InstalledPackManager::roleNames() const -> QHash<int, QByteArray> auto InstalledPackManager::roleNames() const -> QHash<int, QByteArray>
File diff suppressed because it is too large Load Diff
+425 -126
View File
@@ -36,6 +36,8 @@
#include <qobject.h> #include <qobject.h>
#include <qtmetamacros.h> #include <qtmetamacros.h>
#include <QPainter> #include <QPainter>
#include <QtShaderTools>
#include <QtShaderTools/rhi/qshaderbaker.h>
#include <QtConcurrent/qtconcurrentrun.h> #include <QtConcurrent/qtconcurrentrun.h>
#include <qcontainerfwd.h> #include <qcontainerfwd.h>
#include <qmargins.h> #include <qmargins.h>
@@ -43,23 +45,47 @@
#include <qtmetamacros.h> #include <qtmetamacros.h>
#include <qurl.h> #include <qurl.h>
#include "common/komplex_global.h" #include "common/komplex_global.h"
#if __has_include("vulkan/vulkan_core.h")
#define HAS_VULKAN
#include <vulkan/vulkan_core.h>
#endif
#if __has_include("GL/gl.h")
#define HAS_OPENGL
#include <GL/gl.h>
#endif
struct KOMPLEX_EXPORT BuildContext
{
QMap<QByteArray, QByteArray> commonData;
};
/** /**
* @brief The PackCompiler class * @brief The PackCompiler class
* [1] Extract Pack (GZip) * [1] Extract Pack (GZip)
* [2] Verify directory is a pack and has shaders * [2] Verify directory is a pack and has shaders
* [3] Load shader code * [3] Load Common shader code
* [4] Append Common and Global files, if they exist * [4] Walk the shader directory
* [5] Add uniform and replace variable use * [5] Load shader code
* [6] Run C Preprocessor (cpp -P) to process macros * [6] Append type specific common code and global code
* [7] Append version macro * [7] Replace uniform variable use
* [8] Compile with Qt Shader Baker * [8] Add uniform header
* [9] Add uniform footer
* [10] Run preprocessor to process macros
* [11] Append version macro
* [12] Compile with QShaderBaker
* [13] Save
*/ */
class KOMPLEX_EXPORT PackCompiler : public QObject class PackCompiler : public QObject
{ {
Q_OBJECT Q_OBJECT
QML_ELEMENT
public: public:
/**
* @brief The State enum
* Enum of the possible states of the compiler
*/
enum State enum State
{ {
Idle, Idle,
@@ -70,112 +96,418 @@ public:
Q_ENUM(State) Q_ENUM(State)
explicit PackCompiler(QObject *parent = nullptr); explicit PackCompiler(QObject *parent = nullptr);
~PackCompiler() override;
auto compilerOutput() const -> const QString & { return m_compilerOutput; } /**
* @brief progress
* Current compiler progress
* @return
*/
auto progress() -> qreal { return m_progress; } auto progress() -> qreal { return m_progress; }
/**
* @brief currentStep
* Current compiler step
* @return
*/
auto currentStep() -> qint64 { return m_currentStep; } auto currentStep() -> qint64 { return m_currentStep; }
/**
* @brief totalSteps
* Total steps in the current compile
* @return
*/
auto totalSteps() -> qint64 { return m_totalSteps; } auto totalSteps() -> qint64 { return m_totalSteps; }
auto errorTitle() const -> const QString & { return m_errorTitle; }
auto errorMessage() const -> const QString & { return m_errorMessage; }
auto reset() -> void;
auto process(const QUrl &uri) -> QFuture<QUrl>;
/**
* @brief status
* Current status message
* @return
*/
auto status() const -> const QString & { return m_status; } auto status() const -> const QString & { return m_status; }
/**
* @brief state
* Current compiler state
* @return
*/
auto state() const -> State { return m_state; } auto state() const -> State { return m_state; }
protected:
/** /**
* @brief prepareShaders * @brief reset
* Scans the pack's shader directory and sends each file to * Resets the compiler state
* prepareFile()
* @param uri
* Directory to prepare
*/ */
auto prepareShaders(const QUrl &uri) noexcept(false) -> void; auto reset() -> void;
/** /**
* @brief prepareFile * @brief build
* Prepares the individual file by appending the header, footer, * Builds a Komplex pack from a tar.gz file
* common files and replacing standard variable names
* @param uri * @param uri
* Uri of the tar.gz
* @return
* Uri of the built pack
*/ */
auto prepareFile(const QUrl &uri) noexcept(false) -> void; auto build(const QUrl &uri) -> QUrl;
/**
* @brief validateDirectory
*
* @param uri
* @return true
* @return false
*/
auto validateDirectory(const QUrl &uri) -> bool;
auto extract(const QUrl &sourceUri, const QUrl &destinationUri) noexcept(false) -> void;
auto copyFile(const QUrl &sourceUri, const QUrl &destinationUri) noexcept(false) -> void;
auto compile(const QUrl &uri) noexcept(false) -> void;
auto preprocess(const QUrl &uri) noexcept(false) -> void;
auto appendVersion(const QUrl &uri) noexcept(false) -> void;
auto compileShader(const QUrl &uri) noexcept(false) -> void;
auto loadCommonFragmentData(const QUrl &uri) -> QByteArray;
auto loadCommonVertexData(const QUrl &uri) -> QByteArray;
auto loadGlobalData(const QUrl &uri) -> QByteArray;
auto setError(const QString &title, const QString &message, const QUrl &uri = {}) -> void;
auto setCompilerOutput(const QString &compilerOutput) -> void;
auto setState(State state) -> void;
auto setProgress(qreal progress) -> void;
auto setTotalSteps(qint64 steps) -> void;
auto setCurrentStep(qint64 step) -> void;
auto setStatus(const QString &status) -> void;
auto incrementCompileStep() -> void;
auto removeDirectory(const QUrl &uri) -> bool;
signals: signals:
auto compilerOutputChanged() -> void; auto compilerOutputChanged() -> void;
auto errorOcurred() -> void;
auto errorTitleChanged() -> void;
auto errorMessageChanged() -> void;
auto stateChanged() -> void; auto stateChanged() -> void;
auto progressChanged() -> void; auto progressChanged() -> void;
auto currentStepChanged() -> void; auto currentStepChanged() -> void;
auto totalStepsChanged() -> void; auto totalStepsChanged() -> void;
auto compileComplete(const QUrl &uri) -> void; auto compileComplete(const QUrl &uri) -> void;
auto statusChanged() -> void; auto statusChanged() -> void;
auto packReady(const QString &) -> void; auto packReady(const QString &) -> void;
auto errorStepChanged() -> void; auto errorStepChanged() -> void;
auto errorRatingChanged() -> void; auto errorRatingChanged() -> void;
private: private:
//[1]
/**
* @brief extract
* Extracts the packfile and deletes the source
* @param uri of the tar.gz pack
* @return uri of the extracted directory
*/
auto extract(const QUrl &uri) noexcept(false) -> const QUrl;
//[2]
/**
* @brief validatePack
* Validates that the directory is a valid pack and has shaders to compile
* @param uri of the directory provided by extract
*/
auto validatePack(const QUrl &uri) const noexcept(false) -> void;
//[3]
/**
* @brief loadCommonData
* Loads the common and global shader code from the shader directory of the uri
* @param uri
*/
auto loadCommonData(const QUrl &uri) -> QMap<QByteArray,QByteArray>;
//[4-5]
/**
* @brief processShaders
* Walks the shader directory, loads the code and calls 6-13 for each
* @param uri
* @param context
*/
auto processShaders(const QUrl &uri, BuildContext *context) -> void;
//[6]
/**
* @brief appendCommonData
* Appends the type specific common code to the shader data
* @param data
* Pointer to shader data
* @param suffix
* Shader file suffix
* @param context
* Pointer to build context object
*/
auto appendCommonData(QByteArray *data, const QByteArray &suffix, BuildContext *context) noexcept(true) -> void;
//[7]
/**
* @brief replaceUniformVariables
* Replaces standard variables such as iFrame with their uniform buffer name
* @param data
* Pointer to the shader data
*/
auto replaceUniformVariables(QByteArray *data) noexcept(true) -> void;
//[8]
/**
* @brief appendUniformHeader
* Adds header and uniform buffer to the shader data
* @param data
* Pointer to the shader data
*/
auto appendUniformHeader(QByteArray *data) noexcept(true) -> void;
//[9]
/**
* @brief appendUniformFooter
* Adds the uniform footer to the shader data
* @param data
* Pointer to the shader data
*/
auto appendUniformFooter(QByteArray *data) noexcept(true) -> void;
//[10]
/**
* @brief preprocess
* I have had issues with defines in code so passing it to a c/c++
* preprocessor is required. I am now using clang for this as clang
* is more modern and can use stdin
* @param data
*/
auto preprocess(QByteArray *data) noexcept(false) -> void;
//[11]
/**
* @brief appendVersion
* The version header confuses the preprocessor, so add it at the end
* @param data
*/
auto appendVersion(QByteArray *data) noexcept(true) -> void;
//[12]
/**
* @brief compile
* Compiles the shader data in memory and returns the shader object.
* @param data
* Shader data
* @param filename
* Filename of the shader
* @param stage
* Type of shader, based on suffix of original file
* @return
* Compiled shader object
*/
auto compile(const QByteArray &data, const QString &filename, const QShader::Stage stage) noexcept(false) -> QShader;
//[13]
/**
* @brief save
* Saves a serialized version of the shader to the specified uri
* @param uri
* Uri of the file to create
* @param shader
* The compiled shader
*/
auto save(const QUrl &uri, const QShader &shader) noexcept(false) -> void;
//@BEGIN helpers
/**
* @brief validateUri
* Validates that the uri is a local file or direcotry
* @param uri
*/
auto validateUri(const QUrl &uri) const noexcept(false) -> void;
/**
* @brief run
* Runs the supplied command with the given arguments as a QProcess. If
* data is supplied, it is written to the standard input channel after the
* process has started
* @param command
* System command or program to run
* @param arguments
* QStringList of the given arguments. Minimal wildcard expansion available.
* @param data
* Optional data to write
* @return
* Standard non-error output
*/
auto run(const QString &command, const QStringList &arguments, const QByteArray &data = {}) noexcept(false) -> QByteArray;
/**
* @brief readFile
* Reads the file at the given uri and returns its data
* @param uri
* Uri of the file
* @return
* File contents
*/
auto readFile(const QUrl &uri) noexcept(false) -> QByteArray;
/**
* @brief writeFile
* Writes the supplied data to the given uri
* @param uri
* Uri of the file
* @param data
* Data to write
*/
auto writeFile(const QUrl &uri, const QByteArray &data) noexcept(false) -> void;
/**
* @brief copyFile
* Copys file to new uri
* @param sourceUri
* File to copy
* @param destinationUri
* New file location/name
*/
auto copyFile(const QUrl &sourceUri, const QUrl &destinationUri) noexcept(false) -> void;
/**
* @brief createDirectory
* QDir::mkpath was failing, so this helper function calls mkdir -p
* @param uri
* Directory path to create
*/
auto createDirectory(const QUrl &uri) noexcept(false) -> void;
/**
* @brief removeDirectory
* Calls rm -rf, but should be replaced with an agnostic solution
* @param uri
* Directory to remove
*/
auto removeDirectory(const QUrl &uri) noexcept(false) -> void;
/**
* @brief getStageFromSuffix
* Supplies the stage/type of shader based on the shaders file extension
* @param suffix
* @return
*/
auto getStageFromSuffix(const QString &suffix) const -> QShader::Stage;
/**
* @brief setState
* Sets the current state of the compiler
* @param state
*/
auto setState(State state) -> void;
/**
* @brief setProgress
* Sets the current progress of the compiler
* @param progress
*/
auto setProgress(qreal progress) -> void;
/**
* @brief setTotalSteps
* Sets the total steps pack will take to build
* @param steps
*/
auto setTotalSteps(qint64 steps) -> void;
/**
* @brief setCurrentStep
* Sets the current step
* @param step
*/
auto setCurrentStep(qint64 step) -> void;
/**
* @brief setStatus
* Sets the current status message
* @param status
*/
auto setStatus(const QString &status) -> void;
/**
* @brief incrementCompileStep
* Increments the current step and updates progress
*/
auto incrementCompileStep() -> void;
//@END helpers
#ifdef HAS_VULKAN
/**
* @brief vulkanVersion
* Returns the current version reported by the vulkan api
* @return
*/
auto vulkanVersion() const -> qint32;
#endif
#ifdef HAS_OPENGL
/**
* @brief openGlVersion
* Returns the current version reported by the opengl api
* @return
*/
auto openGlVersion() const -> qint32;
#endif
//members
/**
* @brief m_updateVariables
* Standard variables expected by most online shaders, mainly
* shadertoy and similar.
*/
static inline const QStringList m_updateVariables static inline const QStringList m_updateVariables
{ {
QStringLiteral("iTime"), QStringLiteral("iTime"),
QStringLiteral("iTimeDelta"), QStringLiteral("iTimeDelta"),
QStringLiteral("iFrameRate"), QStringLiteral("iFrameRate"),
QStringLiteral("iSampleRate"), QStringLiteral("iSampleRate"),
QStringLiteral("iFrame"), QStringLiteral("iFrame"),
QStringLiteral("iDate"), QStringLiteral("iDate"),
QStringLiteral("iMouse"), QStringLiteral("iMouse"),
QStringLiteral("iResolution"), QStringLiteral("iResolution"),
QStringLiteral("iColorTheme"), QStringLiteral("iColorTheme"),
QStringLiteral("iChannelTime"), QStringLiteral("iChannelTime"),
QStringLiteral("iChannelResolution") QStringLiteral("iChannelResolution")
}; };
/**
* @brief m_variableExpressions
* Regular expressions of standardized variables. Built at runtime
*/
static inline QList<QRegularExpression> m_variableExpressions;
/**
* @brief m_shaderNameFilters
* Name filters for supported shader types
*/
static inline const QStringList m_shaderNameFilters
{
QStringLiteral("*.frag"),
QStringLiteral("*.vert"),
QStringLiteral("*.tese"),
QStringLiteral("*.tesc"),
QStringLiteral("*.geom"),
QStringLiteral("*.comp"),
QStringLiteral("*.glsl")
};
/**
* @brief m_shaderStages
* Map of supported file suffix to their QShader::Stage
*/
static inline const QMap<QString, QShader::Stage> m_shaderStages
{
{
QStringLiteral("frag"),
QShader::FragmentStage
},
{
QStringLiteral("vert"),
QShader::VertexStage
},
{
QStringLiteral("tese"),
QShader::TessellationEvaluationStage
},
{
QStringLiteral("tesc"),
QShader::TessellationControlStage
},
{
QStringLiteral("geom"),
QShader::GeometryStage
},
{
QStringLiteral("comp"),
QShader::ComputeStage
}
};
/**
* @brief m_version
* Version to be appended to the shader before build
*/
static inline const QByteArray m_version static inline const QByteArray m_version
{ {
R"(#version 450)" R"(#version 450)"
}; };
static inline const QString m_header /**
{ * @brief m_header
R"(layout(location = 0) in vec2 qt_TexCoord0; * Header to be appended to the shader before build
*/
static inline const QByteArray m_header
{
R"(layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor; layout(location = 0) out vec4 fragColor;
layout(std140, binding = 0) uniform buf { layout(std140, binding = 0) uniform buf {
@@ -200,61 +532,28 @@ layout(binding = 3) uniform sampler2D iChannel2;
layout(binding = 4) uniform sampler2D iChannel3; layout(binding = 4) uniform sampler2D iChannel3;
vec2 fragCoord = vec2(qt_TexCoord0.x, 1.0 - qt_TexCoord0.y) * ubuf.iResolution.xy;)" vec2 fragCoord = vec2(qt_TexCoord0.x, 1.0 - qt_TexCoord0.y) * ubuf.iResolution.xy;)"
}; };
static inline const QString m_footer /**
{ * @brief m_footer
R"(void main() { * Footer to be appended to the shader before build
*/
static inline const QByteArray m_footer
{
R"(
void main() {
vec4 color = vec4(0.0); vec4 color = vec4(0.0);
mainImage(color, fragCoord); mainImage(color, fragCoord);
fragColor = color; fragColor = color;
})" })"
}; };
QString m_compilerOutput;
QString m_errorMessage;
QString m_errorTitle;
QString m_status;
State m_state; State m_state;
qreal m_currentStep = 0; qreal m_currentStep = 0;
qreal m_progress = 0; qreal m_progress = 0;
qreal m_totalSteps = 0; qreal m_totalSteps = 0;
QString m_status;
QMutex m_downloadMutex;
static inline QList<QRegularExpression> m_variableExpressions;
static inline const QRegularExpression m_commonFragmentExpression = QRegularExpression
(
QString("^common\\.frag$"),
QRegularExpression::CaseInsensitiveOption
);
static inline const QRegularExpression m_commonVertexExpression = QRegularExpression
(
QString("^common\\.vert$"),
QRegularExpression::CaseInsensitiveOption
);
static inline const QRegularExpression m_fragmentExpression = QRegularExpression
(
QString("^.{1,}\\.frag$"),
QRegularExpression::CaseInsensitiveOption |
QRegularExpression::DotMatchesEverythingOption
);
static inline const QRegularExpression m_vertexExpression = QRegularExpression
(
QString("^.{1,}\\.vert$"),
QRegularExpression::CaseInsensitiveOption |
QRegularExpression::DotMatchesEverythingOption
);
Q_PROPERTY(QString compilerOutput READ compilerOutput WRITE setCompilerOutput NOTIFY compilerOutputChanged FINAL)
Q_PROPERTY(QString errorTitle READ errorTitle NOTIFY errorTitleChanged FINAL)
Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged FINAL)
Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged FINAL) Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged FINAL)
Q_PROPERTY(qint64 totalSteps READ totalSteps NOTIFY totalStepsChanged FINAL) Q_PROPERTY(qint64 totalSteps READ totalSteps NOTIFY totalStepsChanged FINAL)
Q_PROPERTY(qint64 currentStep READ currentStep NOTIFY currentStepChanged FINAL) Q_PROPERTY(qint64 currentStep READ currentStep NOTIFY currentStepChanged FINAL)
+8 -10
View File
@@ -139,19 +139,19 @@ Content purchases will be processed through the website using Paypal as will art
| - Popular Videos | ✅ | | | - Popular Videos | ✅ | |
| - View More | ✅ | | | - View More | ✅ | |
| | | | | | | |
| Media Search | | | | Media Search | | |
| - Packs | ✅ | | | - Packs | ✅ | |
| - Videos | ✅ | | | - Videos | ✅ | |
| - Images | ✅ | | | - Images | ✅ | |
| | | | | | | |
| Media Downloader | | | | Media Downloader | | |
| - Packs | | | | - Packs | | |
| - Videos | | | | - Videos | | |
| - Images | ✅ | | | - Images | ✅ | |
| | | | | | | |
| Detailed Views | | | | Detailed Views | | |
| - Packs | | | | - Packs | | |
| - Videos | | | | - Videos | | |
| - Images | ✅ | | | - Images | ✅ | |
| | | | | | | |
| App Management | ✔ | | | App Management | ✔ | |
@@ -182,8 +182,6 @@ Content purchases will be processed through the website using Paypal as will art
| - Artist Payout | ❌ | | | - Artist Payout | ❌ | |
| - User Media Purchase | ❌ | | | - User Media Purchase | ❌ | |
This app is currently under development and is currently alpha. The API is now being hosted on https://komplex.dev. This app is currently under development and is currently BETA1 and the new API is live. Please do expect bugs in pack compiling at this stage.
I have begun adding download functionality, however it is not yet complete.
"Featured" Live wallpapers is currently a duplicated of "Newest". The featured endpoint will take manual curation, so this will take some time. "Featured" Live wallpapers is currently a duplicated of "Newest". The featured endpoint will take manual curation, so this will take some time.
BETA should be here within a few weeks.
+2 -2
View File
@@ -11,8 +11,8 @@ target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE
KomplexHubModuleplugin KomplexHubModuleplugin
KomplexHubContentplugin KomplexHubContentplugin
KomplexHubPluginplugin KomplexHubPluginplugin
KomplexHubModule_Controlsplugin KomplexHubControlsplugin
KomplexHubModule_Keroplugin KomplexHubKeroplugin
Qt6::Quick Qt6::Quick
Qt6::Core Qt6::Core
Qt6::Gui Qt6::Gui