Inital commit of the Komplex Hub

This commit is contained in:
Digital Artifex
2026-06-02 15:11:36 -04:00
commit 15a625008e
2911 changed files with 655555 additions and 0 deletions
@@ -0,0 +1,8 @@
import QtQuick.tooling 1.2
// This file describes the plugin-supplied types contained in the library.
// It is used for QML tooling purposes only.
//
// This file was auto-generated by qmltyperegistrar.
Module {}
@@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/">
<file alias="/qt/qml/KomplexHub/Controls">/home/parametheus/Projects/QtDesigner/KomplexHub/build/qml/KomplexHub/Controls</file>
</qresource>
</RCC>
@@ -0,0 +1,8 @@
import QtQuick.tooling 1.2
// This file describes the plugin-supplied types contained in the library.
// It is used for QML tooling purposes only.
//
// This file was auto-generated by qmltyperegistrar.
Module {}
@@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/">
<file alias="/qt/qml/KomplexHub/Controls">/home/parametheus/Projects/QtDesigner/KomplexHub/build/qml/KomplexHub/Controls</file>
</qresource>
</RCC>
+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(1.75)
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
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
}
}
]
}
}
}
@@ -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)
}
}
]
}
@@ -0,0 +1,63 @@
/*
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: ""
id: searchBarRootItem
clip: true
Rectangle {
color: palette.base
anchors.fill: parent
RowLayout {
id: searchContainerLayout
anchors.fill: parent
LineEdit {
Layout.fillHeight: true
Layout.fillWidth: true
padding.top: 12
font.pixelSize: 12
onAccepted: () => searchBarRootItem.searchTerm = text
}
SquareButton {
margins: 0
id: searchButton
Layout.fillHeight: true
Layout.preferredWidth: height
Layout.rightMargin: Constants.mediumMargin
Layout.topMargin: Constants.smallMargin
Layout.bottomMargin: Constants.smallMargin
icon.source: searchBarRootItem.icon
icon.width: 16
icon.height: 16
}
}
}
states: [
State {
name: "hidden"
PropertyChanges {
target: searchBarRootItem
visible: false
}
}
]
}
@@ -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
}
}
}
+12
View File
@@ -0,0 +1,12 @@
module KomplexHub.Controls
linktarget KomplexHubModule_Controlsplugin
optional plugin KomplexHubModule_Controlsplugin
classname KomplexHub_ControlsPlugin
typeinfo KomplexHubModule_Controls.qmltypes
prefer :/qt/qml/KomplexHub/Controls/
LineEdit 1.0 LineEdit.qml
MenuButton 1.0 MenuButton.qml
SearchBar 1.0 SearchBar.qml
SquareButton 1.0 SquareButton.qml
Throbber 1.0 Throbber.qml