Inital commit of the Komplex Hub
This commit is contained in:
@@ -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>
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user