Inital commit of the Komplex Hub

This commit is contained in:
Digital Artifex
2026-06-02 15:11:36 -04:00
commit 96a7c71a29
290 changed files with 21517 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
### This file is automatically generated by Qt Design Studio.
### Do not change
set_source_files_properties(Constants.qml
PROPERTIES
QT_QML_SINGLETON_TYPE true
)
qt_add_library(KomplexHubModule STATIC)
qt6_add_qml_module(KomplexHubModule
URI "KomplexHub"
VERSION 1.0
RESOURCE_PREFIX "/qt/qml"
QML_FILES
"Constants.qml"
"EventListModel.qml"
"EventListSimulator.qml"
"WallpaperModelData.qml"
)
add_subdirectory("Controls")
add_subdirectory("Kero")
+69
View File
@@ -0,0 +1,69 @@
pragma Singleton
import QtQuick
import QtQuick.Studio.Application
QtObject {
readonly property int width: 1920
readonly property int height: 1080
property string relativeFontDirectory: "fonts"
readonly property font largeFont: Qt.font({
family: Qt.application.font.family,
pixelSize: Qt.application.font.pixelSize * 1.6,
})
readonly property font mediumFont: Qt.font({
family: Qt.application.font.family,
pixelSize: Qt.application.font.pixelSize * 1.3
})
readonly property font font: Qt.font({
family: Qt.application.font.family,
pixelSize: Qt.application.font.pixelSize
})
readonly property font smallFont: Qt.font({
family: Qt.application.font.family,
pixelSize: Qt.application.font.pixelSize * 0.8
})
readonly property font h1Font: Qt.font({
family: Qt.application.font.family,
pixelSize: Qt.application.font.pixelSize * 1.8,
bold: true
})
readonly property font h2Font: Qt.font({
family: Qt.application.font.family,
pixelSize: Qt.application.font.pixelSize * 1.6,
bold: true
})
readonly property font h3Font: Qt.font({
family: Qt.application.font.family,
pixelSize: Qt.application.font.pixelSize * 1.4,
bold: true
})
readonly property font h4Font: Qt.font({
family: Qt.application.font.family,
pixelSize: Qt.application.font.pixelSize * 1.3,
bold: true
})
readonly property font h5Font: Qt.font({
family: Qt.application.font.family,
pixelSize: Qt.application.font.pixelSize * 1,
bold: true
})
readonly property font h6Font: Qt.font({
family: Qt.application.font.family,
pixelSize: Qt.application.font.pixelSize * 0.8,
bold: true
})
readonly property int largeMargin: 12
readonly property int mediumMargin: 6
readonly property int smallMargin: 3
readonly property int slowAnimationDuration: 750
readonly property int normalAnimationDuration: 250
readonly property int fastAnimationDuration: 125
property StudioApplication application: StudioApplication {
fontPath: Qt.resolvedUrl("../KomplexHubContent/" + relativeFontDirectory)
}
}
+18
View File
@@ -0,0 +1,18 @@
### This file is automatically generated by Qt Design Studio.
### Do not change
qt_add_library(KomplexHubModule_Controls STATIC)
qt6_add_qml_module(KomplexHubModule_Controls
URI "KomplexHub.Controls"
VERSION 1.0
RESOURCE_PREFIX "/qt/qml"
QML_FILES
"LineEdit.qml"
"MenuButton.qml"
"SearchBar.qml"
"SquareButton.qml"
"Throbber.qml"
"SearchResultItem.qml"
"SearchResultList.qml"
)
+119
View File
@@ -0,0 +1,119 @@
/*
* QML LineEdit Control
* Copyright (C) 2026 @DigitalArtifex | github.com/DigitalArtifex | digitalartifex.dev
*
* This control provides a wrapped TextInput that looks and acts more like the
* LineEdit control from QtWidgets
*
* 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.Controls
import QtQuick.Layouts
Item {
/* Grouped Settings */
component BorderSettings: QtObject {
property color color: palette.alternateBase.lighter()
property int width: 1
property bool pixelAligned: true
}
component Corners: QtObject {
property int bottom: 0
property int left: 0
property int right: 0
property int top: 0
}
component Radius: QtObject {
property int topLeft: 0
property int topRight: 0
property int bottomLeft: 0
property int bottomRight: 0
}
/* End Grouped Settings */
property var background: palette.alternateBase.darker()
property BorderSettings border: BorderSettings {}
property Corners margins: Corners {bottom: 3; top: 3; left: 3; right: 3}
property Radius radius: Radius {}
property font font
property color color: palette.text
property Corners padding: Corners {bottom: 6; top: 6; left: 6; right: 6}
property alias text: lineEditInput.text
signal accepted
signal editingFinished
id: lineEditRoot
ColumnLayout {
anchors.fill: parent
Rectangle {
id: lineEditBackground
border.color: lineEditRoot.border.color
border.width: lineEditRoot.border.width
border.pixelAligned: lineEditRoot.border.pixelAligned
color: lineEditRoot.background
Layout.fillHeight: true
Layout.fillWidth: true
Layout.topMargin: lineEditRoot.margins.top
Layout.bottomMargin: lineEditRoot.margins.bottom
Layout.leftMargin: lineEditRoot.margins.left
Layout.rightMargin: lineEditRoot.margins.right
bottomLeftRadius: lineEditRoot.radius.bottomLeft
bottomRightRadius: lineEditRoot.radius.bottomRight
topLeftRadius: lineEditRoot.radius.topLeft
topRightRadius: lineEditRoot.radius.topRight
TextInput {
id: lineEditInput
anchors.fill: parent
color: lineEditRoot.color
font: lineEditRoot.font
anchors.leftMargin: lineEditRoot.padding.left
anchors.topMargin: lineEditRoot.padding.top
anchors.bottomMargin: lineEditRoot.padding.bottom
anchors.rightMargin: lineEditRoot.padding.right
onAccepted: () => lineEditRoot.accepted()
onTextChanged: () => lineEditRoot.text = lineEditInput.text
onEditingFinished: () => lineEditRoot.editingFinished()
}
states: [
State {
name: "focused"
when: lineEditInput.focus
PropertyChanges {
target: lineEditBackground
border.color: palette.accent
}
}
]
}
}
}
+134
View File
@@ -0,0 +1,134 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import KomplexHub
Item {
id: menuButtonRoot
property string text: "Button Text"
property IconSettings icon: IconSettings {}
property var page: null
property bool selected: false
signal triggered
component IconSettings: QtObject {
property int width: 16
property int height: 16
property string url: ""
}
Rectangle {
id: menuButtonBackground
anchors.fill: parent
color: "transparent"
ColumnLayout {
spacing: 0
anchors.fill: parent
layoutDirection: Qt.LeftToRight
Image {
id: menuButtonIcon
source: icon.url
Layout.preferredWidth: icon.height
Layout.preferredHeight: icon.width
Layout.topMargin: Constants.mediumMargin
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
}
Text {
color: palette.text
text: menuButtonRoot.text
elide: Text.ElideMiddle
horizontalAlignment: Qt.AlignHCenter
font.pixelSize: 12
Layout.fillWidth: true
Layout.topMargin: Constants.mediumMargin
Layout.bottomMargin: Constants.mediumMargin
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
}
}
Behavior on color {
ColorAnimation { duration: Constants.fastAnimationDuration }
}
}
MouseArea {
property string lastState
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onEntered: () => {
menuButtonRoot.state = "hovered"
}
onExited: () => {
lastState = ""
if(selected)
menuButtonRoot.state = "selected"
else
menuButtonRoot.state = ""
}
onPressed: () => {
lastState = menuButtonRoot.state
menuButtonRoot.state = "clicked"
}
onReleased: () => {
if(!mouseArea.containsMouse)
return;
if(!selected)
selected = true
}
}
onSelectedChanged: () => {
if(selected) {
triggered()
state = "selected"
}
else {
state = ""
}
}
states: [
State {
name: "selected"
PropertyChanges {
target: menuButtonBackground
color: palette.accent.darker(1.5)
}
},
State {
name: "hovered"
//when: mouseArea.containsMouse
PropertyChanges {
target: menuButtonBackground
color: palette.button
}
},
State {
name: "clicked"
//when: mouseArea.containsPress
PropertyChanges {
target: menuButtonBackground
color: palette.button.darker(1.5)
}
}
]
}
+68
View File
@@ -0,0 +1,68 @@
/*
This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
It is supposed to be strictly declarative and only uses a subset of QML. If you edit
this file manually, you might introduce QML code that is not supported by Qt Design Studio.
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import KomplexHub
Item {
property string searchTerm: ""
property string icon: ""
property color color: "transparent"
id: searchBarRootItem
clip: true
Rectangle {
color: searchBarRootItem.color
anchors.fill: parent
RowLayout {
id: searchContainerLayout
anchors.fill: parent
LineEdit {
id: searchEdit
Layout.fillHeight: true
Layout.fillWidth: true
Layout.leftMargin: Constants.mediumMargin
Layout.rightMargin: Constants.mediumMargin
Layout.topMargin: Constants.smallMargin
Layout.bottomMargin: Constants.smallMargin
padding.top: 12
font.pixelSize: 12
onAccepted: () => searchBarRootItem.searchTerm = text
}
SquareButton {
id: searchButton
Layout.fillHeight: searchEdit.height
Layout.preferredWidth: searchEdit.height
Layout.rightMargin: Constants.mediumMargin
Layout.topMargin: Constants.mediumMargin
Layout.bottomMargin: Constants.mediumMargin
icon.source: searchBarRootItem.icon
icon.width: 16
icon.height: 16
}
}
}
states: [
State {
name: "hidden"
PropertyChanges {
target: searchBarRootItem
visible: false
}
}
]
}
@@ -0,0 +1,151 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Item {
property string author: "Author"
property string description: "This is a description of the search result item"
property string title: "Wallpaper Title"
property string thumbnail: ""
property string url: ""
property string uuid: ""
property bool selected: false
signal triggered
id: searchResultItemRoot
width: 256
height: 256
clip: true
Rectangle {
id: searchResultItemContainer
anchors.fill: parent
border.color: palette.alternateBase.lighter(1.75)
color: palette.alternateBase.lighter(1.25)
ColumnLayout {
anchors.fill: parent
Rectangle {
Layout.preferredWidth: 250
Layout.preferredHeight: 141
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
Layout.topMargin: 3
border.color: palette.alternateBase.lighter(1.75)
color: palette.base.lighter(1.25)
}
Text {
color: palette.text
text: searchResultItemRoot.title
font.pixelSize: 16
font.bold: true
elide: Text.ElideRight
Layout.preferredWidth: 246
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
}
Text {
color: palette.text
font.pixelSize: 12
text: "By: " + searchResultItemRoot.author
leftPadding: 12
Layout.alignment: Qt.AlignLeft | Qt.AlignBottom
Layout.preferredWidth: 250
}
Text {
color: palette.text
font.pixelSize: 12
text: searchResultItemRoot.description
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.preferredWidth: 236
Layout.bottomMargin: 3
}
}
Behavior on color {
ColorAnimation { duration: 200 }
}
}
MouseArea {
property string lastState
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onEntered: () => {
if(!selected)
searchResultItemRoot.state = "hovered"
}
onExited: () => {
lastState = ""
if(selected)
searchResultItemRoot.state = "selected"
else
searchResultItemRoot.state = ""
}
onPressed: () => {
if(!selected) {
lastState = searchResultItemRoot.state
searchResultItemRoot.state = "clicked"
}
}
onReleased: () => {
if(!mouseArea.containsMouse)
return;
selected = !selected
}
}
onSelectedChanged: () => {
if(selected) {
searchResultItemRoot.triggered()
searchResultItemRoot.state = "selected"
}
else {
searchResultItemRoot.state = ""
}
}
states: [
State {
name: "hovered"
PropertyChanges {
target: searchResultItemContainer
color: palette.alternateBase.lighter(1.5)
border.color: Qt.hsva(palette.accent.hslHue,
palette.accent.hslSaturation,
0.5, // Set custom lightness
1.0)
}
},
State {
name: "selected"
PropertyChanges {
target: searchResultItemContainer
color: palette.accent
}
}
]
}
@@ -0,0 +1,206 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import KomplexHub
Item {
readonly property bool searchable: true
property int resultsPerPage: resultsPerRow * resultsPerColumn
property int resultsPerRow: width / (256 + Constants.largeMargin)
property int resultsPerColumn: height / (256 + Constants.largeMargin)
property int totalResults: 7
property int currentPage: 1
property color color: "transparent"
id: searchResultsPageRoot
Rectangle {
anchors.fill: parent
color: searchResultsPageRoot.color
ColumnLayout {
anchors.fill: parent
anchors.margins: Constants.largeMargin
Component {
id: highlight
Rectangle {
width: view.cellWidth; height: view.cellHeight
color: "lightsteelblue";
radius: 5
x: view.currentItem.x
y: view.currentItem.y
Behavior on x { SpringAnimation { spring: 3; damping: 0.2 } }
Behavior on y { SpringAnimation { spring: 3; damping: 0.2 } }
}
}
//So the idea here is that the real query would request X number of results
// (say 50), but then the cache aggregator will paginate on the cache
// in a way that it would also account for the total number of results for
// the search term
//this is dummy data for the cache
WallpaperModelData {
property int totalResults: 17
property string term: ""
onTermChanged: () => {
//clear()
//this will be in the plugin
//query(0, 100, term)
}
id: wallpaperDataCache
//use the current search term to get the next chunk of data from the server
function extendCache() {
//this will be in the plugin
//query(count, 100, term)
}
}
ListModel {
property int index: 0
id: wallpaperCacheAggregator
//get the previous page data
function previous() {
searchResultsPageRoot.state = "loading"
index -= searchResultsPageRoot.resultsPerPage
if(index < 0)
index = 0
searchResultsPageRoot.currentPage -= 1
if(searchResultsPageRoot.currentPage < 1)
searchResultsPageRoot.currentPage = 1
searchResultsPageRoot.state = ""
aggregateCache()
}
//get the next page data
function next() {
searchResultsPageRoot.state = "loading"
index += searchResultsPageRoot.resultsPerPage
if(index >= searchResultsPageRoot.totalResults)
index = searchResultsPageRoot.totalResults - searchResultsPageRoot.resultsPerPage
searchResultsPageRoot.currentPage += 1
if(searchResultsPageRoot.currentPage > Math.ceil(searchResultsPageRoot.totalResults / searchResultsPageRoot.resultsPerPage))
searchResultsPageRoot.currentPage = Math.ceil(searchResultsPageRoot.totalResults / searchResultsPageRoot.resultsPerPage)
//download next chunk of data if we're at the end
if(index >= wallpaperDataCache.count)
wallpaperDataCache.extendCache()
searchResultsPageRoot.state = ""
aggregateCache()
}
//re-aggregate the current cache
function aggregateCache() {
clear()
for(var i = 0; i < searchResultsPageRoot.resultsPerPage && (index + i) < wallpaperDataCache.count; i++)
insert(i, wallpaperDataCache.get(index + i))
}
}
GridView {
id: resultsView
Layout.fillHeight: true
Layout.fillWidth: true
cellWidth: 256 + Constants.mediumMargin
cellHeight: 256 + Constants.mediumMargin
clip: true
model: wallpaperCacheAggregator
delegate: Rectangle {
required property string author
required property string description
required property string name
required property string thumbnail
required property string url
required property string uuid
SearchResultItem {
author: parent.author
description: parent.description
title: parent.name
thumbnail: parent.thumbnail
url: parent.url
uuid: parent.uuid
}
}
}
RowLayout {
Layout.fillWidth: true
Layout.fillHeight: false
Layout.preferredHeight: 36
Layout.margins: Constants.largeMargin
SquareButton {
Layout.fillHeight: true
Layout.preferredWidth: 160
icon.source: "qrc:/images/icons/icons8-back.svg"
icon.height: 16
icon.width: 16
text: qsTr("Previous")
enabled: searchResultsPageRoot.currentPage > 1
onTriggered: () => {
wallpaperCacheAggregator.previous()
}
}
Item {
Layout.fillWidth: true
}
SquareButton {
Layout.fillHeight: true
Layout.preferredWidth: 160
icon.source: "qrc:/images/icons/icons8-next.svg"
icon.height: 16
icon.width: 16
text: qsTr("Next")
enabled: searchResultsPageRoot.currentPage < Math.ceil(searchResultsPageRoot.totalResults / searchResultsPageRoot.resultsPerPage)
onTriggered: () => {
wallpaperCacheAggregator.next()
}
}
}
}
}
states: [
State {
name: "loading"
},
State {
name: "empty"
},
State {
name: "error"
}
]
onResultsPerPageChanged: () => wallpaperCacheAggregator.aggregateCache();
Component.onCompleted: () => wallpaperCacheAggregator.aggregateCache()
}
+222
View File
@@ -0,0 +1,222 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Item {
property string text: qsTr("")
property IconSettings icon: IconSettings {}
property alias spacing: squareButtonLayout.spacing
property int margins: 4
property bool checkable: false
property bool checked: false
property color color: palette.button
property Gradient gradient: defaultGradient
property BorderSettings border: BorderSettings {}
signal triggered
height: 36
width: 180
id: squareButtonRoot
//icon properties. access them after Component.onLoad()
component IconSettings: QtObject {
property int width: 16
property int height: 16
property string source: "images/icons/icons8-next.svg"
}
component BorderSettings: QtObject {
}
Gradient {
id: clickedGradient
GradientStop { position: 0.0; color: palette.button.darker(1.25) }
GradientStop { position: 1.0; color: palette.button }
}
Gradient {
id: defaultGradient
GradientStop { position: 0.0; color: palette.button.lighter(1.25) }
GradientStop { position: 1.0; color: palette.button }
}
Gradient {
id: hoveredGradient
GradientStop { position: 0.0; color: palette.button.lighter(1.5) }
GradientStop { position: 1.0; color: palette.button.lighter(1.25) }
}
Rectangle {
id: squareButtonBackground
anchors.fill: parent
gradient: squareButtonRoot.gradient
border.color: palette.button.lighter()
RowLayout {
id: squareButtonLayout
anchors.fill: parent
Rectangle {
Layout.preferredHeight: squareButtonRoot.height < squareButtonRoot.width ? squareButtonRoot.height : squareButtonRoot.width
Layout.preferredWidth: squareButtonRoot.height < squareButtonRoot.width ? squareButtonRoot.height : squareButtonRoot.width
id: iconContainer
color: "transparent"
ColumnLayout {
anchors.fill: parent
Image {
id: squareButtonIcon
Layout.preferredWidth: icon.width
Layout.preferredHeight: icon.height
Layout.maximumHeight: icon.height
Layout.maximumWidth: icon.width
source: icon.source
fillMode: Image.PreserveAspectFit
Layout.alignment: Qt.AlignCenter
}
}
}
Text {
id: squareButtonText
color: palette.text
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideMiddle
text: squareButtonRoot.text
font.pixelSize: 14
visible: text.length > 0
Layout.fillHeight: true
Layout.fillWidth: true
Layout.leftMargin: iconContainer.width * -1
}
}
Behavior on color {
ColorAnimation { duration: 250 }
}
// Behavior on gradient {
// PropertyAnimation { duration: 250 }
// }
}
MouseArea {
property string lastState
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onEntered: () => {
squareButtonRoot.state = "hovered"
}
onExited: () => {
lastState = ""
if(checked)
squareButtonRoot.state = "checked"
else
squareButtonRoot.state = ""
}
onPressed: () => {
lastState = squareButtonRoot.state
squareButtonRoot.state = "clicked"
}
onReleased: () => {
if(!mouseArea.containsMouse)
return;
squareButtonRoot.state = lastState
if(checkable)
checked = !checked
triggered()
}
}
onCheckedChanged: () => {
if(checked) {
squareButtonRoot.triggered()
squareButtonRoot.state = "checked"
}
else {
squareButtonRoot.state = ""
}
}
states:[
State {
name: "hovered"
PropertyChanges {
target: squareButtonBackground
border.color: palette.accent
gradient: hoveredGradient
}
PropertyChanges {
target: squareButtonText
color: palette.text
}
},
State {
name: "clicked"
PropertyChanges {
target: squareButtonBackground
border.color: palette.accent.darker(1.5)
gradient: clickedGradient
}
PropertyChanges {
target: squareButtonText
color: palette.text
}
},
State {
name: "checked"
PropertyChanges {
target: squareButtonBackground
border.color: palette.accent.darker(1.5)
gradient: clickedGradient
}
PropertyChanges {
target: squareButtonText
color: palette.text
}
},
State {
name: "disabled"
PropertyChanges {
target: squareButtonBackground
color: palette.button.darker()
gradient: null
}
PropertyChanges {
target: squareButtonText
color: palette.text.darker()
}
}
]
}
+126
View File
@@ -0,0 +1,126 @@
import QtQuick
import QtQuick.Shapes
import QtQuick.Effects
Item {
id: throbberRoot
Rectangle {
anchors.fill: parent
color: "transparent"
Item
{
id: outerRing
anchors.fill: parent
Shape
{
anchors.fill: parent
asynchronous: true
ShapePath
{
property double progress: 0
property int dashSpaceLength: 15
property int dashLength: 1
id: outerRingPath
strokeColor: palette.accent.darker(1 + (progress - 0.25))
fillColor: "transparent"
strokeWidth: 3
strokeStyle: ShapePath.DashLine
startX: 0
startY: outerRing.height * 0.5
dashPattern: [
dashSpaceLength - (dashSpaceLength * progress),
dashSpaceLength * progress
]
PathArc
{
x: outerRing.width
y: outerRing.height * 0.5
radiusX: outerRing.width / 2
radiusY: outerRing.height / 2
useLargeArc: false
}
PathArc
{
x: 0
y: outerRing.height * 0.5
radiusX: outerRing.width / 2
radiusY: outerRing.height / 2
useLargeArc: false
}
}
}
transform: Rotation {
id: outerRingRotation
origin.x: outerRing.width / 2
origin.y: outerRing.height / 2
}
NumberAnimation {
property bool reverse: false
target: outerRingPath
property: "progress"
duration: 1600
//easing.type: Easing.InOutQuad
from: 0
to: 1
loops: 1
running: true
onFinished: () => {
if(reverse)
{
from = 0
to = 1
start()
}
else
{
from = 1
to = 0
start()
}
reverse = !reverse
}
}
NumberAnimation {
target: outerRingRotation
property: "angle"
duration: 16000
easing.type: Easing.InOutQuad
from: 0
to: (360 * 4)
loops: NumberAnimation.Infinite
running: true
}
}
MultiEffect {
source: outerRing
anchors.fill: outerRing
brightness: 0.4
saturation: 0.2
blurEnabled: true
blurMax: 64
blur: 1.0
}
}
}
+8
View File
@@ -0,0 +1,8 @@
module KomplexHub.Controls
LineEdit 1.0 LineEdit.qml
MenuButton 1.0 MenuButton.qml
SquareButton 1.0 SquareButton.qml
SearchResultItem 1.0 SearchResultItem.qml
SearchResultList 1.0 SearchResultList.qml
SearchBar 1.0 SearchBar.qml
Throbber 1.0 Throbber.qml
+12
View File
@@ -0,0 +1,12 @@
import QtQuick
ListModel {
id: eventListModel
ListElement {
eventId: "enterPressed"
eventDescription: "Emitted when pressing the enter button"
shortcut: "Return"
parameters: "Enter"
}
}
+22
View File
@@ -0,0 +1,22 @@
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()
}
}
+14
View File
@@ -0,0 +1,14 @@
qt_add_library(KomplexHubModule_Kero STATIC)
qt6_add_qml_module(KomplexHubModule_Kero
URI "KomplexHub.Kero"
VERSION 1.0
RESOURCE_PREFIX "/qt/qml"
QML_FILES
"KeroBuildingAnimation.qml"
"KeroChoiceAvatar.qml"
"KeroErrorAvatar.qml"
"KeroHelloAvatar.qml"
"KeroLoadingAnimation.qml"
"KeroNoResultsAvatar.qml"
"KeroWarningAvatar.qml"
)
@@ -0,0 +1,82 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import KomplexHub
Item {
property string title: qsTr("Loading")
property string description: qsTr("Kero is busy looking for wallpapers..we promise")
property color color: palette.window
id: keroLoadingOverlayRoot
Rectangle {
anchors.fill: parent
color: keroLoadingOverlayRoot.color
ColumnLayout {
anchors.fill: parent
Rectangle {
Layout.fillHeight: true
Layout.fillWidth: true
Layout.minimumWidth: 64
Layout.minimumHeight: 64
Layout.maximumWidth: 512
Layout.maximumHeight: 512
Layout.alignment: Qt.AlignCenter
color: "transparent"
Image {
id: keroLoadingImage
anchors.fill: parent
source: "qrc:/images/kero/kero_build_1.png"
antialiasing: true
fillMode: Image.PreserveAspectFit
Timer {
property int frame: 1
id: animationTimer
interval: 175
running: parent.visible
repeat: true
onTriggered: () => {
frame += 1;
if(frame >= 4)
frame = 1
keroLoadingImage.source = "qrc:/images/kero/kero_build_" + frame + ".png"
}
}
}
ColumnLayout {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
Text {
color: palette.text
text: keroLoadingOverlayRoot.title
font: Constants.h1Font
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
}
Text {
id: errorText
text: keroLoadingOverlayRoot.description
color: palette.text.darker()
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.bottomMargin: Constants.largeMargin
}
}
}
}
}
}
@@ -0,0 +1,65 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import KomplexHub
Item {
property string title: qsTr("Please make a choice")
property string description: qsTr("")
property color color: palette.window
id: keroWarningAvatarRoot
Rectangle {
id: keroWarningAvatarBackground
anchors.fill: parent
color: keroWarningAvatarRoot.color
ColumnLayout {
anchors.fill: parent
Rectangle {
Layout.fillHeight: true
Layout.fillWidth: true
Layout.minimumWidth: 64
Layout.minimumHeight: 64
Layout.maximumWidth: 512
Layout.maximumHeight: 512
Layout.alignment: Qt.AlignCenter
color: "transparent"
Image {
anchors.fill: parent
source: "qrc:/images/kero/kero_choice.png"
antialiasing: true
fillMode: Image.PreserveAspectFit
}
ColumnLayout {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
Text {
color: palette.text
text: keroWarningAvatarRoot.title
font.pixelSize: Constants.largeFont.pixelSize * 1.5
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
}
Text {
id: errorText
text: keroWarningAvatarRoot.description
color: palette.text.darker()
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.bottomMargin: Constants.largeMargin
}
}
}
}
}
}
+66
View File
@@ -0,0 +1,66 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import KomplexHub
Item {
property string title: qsTr("Error")
property string description: qsTr("A description of the error")
property color color: palette.window
id: errorOverlayRoot
Rectangle {
id: errorOverlayBackground
anchors.fill: parent
color: errorOverlayRoot.color
ColumnLayout {
anchors.fill: parent
Rectangle {
Layout.fillHeight: true
Layout.fillWidth: true
Layout.minimumWidth: 64
Layout.minimumHeight: 64
Layout.maximumWidth: 512
Layout.maximumHeight: 512
Layout.alignment: Qt.AlignCenter
color: "transparent"
Image {
anchors.fill: parent
source: "qrc:/images/kero/kero_error.png"
antialiasing: true
fillMode: Image.PreserveAspectFit
}
ColumnLayout {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
Text {
color: palette.text
text: errorOverlayRoot.title
font: Constants.h1Font
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
}
Text {
id: errorText
text: errorOverlayRoot.description
color: palette.text.darker()
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.bottomMargin: Constants.largeMargin
}
}
}
}
}
}
+65
View File
@@ -0,0 +1,65 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import KomplexHub
Item {
property string title: qsTr("Hello!")
property string description: qsTr("")
property color color: "transparent"
id: keroHelloAvatarRoot
Rectangle {
id: keroHelloAvatarBackground
anchors.fill: parent
color: keroHelloAvatarRoot.color
ColumnLayout {
anchors.fill: parent
Rectangle {
Layout.fillHeight: true
Layout.fillWidth: true
Layout.minimumWidth: 64
Layout.minimumHeight: 64
Layout.maximumWidth: 512
Layout.maximumHeight: 512
Layout.alignment: Qt.AlignCenter
color: "transparent"
Image {
anchors.fill: parent
source: "qrc:/images/kero/kero_hello.png"
antialiasing: true
fillMode: Image.PreserveAspectFit
}
ColumnLayout {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
Text {
color: palette.text
text: keroHelloAvatarRoot.title
font: Constants.h1Font
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
}
Text {
id: errorText
text: keroHelloAvatarRoot.description
color: palette.text.darker()
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.bottomMargin: Constants.largeMargin
}
}
}
}
}
}
@@ -0,0 +1,82 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import KomplexHub
Item {
property string title: qsTr("Loading")
property string description: qsTr("Kero is busy looking for wallpapers..we promise")
property color color: palette.window
id: keroLoadingOverlayRoot
Rectangle {
anchors.fill: parent
color: keroLoadingOverlayRoot.color
ColumnLayout {
anchors.fill: parent
Rectangle {
Layout.fillHeight: true
Layout.fillWidth: true
Layout.minimumWidth: 64
Layout.minimumHeight: 64
Layout.maximumWidth: 512
Layout.maximumHeight: 512
Layout.alignment: Qt.AlignCenter
color: "transparent"
Image {
id: keroLoadingImage
anchors.fill: parent
source: "qrc:/images/kero/kero_run_1.png"
antialiasing: true
fillMode: Image.PreserveAspectFit
Timer {
property int frame: 1
id: animationTimer
interval: 175
running: parent.visible
repeat: true
onTriggered: () => {
frame += 1;
if(frame >= 4)
frame = 1
keroLoadingImage.source = "qrc:/images/kero/kero_run_" + frame + ".png"
}
}
}
ColumnLayout {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
Text {
color: palette.text
text: keroLoadingOverlayRoot.title
font.pixelSize: Constants.largeFont.pixelSize * 1.5
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
}
Text {
id: errorText
text: keroLoadingOverlayRoot.description
color: palette.text.darker()
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.bottomMargin: Constants.largeMargin
}
}
}
}
}
}
@@ -0,0 +1,64 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import KomplexHub
Item {
property string title: qsTr("No Results")
property string description: qsTr("Kero couldn't find any wallpapers with that search term")
property color color: palette.window
id: noResultsOverlayRoot
Rectangle {
id: noResultsOverlayBackground
anchors.fill: parent
color: noResultsOverlayRoot.color
ColumnLayout {
anchors.fill: parent
Rectangle {
Layout.fillHeight: true
Layout.fillWidth: true
Layout.minimumWidth: 64
Layout.minimumHeight: 64
Layout.maximumWidth: 512
Layout.maximumHeight: 512
Layout.alignment: Qt.AlignCenter
color: "transparent"
Image {
anchors.fill: parent
source: "qrc:/images/kero/kero_no_results.png"
antialiasing: true
fillMode: Image.PreserveAspectFit
}
ColumnLayout {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
Text {
color: palette.text
text: noResultsOverlayRoot.title
font.pixelSize: Constants.largeFont.pixelSize * 1.5
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
}
Text {
id: errorText
text: noResultsOverlayRoot.description
color: palette.text.darker()
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.bottomMargin: Constants.largeMargin
}
}
}
}
}
}
@@ -0,0 +1,65 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import KomplexHub
Item {
property string title: qsTr("Warning")
property string description: qsTr("Kero noticed there might be an issue")
property color color: palette.window
id: keroWarningAvatarRoot
Rectangle {
id: keroWarningAvatarBackground
anchors.fill: parent
color: keroWarningAvatarRoot.color
ColumnLayout {
anchors.fill: parent
Rectangle {
Layout.fillHeight: true
Layout.fillWidth: true
Layout.minimumWidth: 64
Layout.minimumHeight: 64
Layout.maximumWidth: 512
Layout.maximumHeight: 512
Layout.alignment: Qt.AlignCenter
color: "transparent"
Image {
anchors.fill: parent
source: "qrc:/images/kero/kero_warning.png"
antialiasing: true
fillMode: Image.PreserveAspectFit
}
ColumnLayout {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
Text {
color: palette.text
text: keroWarningAvatarRoot.title
font.pixelSize: Constants.largeFont.pixelSize * 1.5
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
}
Text {
id: errorText
text: keroWarningAvatarRoot.description
color: palette.text.darker()
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.bottomMargin: Constants.largeMargin
}
}
}
}
}
}
+8
View File
@@ -0,0 +1,8 @@
module KomplexHub.Kero
KeroBuildingAnimation 1.0 KeroBuildingAnimation.qml
KeroChoiceAvatar 1.0 KeroChoiceAvatar.qml
KeroErrorAvatar 1.0 KeroErrorAvatar.qml
KeroHelloAvatar 1.0 KeroHelloAvatar.qml
KeroLoadingAnimation 1.0 KeroLoadingAnimation.qml
KeroNoResultsAvatar 1.0 KeroNoResultsAvatar.qml
KeroWarningAvatar 1.0 KeroWarningAvatar.qml
+67
View File
@@ -0,0 +1,67 @@
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: ""
}
}
+13
View File
@@ -0,0 +1,13 @@
MetaInfo {
Type {
name: "KomplexHub.EventListSimulator"
icon: ":/qtquickplugin/images/item-icon16.png"
Hints {
visibleInNavigator: true
canBeDroppedInNavigator: true
canBeDroppedInFormEditor: false
canBeDroppedInView3D: false
}
}
}
+7
View File
@@ -0,0 +1,7 @@
module KomplexHub
singleton Constants 1.0 Constants.qml
EventListSimulator 1.0 EventListSimulator.qml
EventListModel 1.0 EventListModel.qml
WallpaperModelData 1.0 WallpaperModelData.qml
Controls 1.0 Controls/
Kero 1.0 Kero/