expandable dialogs for color scheme, fonts and scheduling modes
This commit is contained in:
@@ -15,14 +15,17 @@ Item {
|
|||||||
required property Component content
|
required property Component content
|
||||||
required property string header
|
required property string header
|
||||||
property int horizontalContentMargin
|
property int horizontalContentMargin
|
||||||
required property string icon
|
property string icon
|
||||||
required property string label
|
required property string label
|
||||||
|
property alias iconLabel: openButton.iconLabel
|
||||||
|
property alias rowButton: openButton
|
||||||
property string subtext: ""
|
property string subtext: ""
|
||||||
property bool open
|
property bool open
|
||||||
property real openHeight: Math.min(rootParent.height * 0.8, 600)
|
property real openHeight: Math.min(rootParent.height * 0.8, 600)
|
||||||
property real openWidth: Math.min(rootParent.width * 0.8, 400)
|
property real openWidth: Math.min(rootParent.width * 0.8, 400)
|
||||||
required property Item rootParent
|
required property Item rootParent
|
||||||
property bool separateContent
|
property bool separateContent
|
||||||
|
required property string settingAnchor
|
||||||
property bool first: false
|
property bool first: false
|
||||||
property bool last: false
|
property bool last: false
|
||||||
|
|
||||||
@@ -57,6 +60,7 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
enabled: false
|
enabled: false
|
||||||
hoverEnabled: enabled
|
hoverEnabled: enabled
|
||||||
|
preventStealing: true
|
||||||
parent: root.open ? root.rootParent : root
|
parent: root.open ? root.rootParent : root
|
||||||
|
|
||||||
onClicked: root.open = false
|
onClicked: root.open = false
|
||||||
@@ -77,7 +81,8 @@ Item {
|
|||||||
backdrop.enabled: true
|
backdrop.enabled: true
|
||||||
dialogBg.bottomLeftRadius: Tokens.rounding.largeIncreased
|
dialogBg.bottomLeftRadius: Tokens.rounding.largeIncreased
|
||||||
dialogBg.bottomRightRadius: Tokens.rounding.largeIncreased
|
dialogBg.bottomRightRadius: Tokens.rounding.largeIncreased
|
||||||
dialogBg.radius: Tokens.rounding.largeIncreased
|
dialogBg.topRightRadius: Tokens.rounding.largeIncreased
|
||||||
|
dialogBg.topLeftRadius: Tokens.rounding.largeIncreased
|
||||||
dialogContent.opacity: 1
|
dialogContent.opacity: 1
|
||||||
dialogWrapper.height: root.openHeight
|
dialogWrapper.height: root.openHeight
|
||||||
dialogWrapper.width: root.openWidth
|
dialogWrapper.width: root.openWidth
|
||||||
@@ -105,7 +110,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Anim {
|
Anim {
|
||||||
properties: "opacity,radius,bottomLeftRadius,bottomRightRadius"
|
properties: "opacity,topLeftRadius,topRightRadius,bottomLeftRadius,bottomRightRadius"
|
||||||
type: Anim.DefaultEffects
|
type: Anim.DefaultEffects
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,6 +177,7 @@ Item {
|
|||||||
|
|
||||||
sourceComponent: MouseArea {
|
sourceComponent: MouseArea {
|
||||||
onWheel: event => event.accepted = true
|
onWheel: event => event.accepted = true
|
||||||
|
preventStealing: true
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.bottomMargin: Tokens.padding.largeIncreased
|
anchors.bottomMargin: Tokens.padding.largeIncreased
|
||||||
@@ -224,6 +230,7 @@ Item {
|
|||||||
text: qsTr("Cancel")
|
text: qsTr("Cancel")
|
||||||
type: TextButton.Text
|
type: TextButton.Text
|
||||||
verticalPadding: Tokens.padding.small
|
verticalPadding: Tokens.padding.small
|
||||||
|
stateLayer.preventStealing: true
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.cancelled();
|
root.cancelled();
|
||||||
@@ -237,6 +244,7 @@ Item {
|
|||||||
isRound: true
|
isRound: true
|
||||||
text: root.acceptLabel
|
text: root.acceptLabel
|
||||||
type: TextButton.Text
|
type: TextButton.Text
|
||||||
|
stateLayer.preventStealing: true
|
||||||
verticalPadding: Tokens.padding.small
|
verticalPadding: Tokens.padding.small
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
|||||||
@@ -93,10 +93,13 @@ DialogRowButton {
|
|||||||
|
|
||||||
onOpenChanged: {
|
onOpenChanged: {
|
||||||
if (open) {
|
if (open) {
|
||||||
|
root.rootParent.interactive = false;
|
||||||
if (!initialSelect)
|
if (!initialSelect)
|
||||||
selectedItem = null;
|
selectedItem = null;
|
||||||
else
|
else
|
||||||
selectedItem = initialSelect;
|
selectedItem = initialSelect;
|
||||||
|
} else {
|
||||||
|
root.rootParent.interactive = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ ConnectedRect {
|
|||||||
property alias subtext: subLabel.text
|
property alias subtext: subLabel.text
|
||||||
property alias text: label.text
|
property alias text: label.text
|
||||||
property string trailingIcon
|
property string trailingIcon
|
||||||
|
property string activeItem
|
||||||
|
|
||||||
signal clicked(event: MouseEvent)
|
signal clicked(event: MouseEvent)
|
||||||
|
|
||||||
@@ -40,15 +41,16 @@ ConnectedRect {
|
|||||||
spacing: Tokens.spacing.medium
|
spacing: Tokens.spacing.medium
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {
|
Anim {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialIcon {
|
MaterialIcon {
|
||||||
id: iconLabel
|
id: iconLabel
|
||||||
|
|
||||||
color: Colors.palette.m3onSurfaceVariant
|
color: Colors.palette.m3onSurfaceVariant
|
||||||
|
visible: root.icon !== ""
|
||||||
fill: 1
|
fill: 1
|
||||||
|
text: root.icon
|
||||||
font.pointSize: Tokens.font.size.normal
|
font.pointSize: Tokens.font.size.normal
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,6 +81,26 @@ ConnectedRect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
active: root.activeItem && root.subtext
|
||||||
|
asynchronous: true
|
||||||
|
visible: active
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
sourceComponent: CustomRect {
|
||||||
|
color: Colors.palette.m3secondaryContainer
|
||||||
|
radius: Tokens.rounding.full
|
||||||
|
implicitWidth: text.implicitWidth + Tokens.padding.medium * 2
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: text
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: Colors.palette.m3onSecondaryContainer
|
||||||
|
text: root.activeItem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
active: root.trailingIcon
|
active: root.trailingIcon
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import Quickshell
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import ZShell.Config
|
||||||
|
import qs.Components
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
|
DialogRowButton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property var model
|
||||||
|
property var selectedItem
|
||||||
|
property var initialSelect
|
||||||
|
|
||||||
|
acceptAllowed: !!selectedItem
|
||||||
|
horizontalContentMargin: -Tokens.padding.extraSmall
|
||||||
|
separateContent: true
|
||||||
|
|
||||||
|
content: Component {
|
||||||
|
ColumnLayout {
|
||||||
|
VerticalFadeListView {
|
||||||
|
bottomMargin: Tokens.padding.large
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
model: ScriptModel {
|
||||||
|
values: {
|
||||||
|
const s = searchField.text;
|
||||||
|
var regex = new RegExp(s, "i");
|
||||||
|
|
||||||
|
return root.model.filter(n => regex.test(n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spacing: 0
|
||||||
|
topMargin: Tokens.padding.large
|
||||||
|
|
||||||
|
delegate: CustomRect {
|
||||||
|
id: item
|
||||||
|
|
||||||
|
required property var modelData
|
||||||
|
readonly property bool selected: root.selectedItem === modelData
|
||||||
|
|
||||||
|
anchors.left: ListView.view.contentItem.left
|
||||||
|
anchors.margins: 1 // Gets cut off for some reason without this
|
||||||
|
anchors.right: ListView.view.contentItem.right
|
||||||
|
color: Qt.alpha(Colors.palette.m3tertiaryContainer, selected ? 1 : 0)
|
||||||
|
implicitHeight: label.implicitHeight + Tokens.padding.small * 2
|
||||||
|
radius: stateLayer.pressed ? Tokens.rounding.extraSmall : selected ? Tokens.rounding.largeIncreased : Tokens.rounding.medium
|
||||||
|
|
||||||
|
Behavior on radius {
|
||||||
|
Anim {
|
||||||
|
type: Anim.SlowEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StateLayer {
|
||||||
|
id: stateLayer
|
||||||
|
|
||||||
|
onClicked: root.selectedItem = item.modelData
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: label
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.margins: Tokens.padding.large
|
||||||
|
anchors.right: item.selected ? checkIcon.left : parent.right
|
||||||
|
anchors.rightMargin: item.selected ? Tokens.spacing.medium : anchors.margins
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: item.selected ? Colors.palette.m3onTertiaryContainer : Colors.palette.m3onSurface
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font.pointSize: Tokens.font.size.smaller
|
||||||
|
text: item.modelData
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
id: checkIcon
|
||||||
|
|
||||||
|
anchors.margins: Tokens.padding.large
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: Colors.palette.m3onTertiaryContainer
|
||||||
|
font.pointSize: Tokens.font.size.normal
|
||||||
|
opacity: item.selected ? 1 : 0
|
||||||
|
text: "check"
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {
|
||||||
|
type: Anim.SlowEffects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchBar {
|
||||||
|
id: searchField
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
bg.border.color: Colors.palette.m3outlineVariant
|
||||||
|
bg.color: Colors.tPalette.m3surfaceContainerLowest
|
||||||
|
clearIcon.font.pointSize: Tokens.font.size.large
|
||||||
|
clearIcon.padding: Tokens.padding.extraSmall
|
||||||
|
font.pointSize: Tokens.font.size.small
|
||||||
|
placeholderText: qsTr("Search...")
|
||||||
|
searchIcon.anchors.leftMargin: Tokens.padding.large
|
||||||
|
searchIcon.font.pointSize: Tokens.font.size.large
|
||||||
|
|
||||||
|
Behavior on bg.border.color {
|
||||||
|
CAnim {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onOpenChanged: {
|
||||||
|
if (open) {
|
||||||
|
root.rootParent.interactive = false;
|
||||||
|
if (!initialSelect)
|
||||||
|
selectedItem = null;
|
||||||
|
else
|
||||||
|
selectedItem = initialSelect;
|
||||||
|
} else {
|
||||||
|
root.rootParent.interactive = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,249 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import ZShell.Blobs
|
||||||
|
import qs.Components
|
||||||
|
import ZShell.Config
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool acceptAllowed: true
|
||||||
|
required property string acceptLabel
|
||||||
|
required property Component content
|
||||||
|
required property string header
|
||||||
|
property int horizontalContentMargin
|
||||||
|
property string icon
|
||||||
|
required property string label
|
||||||
|
property alias iconLabel: openButton.iconText
|
||||||
|
property alias rowButton: openButton
|
||||||
|
property alias contentItem: dialogContent.item
|
||||||
|
property string subtext: ""
|
||||||
|
property bool open
|
||||||
|
property real openHeight: Math.min(rootParent.height * 0.8, 400)
|
||||||
|
property real openWidth: Math.min(rootParent.width * 0.8, 600)
|
||||||
|
required property Item rootParent
|
||||||
|
property bool first: false
|
||||||
|
property bool last: false
|
||||||
|
required property string settingAnchor
|
||||||
|
property color openColor: Colors.palette.m3surfaceContainerHighest
|
||||||
|
|
||||||
|
signal accepted
|
||||||
|
signal cancelled
|
||||||
|
|
||||||
|
function reparentWrapper(): void {
|
||||||
|
const newParent = open ? rootParent : root;
|
||||||
|
const pos = dialogWrapper.mapToItem(newParent, 0, 0);
|
||||||
|
dialogWrapper.parent = newParent;
|
||||||
|
dialogWrapper.x = pos.x;
|
||||||
|
dialogWrapper.y = pos.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: openButton.implicitHeight
|
||||||
|
z: open || dialogTransition.running ? 2 : 0
|
||||||
|
|
||||||
|
BlobGroup {
|
||||||
|
id: blobGroup
|
||||||
|
|
||||||
|
color: root.open ? root.openColor : Colors.tPalette.m3surfaceContainer
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
CAnim {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: backdrop
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: false
|
||||||
|
hoverEnabled: enabled
|
||||||
|
preventStealing: true
|
||||||
|
parent: root.open ? root.rootParent : root
|
||||||
|
|
||||||
|
onClicked: root.open = false
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: dialogWrapper
|
||||||
|
|
||||||
|
height: openButton.implicitHeight
|
||||||
|
width: root.width
|
||||||
|
z: 1
|
||||||
|
|
||||||
|
states: State {
|
||||||
|
name: "open"
|
||||||
|
when: root.open
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
backdrop.enabled: true
|
||||||
|
dialogBg.bottomLeftRadius: Tokens.rounding.largeIncreased
|
||||||
|
dialogBg.bottomRightRadius: Tokens.rounding.largeIncreased
|
||||||
|
dialogBg.topRightRadius: Tokens.rounding.largeIncreased
|
||||||
|
dialogBg.topLeftRadius: Tokens.rounding.largeIncreased
|
||||||
|
dialogContent.opacity: 1
|
||||||
|
dialogWrapper.height: root.openHeight
|
||||||
|
dialogWrapper.width: root.openWidth
|
||||||
|
dialogWrapper.x: (root.rootParent.width - root.openWidth) / 2
|
||||||
|
dialogWrapper.y: (root.rootParent.height - root.openHeight) / 2
|
||||||
|
elevation.opacity: 1
|
||||||
|
openButton.opacity: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
transitions: Transition {
|
||||||
|
id: dialogTransition
|
||||||
|
|
||||||
|
SequentialAnimation {
|
||||||
|
ScriptAction {
|
||||||
|
script: root.reparentWrapper()
|
||||||
|
}
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
properties: "x,y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyAction {
|
||||||
|
property: "enabled"
|
||||||
|
}
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
properties: "opacity,topLeftRadius,topRightRadius,bottomLeftRadius,bottomRightRadius"
|
||||||
|
type: Anim.DefaultEffects
|
||||||
|
}
|
||||||
|
|
||||||
|
Anim {
|
||||||
|
properties: "width,height"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Elevation {
|
||||||
|
id: elevation
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
bottomLeftRadius: dialogBg.bottomLeftRadius
|
||||||
|
bottomRightRadius: dialogBg.bottomRightRadius
|
||||||
|
level: 4
|
||||||
|
opacity: 0
|
||||||
|
radius: dialogBg.radius
|
||||||
|
|
||||||
|
transform: Matrix4x4 {
|
||||||
|
matrix: dialogBg.deformMatrix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BlobRect {
|
||||||
|
id: dialogBg
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
bottomLeftRadius: root.last ? Tokens.rounding.largeIncreased : Tokens.rounding.extraSmall
|
||||||
|
bottomRightRadius: root.last ? Tokens.rounding.largeIncreased : Tokens.rounding.extraSmall
|
||||||
|
topRightRadius: root.first ? Tokens.rounding.largeIncreased : Tokens.rounding.extraSmall
|
||||||
|
topLeftRadius: root.first ? Tokens.rounding.largeIncreased : Tokens.rounding.extraSmall
|
||||||
|
deformScale: 0
|
||||||
|
group: blobGroup
|
||||||
|
opacity: blobGroup.color.a * (root.enabled ? 1 : 0.5)
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeDialogToggle {
|
||||||
|
id: openButton
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
color: "transparent"
|
||||||
|
height: Math.min(implicitHeight, parent.height)
|
||||||
|
subtext: root.subtext
|
||||||
|
last: root.last
|
||||||
|
first: root.first
|
||||||
|
text: root.label
|
||||||
|
|
||||||
|
transform: Matrix4x4 {
|
||||||
|
matrix: dialogBg.deformMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: root.open = true
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: dialogContent
|
||||||
|
|
||||||
|
active: opacity > 0
|
||||||
|
anchors.fill: parent
|
||||||
|
asynchronous: false
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
sourceComponent: MouseArea {
|
||||||
|
onWheel: event => event.accepted = true
|
||||||
|
preventStealing: true
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
cursorShape: undefined
|
||||||
|
enabled: dialogContent.opacity > 0
|
||||||
|
clip: true
|
||||||
|
implicitWidth: innerLayout.implicitWidth + innerLayout.anchors.margins * 2
|
||||||
|
implicitHeight: innerLayout.implicitHeight + innerLayout.anchors.margins + innerLayout.anchors.bottomMargin
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: innerLayout
|
||||||
|
anchors.bottomMargin: Tokens.padding.largeIncreased
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Tokens.padding.extraLarge
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
font.pointSize: Tokens.font.size.large
|
||||||
|
text: root.header
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: root.horizontalContentMargin
|
||||||
|
Layout.topMargin: Tokens.spacing.medium
|
||||||
|
Layout.bottomMargin: Tokens.spacing.medium
|
||||||
|
Layout.rightMargin: root.horizontalContentMargin
|
||||||
|
sourceComponent: root.content
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
spacing: Tokens.spacing.extraSmall
|
||||||
|
|
||||||
|
TextButton {
|
||||||
|
horizontalPadding: Tokens.padding.largeIncreased
|
||||||
|
isRound: true
|
||||||
|
text: qsTr("Cancel")
|
||||||
|
type: TextButton.Text
|
||||||
|
verticalPadding: Tokens.padding.small
|
||||||
|
stateLayer.preventStealing: true
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
root.cancelled();
|
||||||
|
root.open = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextButton {
|
||||||
|
enabled: root.acceptAllowed
|
||||||
|
horizontalPadding: Tokens.padding.largeIncreased
|
||||||
|
isRound: true
|
||||||
|
text: root.acceptLabel
|
||||||
|
type: TextButton.Text
|
||||||
|
stateLayer.preventStealing: true
|
||||||
|
verticalPadding: Tokens.padding.small
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
root.accepted();
|
||||||
|
root.open = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
transform: Matrix4x4 {
|
||||||
|
matrix: dialogBg.deformMatrix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import ZShell.Config
|
||||||
|
import qs.Helpers
|
||||||
|
import qs.Components
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
|
TimeDialogRow {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property int start
|
||||||
|
required property int end
|
||||||
|
property int endCurrent
|
||||||
|
property int startCurrent
|
||||||
|
openColor: Colors.palette.m3surfaceContainer
|
||||||
|
openHeight: Math.min(rootParent.height * 0.8, contentItem?.implicitHeight ?? 0)
|
||||||
|
openWidth: Math.min(rootParent.width * 0.8, contentItem?.implicitWidth ?? 0)
|
||||||
|
|
||||||
|
function keyFor(item: var): string {
|
||||||
|
return item.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function labelFor(item: var): string {
|
||||||
|
return item.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
horizontalContentMargin: -Tokens.padding.extraSmall
|
||||||
|
|
||||||
|
content: Component {
|
||||||
|
TimeInput {
|
||||||
|
id: timeContent
|
||||||
|
start: root.start
|
||||||
|
end: root.end
|
||||||
|
|
||||||
|
onEndEdit: value => root.endCurrent = value
|
||||||
|
onStartEdit: value => root.startCurrent = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onOpenChanged: {
|
||||||
|
if (open) {
|
||||||
|
root.rootParent.interactive = false;
|
||||||
|
root.z = 5;
|
||||||
|
} else {
|
||||||
|
root.rootParent.interactive = true;
|
||||||
|
root.z = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
-5
@@ -10,12 +10,14 @@ ConnectedRect {
|
|||||||
|
|
||||||
property alias checked: switchButton.checked
|
property alias checked: switchButton.checked
|
||||||
property int horizontalPadding: Tokens.padding.largeIncreased
|
property int horizontalPadding: Tokens.padding.largeIncreased
|
||||||
required property Component popup
|
|
||||||
property alias subtext: subtext.text
|
property alias subtext: subtext.text
|
||||||
property alias text: text.text
|
property alias text: text.text
|
||||||
|
property alias icon: icon
|
||||||
|
property string iconText: "open_in_new"
|
||||||
property int verticalPadding: Tokens.padding.small
|
property int verticalPadding: Tokens.padding.small
|
||||||
|
|
||||||
signal clicked(checked: bool)
|
signal clicked
|
||||||
|
signal toggled(checked: bool)
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
implicitHeight: layout.implicitHeight + verticalPadding * 2
|
implicitHeight: layout.implicitHeight + verticalPadding * 2
|
||||||
@@ -50,11 +52,11 @@ ConnectedRect {
|
|||||||
anchors.right: switchButton.left
|
anchors.right: switchButton.left
|
||||||
anchors.rightMargin: Tokens.spacing.medium
|
anchors.rightMargin: Tokens.spacing.medium
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: "open_in_new"
|
text: root.iconText
|
||||||
}
|
}
|
||||||
|
|
||||||
StateLayer {
|
StateLayer {
|
||||||
onClicked: PopupManager.requestOpen(root.popup)
|
onClicked: root.clicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomSwitch {
|
CustomSwitch {
|
||||||
@@ -64,6 +66,6 @@ ConnectedRect {
|
|||||||
anchors.rightMargin: root.horizontalPadding
|
anchors.rightMargin: root.horizontalPadding
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
onClicked: root.clicked(checked)
|
onClicked: root.toggled(checked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,15 +6,13 @@ import qs.Components
|
|||||||
import qs.Helpers
|
import qs.Helpers
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
|
||||||
CustomClippingRect {
|
ColumnLayout {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
required property var object
|
required property int start
|
||||||
required property list<string> settings
|
required property int end
|
||||||
property bool shouldBeActive: true
|
signal endEdit(time: int)
|
||||||
|
signal startEdit(time: int)
|
||||||
signal applySettings(startTime: int, endTime: int)
|
|
||||||
signal close
|
|
||||||
|
|
||||||
function convertHour(timeValue: int): int {
|
function convertHour(timeValue: int): int {
|
||||||
return Math.floor(timeValue / 60);
|
return Math.floor(timeValue / 60);
|
||||||
@@ -28,555 +26,459 @@ CustomClippingRect {
|
|||||||
return hour * 60 + minute;
|
return hour * 60 + minute;
|
||||||
}
|
}
|
||||||
|
|
||||||
color: Colors.palette.m3surfaceContainer
|
spacing: Tokens.spacing.medium
|
||||||
implicitHeight: column.implicitHeight + column.anchors.margins * 2 + buttonRow.implicitHeight + buttonRow.anchors.topMargin
|
|
||||||
implicitWidth: column.implicitWidth + column.anchors.margins * 2
|
|
||||||
radius: Tokens.rounding.largeIncreased
|
|
||||||
|
|
||||||
ColumnLayout {
|
RowLayout {
|
||||||
id: column
|
CustomRect {
|
||||||
|
id: startHourRect
|
||||||
|
|
||||||
anchors.left: parent.left
|
Layout.preferredHeight: 72
|
||||||
anchors.margins: Tokens.padding.largeIncreased
|
Layout.preferredWidth: 96
|
||||||
anchors.right: parent.right
|
color: startHourField.focus ? Colors.palette.m3onPrimaryContainer : Colors.palette.m3surfaceContainerHighest
|
||||||
anchors.top: parent.top
|
implicitHeight: 72
|
||||||
spacing: Tokens.spacing.medium
|
implicitWidth: 96
|
||||||
|
radius: Tokens.rounding.small
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
anchors.fill: parent
|
||||||
|
border.color: startHourField.focus ? Colors.palette.m3primaryContainer : Colors.palette.m3surfaceContainerHighest
|
||||||
|
border.width: startHourField.focus ? 2 : 0
|
||||||
|
radius: parent.radius - border.width
|
||||||
|
|
||||||
|
Behavior on border.width {
|
||||||
|
Anim {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldBase {
|
||||||
|
id: startHourField
|
||||||
|
|
||||||
|
function setConfigText(): string {
|
||||||
|
var val = root.convertHour(root.start);
|
||||||
|
if (val === 0) {
|
||||||
|
return "00";
|
||||||
|
}
|
||||||
|
return String(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
clip: true
|
||||||
|
color: focus ? Colors.palette.m3primaryContainer : Colors.palette.m3onSurface
|
||||||
|
font.family: "Roboto"
|
||||||
|
font.letterSpacing: -0.25
|
||||||
|
font.pixelSize: 56
|
||||||
|
font.weight: 400
|
||||||
|
horizontalAlignment: TextInput.AlignHCenter
|
||||||
|
text: setConfigText()
|
||||||
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
|
|
||||||
|
Keys.onPressed: event => {
|
||||||
|
if (event.key === Qt.Key_Backspace) {
|
||||||
|
event.accepted = true;
|
||||||
|
if (startHourField.text.length >= 2) {
|
||||||
|
startHourField.text = "0" + startHourField.text[0];
|
||||||
|
} else if (startHourField.text.length === 1) {
|
||||||
|
startHourField.text = "0";
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (event.key === Qt.Key_Escape) {
|
||||||
|
event.accepted = true;
|
||||||
|
startHourField.text = setConfigText();
|
||||||
|
startHourField.focus = false;
|
||||||
|
} else if (event.key === Qt.Key_Return) {
|
||||||
|
startHourField.focus = false;
|
||||||
|
return;
|
||||||
|
} else if (event.key === Qt.Key_Tab) {
|
||||||
|
startMinuteField.focus = true;
|
||||||
|
} else if (event.key === Qt.Key_Backtab) {
|
||||||
|
endMinuteField.focus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.text.length === 1 && event.text >= "0" && event.text <= "9") {
|
||||||
|
event.accepted = true;
|
||||||
|
var digit = event.text;
|
||||||
|
var textLen = startHourField.text.length;
|
||||||
|
|
||||||
|
if (textLen >= 2 && startHourField.text[0] !== '0') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var val = 0;
|
||||||
|
if (textLen === 0) {
|
||||||
|
val = parseInt(digit);
|
||||||
|
} else if (textLen === 1) {
|
||||||
|
val = parseInt(startHourField.text + digit);
|
||||||
|
} else {
|
||||||
|
val = parseInt(startHourField.text[1] + digit);
|
||||||
|
}
|
||||||
|
|
||||||
|
val = Math.max(0, Math.min(23, val));
|
||||||
|
|
||||||
|
if (textLen >= 2 && val < 10) {
|
||||||
|
startHourField.text = "0" + val;
|
||||||
|
} else {
|
||||||
|
startHourField.text = val.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
|
onCursorPositionChanged: cursorPosition = 2
|
||||||
|
onTextChanged: {
|
||||||
|
var mins = parseInt(startMinuteField.text);
|
||||||
|
const hours = root.convertToMinutes(parseInt(startHourField.text));
|
||||||
|
root.startEdit(hours + mins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CustomText {
|
CustomText {
|
||||||
text: qsTr("Select time")
|
id: startSeparator
|
||||||
|
|
||||||
|
font.pointSize: Tokens.font.size.extraLarge
|
||||||
|
text: ":"
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
CustomRect {
|
||||||
CustomRect {
|
id: startMinuteRect
|
||||||
id: startHourRect
|
|
||||||
|
|
||||||
Layout.preferredHeight: 72
|
Layout.preferredHeight: 72
|
||||||
Layout.preferredWidth: 96
|
Layout.preferredWidth: 96
|
||||||
color: startHourField.focus ? Colors.palette.m3onPrimaryContainer : Colors.palette.m3surfaceContainerHighest
|
color: startMinuteField.focus ? Colors.palette.m3onPrimaryContainer : Colors.palette.m3surfaceContainerHighest
|
||||||
implicitHeight: 72
|
implicitHeight: 72
|
||||||
implicitWidth: 96
|
implicitWidth: 96
|
||||||
radius: Tokens.rounding.small
|
radius: Tokens.rounding.small
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
anchors.fill: parent
|
|
||||||
border.color: startHourField.focus ? Colors.palette.m3primaryContainer : Colors.palette.m3surfaceContainerHighest
|
|
||||||
border.width: startHourField.focus ? 2 : 0
|
|
||||||
radius: parent.radius - border.width
|
|
||||||
|
|
||||||
Behavior on border.width {
|
|
||||||
Anim {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextFieldBase {
|
|
||||||
id: startHourField
|
|
||||||
|
|
||||||
function setConfigText(setting: string): string {
|
|
||||||
var val = root.convertHour(root.object[setting]);
|
|
||||||
if (val === 0) {
|
|
||||||
return "00";
|
|
||||||
}
|
|
||||||
return String(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
clip: true
|
|
||||||
color: focus ? Colors.palette.m3primaryContainer : Colors.palette.m3onSurface
|
|
||||||
font.family: "Roboto"
|
|
||||||
font.letterSpacing: -0.25
|
|
||||||
font.pixelSize: 56
|
|
||||||
font.weight: 400
|
|
||||||
horizontalAlignment: TextInput.AlignHCenter
|
|
||||||
text: setConfigText(root.settings[1])
|
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
|
||||||
|
|
||||||
Keys.onPressed: event => {
|
|
||||||
if (event.key === Qt.Key_Backspace) {
|
|
||||||
event.accepted = true;
|
|
||||||
if (startHourField.text.length >= 2) {
|
|
||||||
startHourField.text = "0" + startHourField.text[0];
|
|
||||||
} else if (startHourField.text.length === 1) {
|
|
||||||
startHourField.text = "0";
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} else if (event.key === Qt.Key_Escape) {
|
|
||||||
event.accepted = true;
|
|
||||||
startHourField.text = setConfigText(root.settings[1]);
|
|
||||||
startHourField.focus = false;
|
|
||||||
} else if (event.key === Qt.Key_Return) {
|
|
||||||
startHourField.focus = false;
|
|
||||||
return;
|
|
||||||
} else if (event.key === Qt.Key_Tab) {
|
|
||||||
startMinuteField.focus = true;
|
|
||||||
} else if (event.key === Qt.Key_Backtab) {
|
|
||||||
endMinuteField.focus = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.text.length === 1 && event.text >= "0" && event.text <= "9") {
|
|
||||||
event.accepted = true;
|
|
||||||
var digit = event.text;
|
|
||||||
var textLen = startHourField.text.length;
|
|
||||||
|
|
||||||
if (textLen >= 2 && startHourField.text[0] !== '0') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var val = 0;
|
|
||||||
if (textLen === 0) {
|
|
||||||
val = parseInt(digit);
|
|
||||||
} else if (textLen === 1) {
|
|
||||||
val = parseInt(startHourField.text + digit);
|
|
||||||
} else {
|
|
||||||
val = parseInt(startHourField.text[1] + digit);
|
|
||||||
}
|
|
||||||
|
|
||||||
val = Math.max(0, Math.min(23, val));
|
|
||||||
|
|
||||||
if (textLen >= 2 && val < 10) {
|
|
||||||
startHourField.text = "0" + val;
|
|
||||||
} else {
|
|
||||||
startHourField.text = val.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
event.accepted = true;
|
|
||||||
}
|
|
||||||
onCursorPositionChanged: cursorPosition = 2
|
|
||||||
onTextEdited: {
|
|
||||||
if (startHourField.text === "")
|
|
||||||
return;
|
|
||||||
var val = parseInt(startHourField.text);
|
|
||||||
if (isNaN(val))
|
|
||||||
return;
|
|
||||||
val = Math.max(0, Math.min(23, val));
|
|
||||||
var newText = val.toString();
|
|
||||||
if (newText !== startHourField.text)
|
|
||||||
startHourField.text = newText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomText {
|
|
||||||
id: startSeparator
|
|
||||||
|
|
||||||
font.pointSize: Tokens.font.size.extraLarge
|
|
||||||
text: ":"
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomRect {
|
CustomRect {
|
||||||
id: startMinuteRect
|
anchors.fill: parent
|
||||||
|
border.color: startMinuteField.focus ? Colors.palette.m3primaryContainer : Colors.palette.m3surfaceContainerHighest
|
||||||
|
border.width: startMinuteField.focus ? 2 : 0
|
||||||
|
radius: parent.radius - border.width
|
||||||
|
|
||||||
Layout.preferredHeight: 72
|
Behavior on border.width {
|
||||||
Layout.preferredWidth: 96
|
Anim {}
|
||||||
color: startMinuteField.focus ? Colors.palette.m3onPrimaryContainer : Colors.palette.m3surfaceContainerHighest
|
}
|
||||||
implicitHeight: 72
|
}
|
||||||
implicitWidth: 96
|
|
||||||
radius: Tokens.rounding.small
|
|
||||||
|
|
||||||
CustomRect {
|
TextFieldBase {
|
||||||
anchors.fill: parent
|
id: startMinuteField
|
||||||
border.color: startMinuteField.focus ? Colors.palette.m3primaryContainer : Colors.palette.m3surfaceContainerHighest
|
|
||||||
border.width: startMinuteField.focus ? 2 : 0
|
|
||||||
radius: parent.radius - border.width
|
|
||||||
|
|
||||||
Behavior on border.width {
|
function setConfigText(): string {
|
||||||
Anim {
|
var val = root.convertMinute(root.start);
|
||||||
}
|
if (val === 0) {
|
||||||
|
return "00";
|
||||||
}
|
}
|
||||||
|
return String(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextFieldBase {
|
anchors.left: parent.left
|
||||||
id: startMinuteField
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
function setConfigText(setting: string): string {
|
clip: true
|
||||||
var val = root.convertMinute(root.object[setting]);
|
color: focus ? Colors.palette.m3primaryContainer : Colors.palette.m3onSurface
|
||||||
if (val === 0) {
|
font.family: "Roboto"
|
||||||
return "00";
|
font.letterSpacing: -0.25
|
||||||
}
|
font.pixelSize: 56
|
||||||
return String(val);
|
font.weight: 400
|
||||||
}
|
horizontalAlignment: TextInput.AlignHCenter
|
||||||
|
text: setConfigText()
|
||||||
anchors.left: parent.left
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
clip: true
|
|
||||||
color: focus ? Colors.palette.m3primaryContainer : Colors.palette.m3onSurface
|
|
||||||
font.family: "Roboto"
|
|
||||||
font.letterSpacing: -0.25
|
|
||||||
font.pixelSize: 56
|
|
||||||
font.weight: 400
|
|
||||||
horizontalAlignment: TextInput.AlignHCenter
|
|
||||||
text: setConfigText(root.settings[1])
|
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
|
||||||
|
|
||||||
Keys.onPressed: event => {
|
|
||||||
if (event.key === Qt.Key_Backspace) {
|
|
||||||
event.accepted = true;
|
|
||||||
if (startMinuteField.text.length >= 2) {
|
|
||||||
startMinuteField.text = "0" + startMinuteField.text[0];
|
|
||||||
} else if (startMinuteField.text.length === 1) {
|
|
||||||
startMinuteField.text = "0";
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} else if (event.key === Qt.Key_Escape) {
|
|
||||||
event.accepted = true;
|
|
||||||
startMinuteField.text = setConfigText(root.settings[1]);
|
|
||||||
startMinuteField.focus = false;
|
|
||||||
} else if (event.key === Qt.Key_Return) {
|
|
||||||
startMinuteField.focus = false;
|
|
||||||
return;
|
|
||||||
} else if (event.key === Qt.Key_Tab) {
|
|
||||||
endHourField.focus = true;
|
|
||||||
} else if (event.key === Qt.Key_Backtab) {
|
|
||||||
startHourField.focus = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.text.length === 1 && event.text >= "0" && event.text <= "9") {
|
|
||||||
event.accepted = true;
|
|
||||||
var digit = event.text;
|
|
||||||
var textLen = startMinuteField.text.length;
|
|
||||||
|
|
||||||
if (textLen >= 2 && startMinuteField.text[0] !== '0') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var val = 0;
|
|
||||||
if (textLen === 0) {
|
|
||||||
val = parseInt(digit);
|
|
||||||
} else if (textLen === 1) {
|
|
||||||
val = parseInt(startMinuteField.text + digit);
|
|
||||||
} else {
|
|
||||||
val = parseInt(startMinuteField.text[1] + digit);
|
|
||||||
}
|
|
||||||
|
|
||||||
val = Math.max(0, Math.min(59, val));
|
|
||||||
|
|
||||||
if (textLen >= 2 && val < 10) {
|
|
||||||
startMinuteField.text = "0" + val;
|
|
||||||
} else {
|
|
||||||
startMinuteField.text = val.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Keys.onPressed: event => {
|
||||||
|
if (event.key === Qt.Key_Backspace) {
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
}
|
if (startMinuteField.text.length >= 2) {
|
||||||
onCursorPositionChanged: cursorPosition = 2
|
startMinuteField.text = "0" + startMinuteField.text[0];
|
||||||
onTextEdited: {
|
} else if (startMinuteField.text.length === 1) {
|
||||||
if (startMinuteField.text === "")
|
startMinuteField.text = "0";
|
||||||
return;
|
|
||||||
var val = parseInt(startMinuteField.text);
|
|
||||||
if (isNaN(val))
|
|
||||||
return;
|
|
||||||
val = Math.max(0, Math.min(23, val));
|
|
||||||
var newText = val.toString();
|
|
||||||
if (newText !== startMinuteField.text)
|
|
||||||
startMinuteField.text = newText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: spacer
|
|
||||||
|
|
||||||
Layout.preferredWidth: Tokens.spacing.largeIncreased
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
id: endHourRect
|
|
||||||
|
|
||||||
Layout.preferredHeight: 72
|
|
||||||
Layout.preferredWidth: 96
|
|
||||||
color: endHourField.focus ? Colors.palette.m3onPrimaryContainer : Colors.palette.m3surfaceContainerHighest
|
|
||||||
implicitHeight: 72
|
|
||||||
implicitWidth: 96
|
|
||||||
radius: Tokens.rounding.small
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
anchors.fill: parent
|
|
||||||
border.color: endHourField.focus ? Colors.palette.m3primaryContainer : Colors.palette.m3surfaceContainerHighest
|
|
||||||
border.width: endHourField.focus ? 2 : 0
|
|
||||||
radius: parent.radius - border.width
|
|
||||||
|
|
||||||
Behavior on border.width {
|
|
||||||
Anim {
|
|
||||||
}
|
}
|
||||||
}
|
return;
|
||||||
}
|
} else if (event.key === Qt.Key_Escape) {
|
||||||
|
|
||||||
TextFieldBase {
|
|
||||||
id: endHourField
|
|
||||||
|
|
||||||
function setConfigText(setting: string): string {
|
|
||||||
var val = root.convertHour(root.object[setting]);
|
|
||||||
if (val === 0) {
|
|
||||||
return "00";
|
|
||||||
}
|
|
||||||
return String(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
clip: true
|
|
||||||
color: focus ? Colors.palette.m3primaryContainer : Colors.palette.m3onSurface
|
|
||||||
font.family: "Roboto"
|
|
||||||
font.letterSpacing: -0.25
|
|
||||||
font.pixelSize: 56
|
|
||||||
font.weight: 400
|
|
||||||
horizontalAlignment: TextInput.AlignHCenter
|
|
||||||
text: setConfigText(root.settings[2])
|
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
|
||||||
|
|
||||||
Keys.onPressed: event => {
|
|
||||||
if (event.key === Qt.Key_Backspace) {
|
|
||||||
event.accepted = true;
|
|
||||||
if (endHourField.text.length >= 2) {
|
|
||||||
endHourField.text = "0" + endHourField.text[0];
|
|
||||||
} else if (endHourField.text.length === 1) {
|
|
||||||
endHourField.text = "0";
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} else if (event.key === Qt.Key_Escape) {
|
|
||||||
event.accepted = true;
|
|
||||||
endHourField.text = setConfigText(root.settings[2]);
|
|
||||||
endHourField.focus = false;
|
|
||||||
} else if (event.key === Qt.Key_Return) {
|
|
||||||
endHourField.focus = false;
|
|
||||||
return;
|
|
||||||
} else if (event.key === Qt.Key_Tab) {
|
|
||||||
endMinuteField.focus = true;
|
|
||||||
} else if (event.key === Qt.Key_Backtab) {
|
|
||||||
startMinuteField.focus = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.text.length === 1 && event.text >= "0" && event.text <= "9") {
|
|
||||||
event.accepted = true;
|
|
||||||
var digit = event.text;
|
|
||||||
var textLen = endHourField.text.length;
|
|
||||||
|
|
||||||
if (textLen >= 2 && endHourField.text[0] !== '0') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var val = 0;
|
|
||||||
if (textLen === 0) {
|
|
||||||
val = parseInt(digit);
|
|
||||||
} else if (textLen === 1) {
|
|
||||||
val = parseInt(endHourField.text + digit);
|
|
||||||
} else {
|
|
||||||
val = parseInt(endHourField.text[1] + digit);
|
|
||||||
}
|
|
||||||
|
|
||||||
val = Math.max(0, Math.min(23, val));
|
|
||||||
|
|
||||||
if (textLen >= 2 && val < 10) {
|
|
||||||
endHourField.text = "0" + val;
|
|
||||||
} else {
|
|
||||||
endHourField.text = val.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
}
|
startMinuteField.text = setConfigText();
|
||||||
onCursorPositionChanged: cursorPosition = 2
|
startMinuteField.focus = false;
|
||||||
onTextEdited: {
|
} else if (event.key === Qt.Key_Return) {
|
||||||
if (endHourField.text === "")
|
startMinuteField.focus = false;
|
||||||
return;
|
return;
|
||||||
var val = parseInt(endHourField.text);
|
} else if (event.key === Qt.Key_Tab) {
|
||||||
if (isNaN(val))
|
endHourField.focus = true;
|
||||||
return;
|
} else if (event.key === Qt.Key_Backtab) {
|
||||||
val = Math.max(0, Math.min(23, val));
|
startHourField.focus = true;
|
||||||
var newText = val.toString();
|
|
||||||
if (newText !== endHourField.text)
|
|
||||||
endHourField.text = newText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomText {
|
|
||||||
id: endSeparator
|
|
||||||
|
|
||||||
font.pointSize: Tokens.font.size.extraLarge
|
|
||||||
text: ":"
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
id: endMinuteRect
|
|
||||||
|
|
||||||
Layout.preferredHeight: 72
|
|
||||||
Layout.preferredWidth: 96
|
|
||||||
color: endMinuteField.focus ? Colors.palette.m3onPrimaryContainer : Colors.palette.m3surfaceContainerHighest
|
|
||||||
implicitHeight: 72
|
|
||||||
implicitWidth: 96
|
|
||||||
radius: Tokens.rounding.small
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
anchors.fill: parent
|
|
||||||
border.color: endMinuteField.focus ? Colors.palette.m3primaryContainer : Colors.palette.m3surfaceContainerHighest
|
|
||||||
border.width: endMinuteField.focus ? 2 : 0
|
|
||||||
radius: parent.radius - border.width
|
|
||||||
|
|
||||||
Behavior on border.width {
|
|
||||||
Anim {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextFieldBase {
|
|
||||||
id: endMinuteField
|
|
||||||
|
|
||||||
function setConfigText(setting: string): string {
|
|
||||||
var val = root.convertMinute(root.object[setting]);
|
|
||||||
if (val === 0) {
|
|
||||||
return "00";
|
|
||||||
}
|
|
||||||
return String(val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
anchors.left: parent.left
|
if (event.text.length === 1 && event.text >= "0" && event.text <= "9") {
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
clip: true
|
|
||||||
color: focus ? Colors.palette.m3primaryContainer : Colors.palette.m3onSurface
|
|
||||||
font.family: "Roboto"
|
|
||||||
font.letterSpacing: -0.25
|
|
||||||
font.pixelSize: 56
|
|
||||||
font.weight: 400
|
|
||||||
horizontalAlignment: TextInput.AlignHCenter
|
|
||||||
text: setConfigText(root.settings[2])
|
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
|
||||||
|
|
||||||
Keys.onPressed: event => {
|
|
||||||
if (event.key === Qt.Key_Backspace) {
|
|
||||||
event.accepted = true;
|
|
||||||
if (endMinuteField.text.length >= 2) {
|
|
||||||
endMinuteField.text = "0" + endMinuteField.text[0];
|
|
||||||
} else if (endMinuteField.text.length === 1) {
|
|
||||||
endMinuteField.text = "0";
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} else if (event.key === Qt.Key_Escape) {
|
|
||||||
event.accepted = true;
|
|
||||||
endMinuteField.text = setConfigText(root.settings[2]);
|
|
||||||
endMinuteField.focus = false;
|
|
||||||
} else if (event.key === Qt.Key_Return) {
|
|
||||||
endMinuteField.focus = false;
|
|
||||||
return;
|
|
||||||
} else if (event.key === Qt.Key_Tab) {
|
|
||||||
startHourField.focus = true;
|
|
||||||
} else if (event.key === Qt.Key_Backtab) {
|
|
||||||
endHourField.focus = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.text.length === 1 && event.text >= "0" && event.text <= "9") {
|
|
||||||
event.accepted = true;
|
|
||||||
var digit = event.text;
|
|
||||||
var textLen = endMinuteField.text.length;
|
|
||||||
|
|
||||||
if (textLen >= 2 && endMinuteField.text[0] !== '0') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var val = 0;
|
|
||||||
if (textLen === 0) {
|
|
||||||
val = parseInt(digit);
|
|
||||||
} else if (textLen === 1) {
|
|
||||||
val = parseInt(endMinuteField.text + digit);
|
|
||||||
} else {
|
|
||||||
val = parseInt(endMinuteField.text[1] + digit);
|
|
||||||
}
|
|
||||||
|
|
||||||
val = Math.max(0, Math.min(59, val));
|
|
||||||
|
|
||||||
if (textLen >= 2 && val < 10) {
|
|
||||||
endMinuteField.text = "0" + val;
|
|
||||||
} else {
|
|
||||||
endMinuteField.text = val.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
}
|
var digit = event.text;
|
||||||
onCursorPositionChanged: cursorPosition = 2
|
var textLen = startMinuteField.text.length;
|
||||||
onTextEdited: {
|
|
||||||
if (endMinuteField.text === "")
|
if (textLen >= 2 && startMinuteField.text[0] !== '0') {
|
||||||
return;
|
return;
|
||||||
var val = parseInt(endMinuteField.text);
|
}
|
||||||
if (isNaN(val))
|
|
||||||
return;
|
var val = 0;
|
||||||
val = Math.max(0, Math.min(23, val));
|
if (textLen === 0) {
|
||||||
var newText = val.toString();
|
val = parseInt(digit);
|
||||||
if (newText !== endMinuteField.text)
|
} else if (textLen === 1) {
|
||||||
endMinuteField.text = newText;
|
val = parseInt(startMinuteField.text + digit);
|
||||||
|
} else {
|
||||||
|
val = parseInt(startMinuteField.text[1] + digit);
|
||||||
|
}
|
||||||
|
|
||||||
|
val = Math.max(0, Math.min(59, val));
|
||||||
|
|
||||||
|
if (textLen >= 2 && val < 10) {
|
||||||
|
startMinuteField.text = "0" + val;
|
||||||
|
} else {
|
||||||
|
startMinuteField.text = val.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
|
onCursorPositionChanged: cursorPosition = 2
|
||||||
|
onTextChanged: {
|
||||||
|
var mins = parseInt(startMinuteField.text);
|
||||||
|
const hours = root.convertToMinutes(parseInt(startHourField.text));
|
||||||
|
root.startEdit(hours + mins);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
Item {
|
||||||
CustomText {
|
id: spacer
|
||||||
Layout.preferredWidth: spacer.x + spacer.width
|
|
||||||
text: qsTr("Start")
|
Layout.preferredWidth: Tokens.spacing.largeIncreased
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
id: endHourRect
|
||||||
|
|
||||||
|
Layout.preferredHeight: 72
|
||||||
|
Layout.preferredWidth: 96
|
||||||
|
color: endHourField.focus ? Colors.palette.m3onPrimaryContainer : Colors.palette.m3surfaceContainerHighest
|
||||||
|
implicitHeight: 72
|
||||||
|
implicitWidth: 96
|
||||||
|
radius: Tokens.rounding.small
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
anchors.fill: parent
|
||||||
|
border.color: endHourField.focus ? Colors.palette.m3primaryContainer : Colors.palette.m3surfaceContainerHighest
|
||||||
|
border.width: endHourField.focus ? 2 : 0
|
||||||
|
radius: parent.radius - border.width
|
||||||
|
|
||||||
|
Behavior on border.width {
|
||||||
|
Anim {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomText {
|
TextFieldBase {
|
||||||
Layout.preferredWidth: endMinuteRect.width + endHourRect.width
|
id: endHourField
|
||||||
text: qsTr("End")
|
|
||||||
|
function setConfigText(): string {
|
||||||
|
var val = root.convertHour(root.end);
|
||||||
|
if (val === 0) {
|
||||||
|
return "00";
|
||||||
|
}
|
||||||
|
return String(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
clip: true
|
||||||
|
color: focus ? Colors.palette.m3primaryContainer : Colors.palette.m3onSurface
|
||||||
|
font.family: "Roboto"
|
||||||
|
font.letterSpacing: -0.25
|
||||||
|
font.pixelSize: 56
|
||||||
|
font.weight: 400
|
||||||
|
horizontalAlignment: TextInput.AlignHCenter
|
||||||
|
text: setConfigText()
|
||||||
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
|
|
||||||
|
Keys.onPressed: event => {
|
||||||
|
if (event.key === Qt.Key_Backspace) {
|
||||||
|
event.accepted = true;
|
||||||
|
if (endHourField.text.length >= 2) {
|
||||||
|
endHourField.text = "0" + endHourField.text[0];
|
||||||
|
} else if (endHourField.text.length === 1) {
|
||||||
|
endHourField.text = "0";
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (event.key === Qt.Key_Escape) {
|
||||||
|
event.accepted = true;
|
||||||
|
endHourField.text = setConfigText();
|
||||||
|
endHourField.focus = false;
|
||||||
|
} else if (event.key === Qt.Key_Return) {
|
||||||
|
endHourField.focus = false;
|
||||||
|
return;
|
||||||
|
} else if (event.key === Qt.Key_Tab) {
|
||||||
|
endMinuteField.focus = true;
|
||||||
|
} else if (event.key === Qt.Key_Backtab) {
|
||||||
|
startMinuteField.focus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.text.length === 1 && event.text >= "0" && event.text <= "9") {
|
||||||
|
event.accepted = true;
|
||||||
|
var digit = event.text;
|
||||||
|
var textLen = endHourField.text.length;
|
||||||
|
|
||||||
|
if (textLen >= 2 && endHourField.text[0] !== '0') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var val = 0;
|
||||||
|
if (textLen === 0) {
|
||||||
|
val = parseInt(digit);
|
||||||
|
} else if (textLen === 1) {
|
||||||
|
val = parseInt(endHourField.text + digit);
|
||||||
|
} else {
|
||||||
|
val = parseInt(endHourField.text[1] + digit);
|
||||||
|
}
|
||||||
|
|
||||||
|
val = Math.max(0, Math.min(23, val));
|
||||||
|
|
||||||
|
if (textLen >= 2 && val < 10) {
|
||||||
|
endHourField.text = "0" + val;
|
||||||
|
} else {
|
||||||
|
endHourField.text = val.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
|
onCursorPositionChanged: cursorPosition = 2
|
||||||
|
onTextChanged: {
|
||||||
|
var mins = parseInt(endMinuteField.text);
|
||||||
|
const hours = root.convertToMinutes(parseInt(endHourField.text));
|
||||||
|
root.endEdit(hours + mins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: endSeparator
|
||||||
|
|
||||||
|
font.pointSize: Tokens.font.size.extraLarge
|
||||||
|
text: ":"
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
id: endMinuteRect
|
||||||
|
|
||||||
|
Layout.preferredHeight: 72
|
||||||
|
Layout.preferredWidth: 96
|
||||||
|
color: endMinuteField.focus ? Colors.palette.m3onPrimaryContainer : Colors.palette.m3surfaceContainerHighest
|
||||||
|
implicitHeight: 72
|
||||||
|
implicitWidth: 96
|
||||||
|
radius: Tokens.rounding.small
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
anchors.fill: parent
|
||||||
|
border.color: endMinuteField.focus ? Colors.palette.m3primaryContainer : Colors.palette.m3surfaceContainerHighest
|
||||||
|
border.width: endMinuteField.focus ? 2 : 0
|
||||||
|
radius: parent.radius - border.width
|
||||||
|
|
||||||
|
Behavior on border.width {
|
||||||
|
Anim {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldBase {
|
||||||
|
id: endMinuteField
|
||||||
|
|
||||||
|
function setConfigText(): string {
|
||||||
|
var val = root.convertMinute(root.end);
|
||||||
|
if (val === 0) {
|
||||||
|
return "00";
|
||||||
|
}
|
||||||
|
return String(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
clip: true
|
||||||
|
color: focus ? Colors.palette.m3primaryContainer : Colors.palette.m3onSurface
|
||||||
|
font.family: "Roboto"
|
||||||
|
font.letterSpacing: -0.25
|
||||||
|
font.pixelSize: 56
|
||||||
|
font.weight: 400
|
||||||
|
horizontalAlignment: TextInput.AlignHCenter
|
||||||
|
text: setConfigText()
|
||||||
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
|
|
||||||
|
Keys.onPressed: event => {
|
||||||
|
if (event.key === Qt.Key_Backspace) {
|
||||||
|
event.accepted = true;
|
||||||
|
if (endMinuteField.text.length >= 2) {
|
||||||
|
endMinuteField.text = "0" + endMinuteField.text[0];
|
||||||
|
} else if (endMinuteField.text.length === 1) {
|
||||||
|
endMinuteField.text = "0";
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (event.key === Qt.Key_Escape) {
|
||||||
|
event.accepted = true;
|
||||||
|
endMinuteField.text = setConfigText();
|
||||||
|
endMinuteField.focus = false;
|
||||||
|
} else if (event.key === Qt.Key_Return) {
|
||||||
|
endMinuteField.focus = false;
|
||||||
|
return;
|
||||||
|
} else if (event.key === Qt.Key_Tab) {
|
||||||
|
startHourField.focus = true;
|
||||||
|
} else if (event.key === Qt.Key_Backtab) {
|
||||||
|
endHourField.focus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.text.length === 1 && event.text >= "0" && event.text <= "9") {
|
||||||
|
event.accepted = true;
|
||||||
|
var digit = event.text;
|
||||||
|
var textLen = endMinuteField.text.length;
|
||||||
|
|
||||||
|
if (textLen >= 2 && endMinuteField.text[0] !== '0') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var val = 0;
|
||||||
|
if (textLen === 0) {
|
||||||
|
val = parseInt(digit);
|
||||||
|
} else if (textLen === 1) {
|
||||||
|
val = parseInt(endMinuteField.text + digit);
|
||||||
|
} else {
|
||||||
|
val = parseInt(endMinuteField.text[1] + digit);
|
||||||
|
}
|
||||||
|
|
||||||
|
val = Math.max(0, Math.min(59, val));
|
||||||
|
|
||||||
|
if (textLen >= 2 && val < 10) {
|
||||||
|
endMinuteField.text = "0" + val;
|
||||||
|
} else {
|
||||||
|
endMinuteField.text = val.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
|
onCursorPositionChanged: cursorPosition = 2
|
||||||
|
onTextChanged: {
|
||||||
|
var mins = parseInt(endMinuteField.text);
|
||||||
|
const hours = root.convertToMinutes(parseInt(endHourField.text));
|
||||||
|
root.endEdit(hours + mins);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: buttonRow
|
CustomText {
|
||||||
|
Layout.preferredWidth: spacer.x + spacer.width
|
||||||
anchors.bottom: parent.bottom
|
text: qsTr("Start")
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.margins: Tokens.padding.largeIncreased
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: column.bottom
|
|
||||||
anchors.topMargin: Tokens.spacing.medium
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: buttonSpacer
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ButtonRow {
|
CustomText {
|
||||||
spacing: Tokens.spacing.medium
|
Layout.preferredWidth: endMinuteRect.width + endHourRect.width
|
||||||
|
text: qsTr("End")
|
||||||
IconTextButton {
|
|
||||||
font.pointSize: Tokens.font.size.normal
|
|
||||||
icon: "close"
|
|
||||||
inactiveColor: Colors.layer(Colors.palette.m3surfaceContainerHighest, 2)
|
|
||||||
inactiveOnColor: Colors.palette.m3onSurfaceVariant
|
|
||||||
isRound: true
|
|
||||||
isToggle: false
|
|
||||||
shapeMorph: true
|
|
||||||
shapeMorphExpansion: pressed ? 12 : 0
|
|
||||||
text: "Cancel"
|
|
||||||
|
|
||||||
onClicked: root.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
IconTextButton {
|
|
||||||
font.pointSize: Tokens.font.size.normal
|
|
||||||
icon: "check"
|
|
||||||
isRound: true
|
|
||||||
isToggle: false
|
|
||||||
shapeMorph: true
|
|
||||||
shapeMorphExpansion: pressed ? 12 : 0
|
|
||||||
text: "Apply"
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
const start = root.convertToMinutes(parseInt(startHourField.text)) + parseInt(startMinuteField.text);
|
|
||||||
const end = root.convertToMinutes(parseInt(endHourField.text)) + parseInt(endMinuteField.text);
|
|
||||||
root.applySettings(start, end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ CustomSwitch {
|
|||||||
property alias last: bg.last
|
property alias last: bg.last
|
||||||
property string settingAnchor
|
property string settingAnchor
|
||||||
property string subtext
|
property string subtext
|
||||||
|
property string iconText
|
||||||
|
|
||||||
function flashHighlight(): void {
|
function flashHighlight(): void {
|
||||||
bg.flashHighlight();
|
bg.flashHighlight();
|
||||||
@@ -63,8 +64,7 @@ CustomSwitch {
|
|||||||
text: root.text
|
text: root.text
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {
|
Anim {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,10 +81,16 @@ CustomSwitch {
|
|||||||
visible: root.subtext
|
visible: root.subtext
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
Anim {
|
Anim {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
id: icon
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: root.iconText ?? ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ CustomClippingRect {
|
|||||||
radius: Tokens.rounding.largeIncreased + Tokens.padding.small
|
radius: Tokens.rounding.largeIncreased + Tokens.padding.small
|
||||||
|
|
||||||
Behavior on blobColor {
|
Behavior on blobColor {
|
||||||
CAnim {
|
CAnim {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TapHandler {
|
TapHandler {
|
||||||
@@ -70,8 +69,4 @@ CustomClippingRect {
|
|||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
sState: root.sState
|
sState: root.sState
|
||||||
}
|
}
|
||||||
|
|
||||||
PopupOverlay {
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ QtObject {
|
|||||||
Component {
|
Component {
|
||||||
WallpaperSelect {}
|
WallpaperSelect {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
ColorsFonts {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Component {
|
Component {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import qs.Components
|
import qs.Components
|
||||||
import ZShell.Config
|
import ZShell.Config
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
@@ -41,6 +42,18 @@ Item {
|
|||||||
objectName: "PageContainer"
|
objectName: "PageContainer"
|
||||||
|
|
||||||
Component.onCompleted: root.loadPage(root.sState.currentPageIdx)
|
Component.onCompleted: root.loadPage(root.sState.currentPageIdx)
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: Qt.alpha(Colors.palette.m3shadow, 0.3)
|
||||||
|
opacity: root.sState.dimmed ? 1 : 0
|
||||||
|
visible: opacity > 0
|
||||||
|
z: 0
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
|||||||
@@ -55,6 +55,10 @@ PageBase {
|
|||||||
enabled: Object.keys(model).length > 0
|
enabled: Object.keys(model).length > 0
|
||||||
header: qsTr("Add new entry")
|
header: qsTr("Add new entry")
|
||||||
icon: "add"
|
icon: "add"
|
||||||
|
settingAnchor: "panels-bar-status-icons-add-item"
|
||||||
|
onOpenChanged: {
|
||||||
|
root.sState.dimmed = open;
|
||||||
|
}
|
||||||
last: true
|
last: true
|
||||||
label: qsTr("Add entry")
|
label: qsTr("Add entry")
|
||||||
model: {
|
model: {
|
||||||
|
|||||||
@@ -75,10 +75,18 @@ PageBase {
|
|||||||
|
|
||||||
acceptLabel: qsTr("Confirm")
|
acceptLabel: qsTr("Confirm")
|
||||||
enabled: Object.keys(model).length > 0
|
enabled: Object.keys(model).length > 0
|
||||||
|
settingAnchor: "panels-sidebar-select-scheme"
|
||||||
|
separateContent: false
|
||||||
header: qsTr("Select scheme")
|
header: qsTr("Select scheme")
|
||||||
first: true
|
first: true
|
||||||
last: true
|
last: true
|
||||||
icon: "add"
|
icon: "format_paint"
|
||||||
|
iconLabel.font.pointSize: Tokens.font.size.large
|
||||||
|
rowButton.trailingIcon: "open_in_new"
|
||||||
|
onOpenChanged: {
|
||||||
|
root.sState.dimmed = open;
|
||||||
|
}
|
||||||
|
rowButton.activeItem: root.schemes.find(s => s.id === Config.llm.appearance.scheme).label
|
||||||
label: qsTr("Color scheme")
|
label: qsTr("Color scheme")
|
||||||
subtext: qsTr("Select the color scheme used for code blocks")
|
subtext: qsTr("Select the color scheme used for code blocks")
|
||||||
model: root.schemes
|
model: root.schemes
|
||||||
|
|||||||
@@ -88,6 +88,10 @@ PageBase {
|
|||||||
enabled: Object.keys(model).length > 0
|
enabled: Object.keys(model).length > 0
|
||||||
header: qsTr("Add new entry")
|
header: qsTr("Add new entry")
|
||||||
icon: "add"
|
icon: "add"
|
||||||
|
onOpenChanged: {
|
||||||
|
root.sState.dimmed = open;
|
||||||
|
}
|
||||||
|
settingAnchor: "panels-sidebar-quick-toggles-add-item"
|
||||||
label: qsTr("Add entry")
|
label: qsTr("Add entry")
|
||||||
last: true
|
last: true
|
||||||
model: {
|
model: {
|
||||||
|
|||||||
@@ -0,0 +1,327 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import ZShell.Config
|
||||||
|
import qs.Paths
|
||||||
|
import qs.Services
|
||||||
|
import qs.Modules.Settings.Common
|
||||||
|
|
||||||
|
PageBase {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property list<string> fonts: Qt.fontFamilies()
|
||||||
|
readonly property var schemes: [
|
||||||
|
{
|
||||||
|
id: "onedark",
|
||||||
|
label: qsTr("One Dark")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "nord",
|
||||||
|
label: qsTr("Nord")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "dracula",
|
||||||
|
label: qsTr("Dracula")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "darkgreen",
|
||||||
|
label: qsTr("Darkgreen")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "solarized",
|
||||||
|
label: qsTr("Solarized")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "rosepine",
|
||||||
|
label: qsTr("Rosepine")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "gruvbox",
|
||||||
|
label: qsTr("Gruvbox")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "catppuccin",
|
||||||
|
label: qsTr("Catppuccin")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "tokyonight",
|
||||||
|
label: qsTr("Tokyo Night")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "shadotheme",
|
||||||
|
label: qsTr("Shadotheme")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
isSubPage: true
|
||||||
|
title: qsTr("Colors & font")
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.top: parent.top
|
||||||
|
spacing: Tokens.spacing.extraSmall / 2
|
||||||
|
width: root.cappedWidth
|
||||||
|
|
||||||
|
SectionHeader {
|
||||||
|
first: true
|
||||||
|
text: qsTr("Colors")
|
||||||
|
}
|
||||||
|
|
||||||
|
ToggleRow {
|
||||||
|
text: qsTr("Dynamic colors")
|
||||||
|
first: true
|
||||||
|
subtext: qsTr("Automatic color scheme based on wallpaper is %1").arg(Config.general.color.schemeGeneration ? "enabled" : "disabled")
|
||||||
|
checked: Config.general.color.schemeGeneration
|
||||||
|
settingAnchor: "colors-fonts-dynamic-colors"
|
||||||
|
|
||||||
|
onToggled: {
|
||||||
|
Config.general.color.schemeGeneration = checked;
|
||||||
|
|
||||||
|
if (checked)
|
||||||
|
Colors.setMode(Config.general.color.mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogSelectButton {
|
||||||
|
settingAnchor: "colors-fonts-preset-scheme"
|
||||||
|
model: root.schemes
|
||||||
|
acceptLabel: qsTr("Confirm")
|
||||||
|
enabled: !Config.general.color.schemeGeneration
|
||||||
|
header: qsTr("Select scheme")
|
||||||
|
rowButton.activeItem: root.schemes.find(s => {
|
||||||
|
var regex = new RegExp(Config.colors.presets.name, "i");
|
||||||
|
return regex.test(s.id);
|
||||||
|
}).label ?? ""
|
||||||
|
label: qsTr("Preset scheme")
|
||||||
|
subtext: qsTr("Select preset color scheme")
|
||||||
|
rootParent: root.flickable
|
||||||
|
|
||||||
|
FileView {
|
||||||
|
id: view
|
||||||
|
path: `${Paths.state}/presets.json`
|
||||||
|
|
||||||
|
watchChanges: true
|
||||||
|
onFileChanged: reload()
|
||||||
|
|
||||||
|
JsonAdapter {
|
||||||
|
id: adapter
|
||||||
|
|
||||||
|
property var presets
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initialSelect: Config.colors.presets.name.toLowerCase()
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
if (!selectedItem)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const s = selectedItem.toLowerCase();
|
||||||
|
let v = "";
|
||||||
|
let a = "";
|
||||||
|
const existingVariant = Config.colors.presets.variant;
|
||||||
|
const existingAccent = Config.colors.presets.accent;
|
||||||
|
const variantKeys = Object.keys(adapter.presets[s].variants);
|
||||||
|
|
||||||
|
if (existingVariant !== "" && variantKeys.some(v => v === existingVariant))
|
||||||
|
v = existingVariant;
|
||||||
|
|
||||||
|
if (v !== "" && existingAccent !== "" && adapter.presets[s].variants[v]?.accents.some(a => a === existingAccent))
|
||||||
|
a = existingAccent;
|
||||||
|
|
||||||
|
if (a !== "")
|
||||||
|
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${v}`, "-a", `${a}`]);
|
||||||
|
else if (v !== "")
|
||||||
|
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${v}`]);
|
||||||
|
else
|
||||||
|
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${variantKeys[0]}`]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogSelectButton {
|
||||||
|
settingAnchor: "colors-fonts-preset-variant"
|
||||||
|
// qmlformat off
|
||||||
|
model: {
|
||||||
|
const v = adapter.presets[Config.colors.presets.name].variants;
|
||||||
|
const map = Object.keys(v).map(v => ({
|
||||||
|
id: v,
|
||||||
|
label: qsTr("%1%2")
|
||||||
|
.arg(v.charAt(0).toUpperCase())
|
||||||
|
.arg(v.slice(1).toLowerCase())
|
||||||
|
}));
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
// qmlformat on
|
||||||
|
acceptLabel: qsTr("Confirm")
|
||||||
|
enabled: !Config.general.color.schemeGeneration && model.length > 1
|
||||||
|
header: qsTr("Select variant")
|
||||||
|
rowButton.activeItem: {
|
||||||
|
const v = Config.colors.presets.variant ?? "";
|
||||||
|
if (v === "")
|
||||||
|
return "";
|
||||||
|
return qsTr("%1%2").arg(v.charAt(0).toUpperCase()).arg(v.slice(1).toLowerCase());
|
||||||
|
}
|
||||||
|
label: qsTr("Variant")
|
||||||
|
subtext: qsTr("Select preset variant")
|
||||||
|
rootParent: root.flickable
|
||||||
|
|
||||||
|
initialSelect: Config.colors.presets.variant
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
if (!selectedItem)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const v = selectedItem.toLowerCase();
|
||||||
|
const s = Config.colors.presets.name;
|
||||||
|
const existingAccent = Config.colors.presets.accent;
|
||||||
|
let a = "";
|
||||||
|
|
||||||
|
if (existingAccent !== "" && adapter.presets[s].variants[v]?.accents.some(a => a === existingAccent))
|
||||||
|
a = existingAccent;
|
||||||
|
|
||||||
|
if (a !== "")
|
||||||
|
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${v}`, "-a", `${a}`]);
|
||||||
|
else
|
||||||
|
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${v}`]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogSelectButton {
|
||||||
|
settingAnchor: "colors-fonts-preset-accent"
|
||||||
|
// qmlformat off
|
||||||
|
model: {
|
||||||
|
const a = adapter.presets[Config.colors.presets.name].variants[Config.colors.presets.variant]?.accents ?? [];
|
||||||
|
|
||||||
|
if (a.length === 0)
|
||||||
|
return a;
|
||||||
|
|
||||||
|
const map = a.map(a => ({
|
||||||
|
id: a,
|
||||||
|
label: qsTr("%1%2")
|
||||||
|
.arg(a.charAt(0).toUpperCase())
|
||||||
|
.arg(a.slice(1).toLowerCase())
|
||||||
|
}));
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
// qmlformat on
|
||||||
|
acceptLabel: qsTr("Confirm")
|
||||||
|
enabled: !Config.general.color.schemeGeneration && model.length > 1
|
||||||
|
header: qsTr("Select accent")
|
||||||
|
rowButton.activeItem: {
|
||||||
|
const a = Config.colors.presets.accent ?? "";
|
||||||
|
if (a === "")
|
||||||
|
return "";
|
||||||
|
return qsTr("%1%2").arg(a.charAt(0).toUpperCase()).arg(a.slice(1).toLowerCase());
|
||||||
|
}
|
||||||
|
label: qsTr("Accent")
|
||||||
|
last: true
|
||||||
|
subtext: qsTr("Select preset accent")
|
||||||
|
rootParent: root.flickable
|
||||||
|
|
||||||
|
initialSelect: Config.colors.presets.accent
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
if (!selectedItem)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const a = selectedItem.toLowerCase();
|
||||||
|
const v = Config.colors.presets.variant;
|
||||||
|
const s = Config.colors.presets.name;
|
||||||
|
|
||||||
|
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${v}`, "-a", `${a}`]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SectionHeader {
|
||||||
|
text: qsTr("Fonts")
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchPopup {
|
||||||
|
id: selectSansFont
|
||||||
|
|
||||||
|
settingAnchor: "colors-fonts-sans-font"
|
||||||
|
model: root.fonts
|
||||||
|
acceptLabel: qsTr("Confirm")
|
||||||
|
enabled: Object.keys(model).length > 0
|
||||||
|
separateContent: false
|
||||||
|
header: qsTr("Select font")
|
||||||
|
first: true
|
||||||
|
rowButton.activeItem: root.fonts.find(s => {
|
||||||
|
var regex = new RegExp(Config.appearance.font.family.sans, "i");
|
||||||
|
return regex.test(s);
|
||||||
|
}) ?? ""
|
||||||
|
label: qsTr("Sans font")
|
||||||
|
subtext: qsTr("Select desired sans font")
|
||||||
|
rootParent: root.flickable
|
||||||
|
|
||||||
|
initialSelect: Config.appearance.font.family.sans
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
if (!selectedItem)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Config.appearance.font.family.sans = selectedItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchPopup {
|
||||||
|
id: selectMonoFont
|
||||||
|
|
||||||
|
acceptLabel: qsTr("Confirm")
|
||||||
|
enabled: Object.keys(model).length > 0
|
||||||
|
settingAnchor: "colors-fonts-mono-font"
|
||||||
|
separateContent: false
|
||||||
|
header: qsTr("Select font")
|
||||||
|
rowButton.activeItem: root.fonts.find(s => {
|
||||||
|
var regex = new RegExp(Config.appearance.font.family.mono, "i");
|
||||||
|
return regex.test(s);
|
||||||
|
}) ?? ""
|
||||||
|
label: qsTr("Mono font")
|
||||||
|
subtext: qsTr("Select desired mono font")
|
||||||
|
model: root.fonts
|
||||||
|
rootParent: root.flickable
|
||||||
|
|
||||||
|
initialSelect: Config.appearance.font.family.mono
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
if (!selectedItem)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Config.appearance.font.family.mono = selectedItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchPopup {
|
||||||
|
id: selectClockFont
|
||||||
|
|
||||||
|
acceptLabel: qsTr("Confirm")
|
||||||
|
enabled: Object.keys(model).length > 0
|
||||||
|
separateContent: false
|
||||||
|
settingAnchor: "colors-fonts-clock-font"
|
||||||
|
header: qsTr("Select font")
|
||||||
|
last: true
|
||||||
|
rowButton.activeItem: root.fonts.find(s => {
|
||||||
|
var regex = new RegExp(Config.appearance.font.family.clock, "i");
|
||||||
|
return regex.test(s);
|
||||||
|
}) ?? ""
|
||||||
|
label: qsTr("Clock font")
|
||||||
|
subtext: qsTr("Select desired clock font")
|
||||||
|
model: root.fonts
|
||||||
|
rootParent: root.flickable
|
||||||
|
|
||||||
|
initialSelect: Config.appearance.font.family.clock
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
if (!selectedItem)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Config.appearance.font.family.clock = selectedItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,18 +33,35 @@ PageBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IconTextButton {
|
ButtonRow {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
enabled: Config.background.enabled
|
spacing: Tokens.spacing.small
|
||||||
horizontalPadding: Tokens.padding.extraLarge
|
|
||||||
icon: "wallpaper"
|
|
||||||
isRound: true
|
|
||||||
shapeMorph: true
|
|
||||||
text: qsTr("Wallpapers")
|
|
||||||
type: IconTextButton.Tonal
|
|
||||||
verticalPadding: Tokens.padding.small
|
|
||||||
|
|
||||||
onClicked: root.sState.openSubPage(1) // Wallpaper page
|
IconTextButton {
|
||||||
|
enabled: Config.background.enabled
|
||||||
|
horizontalPadding: Tokens.padding.extraLarge
|
||||||
|
icon: "wallpaper"
|
||||||
|
isRound: true
|
||||||
|
shapeMorph: true
|
||||||
|
text: qsTr("Wallpapers")
|
||||||
|
type: IconTextButton.Tonal
|
||||||
|
verticalPadding: Tokens.padding.small
|
||||||
|
|
||||||
|
onClicked: root.sState.openSubPage(1) // Wallpaper page
|
||||||
|
}
|
||||||
|
|
||||||
|
IconTextButton {
|
||||||
|
enabled: Config.background.enabled
|
||||||
|
horizontalPadding: Tokens.padding.extraLarge
|
||||||
|
icon: "palette"
|
||||||
|
isRound: true
|
||||||
|
shapeMorph: true
|
||||||
|
text: qsTr("Colors & font")
|
||||||
|
type: IconTextButton.Tonal
|
||||||
|
verticalPadding: Tokens.padding.small
|
||||||
|
|
||||||
|
onClicked: root.sState.openSubPage(2) // Colors & font page
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ToggleRow {
|
ToggleRow {
|
||||||
@@ -76,9 +93,7 @@ PageBase {
|
|||||||
onToggled: Colors.setMode(checked ? "dark" : "light")
|
onToggled: Colors.setMode(checked ? "dark" : "light")
|
||||||
}
|
}
|
||||||
|
|
||||||
OverlayRow {
|
TimeDialogSelect {
|
||||||
id: darkMode
|
|
||||||
|
|
||||||
readonly property string endTime: {
|
readonly property string endTime: {
|
||||||
var d = new Date(0, 0, 0, 0, 0, 0, 0);
|
var d = new Date(0, 0, 0, 0, 0, 0, 0);
|
||||||
d.setMinutes(Config.general.color.scheduleDarkEnd);
|
d.setMinutes(Config.general.color.scheduleDarkEnd);
|
||||||
@@ -90,35 +105,30 @@ PageBase {
|
|||||||
return Qt.formatTime(d, "hh:mm AP");
|
return Qt.formatTime(d, "hh:mm AP");
|
||||||
}
|
}
|
||||||
|
|
||||||
checked: Config.general.color.scheduleDark
|
rowButton.checked: Config.general.color.scheduleDark
|
||||||
|
rowButton.onToggled: Config.general.color.scheduleDark = rowButton.checked
|
||||||
|
start: Config.general.color.scheduleDarkStart
|
||||||
|
end: Config.general.color.scheduleDarkEnd
|
||||||
first: true
|
first: true
|
||||||
settingAnchor: "style-schedule-dark-mode"
|
settingAnchor: "style-schedule-dark-mode"
|
||||||
|
acceptLabel: qsTr("Apply")
|
||||||
|
rootParent: root.flickable
|
||||||
|
header: qsTr("Select time")
|
||||||
subtext: qsTr("Dark mode will turn on at %1, and turn off at %2.").arg(startTime).arg(endTime)
|
subtext: qsTr("Dark mode will turn on at %1, and turn off at %2.").arg(startTime).arg(endTime)
|
||||||
text: qsTr("Schedule dark mode")
|
label: qsTr("Schedule dark mode")
|
||||||
|
|
||||||
popup: Component {
|
onOpenChanged: {
|
||||||
TimeInput {
|
root.sState.dimmed = open;
|
||||||
object: Config.general.color
|
|
||||||
settings: ["scheduleDark", "scheduleDarkStart", "scheduleDarkEnd"]
|
|
||||||
|
|
||||||
onApplySettings: (start, end) => {
|
|
||||||
Config.general.color.scheduleDarkStart = start;
|
|
||||||
Config.general.color.scheduleDarkEnd = end;
|
|
||||||
ModeScheduler.checkStartup();
|
|
||||||
PopupManager.requestClose();
|
|
||||||
}
|
|
||||||
onClose: PopupManager.requestClose()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: value => {
|
onAccepted: {
|
||||||
Config.general.color.scheduleDark = value;
|
Config.general.color.scheduleDarkStart = startCurrent;
|
||||||
|
Config.general.color.scheduleDarkEnd = endCurrent;
|
||||||
|
ModeScheduler.checkStartup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OverlayRow {
|
TimeDialogSelect {
|
||||||
id: hyprsunset
|
|
||||||
|
|
||||||
readonly property string endTime: {
|
readonly property string endTime: {
|
||||||
var d = new Date(0, 0, 0, 0, 0, 0, 0);
|
var d = new Date(0, 0, 0, 0, 0, 0, 0);
|
||||||
d.setMinutes(Config.general.color.scheduleHyprsunsetEnd);
|
d.setMinutes(Config.general.color.scheduleHyprsunsetEnd);
|
||||||
@@ -131,29 +141,26 @@ PageBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Layout.topMargin: Tokens.spacing.extraSmall / 2 - parent.spacing
|
Layout.topMargin: Tokens.spacing.extraSmall / 2 - parent.spacing
|
||||||
checked: Config.general.color.scheduleHyprsunset
|
rowButton.checked: Config.general.color.scheduleHyprsunset
|
||||||
|
rowButton.onToggled: Config.general.color.scheduleHyprsunset = rowButton.checked
|
||||||
|
start: Config.general.color.scheduleHyprsunsetStart
|
||||||
|
end: Config.general.color.scheduleHyprsunsetEnd
|
||||||
last: true
|
last: true
|
||||||
settingAnchor: "style-schedule-hyprsunset"
|
settingAnchor: "style-schedule-hyprsunset"
|
||||||
|
acceptLabel: qsTr("Apply")
|
||||||
|
rootParent: root.flickable
|
||||||
|
header: qsTr("Select time")
|
||||||
subtext: qsTr("Hyprsunset will turn on at %1, and turn off at %2.").arg(startTime).arg(endTime)
|
subtext: qsTr("Hyprsunset will turn on at %1, and turn off at %2.").arg(startTime).arg(endTime)
|
||||||
text: qsTr("Schedule hyprsunset")
|
label: qsTr("Schedule hyprsunset")
|
||||||
|
|
||||||
popup: Component {
|
onOpenChanged: {
|
||||||
TimeInput {
|
root.sState.dimmed = open;
|
||||||
object: Config.general.color
|
|
||||||
settings: ["scheduleHyprsunset", "scheduleHyprsunsetStart", "scheduleHyprsunsetEnd"]
|
|
||||||
|
|
||||||
onApplySettings: (start, end) => {
|
|
||||||
Config.general.color.scheduleHyprsunsetStart = start;
|
|
||||||
Config.general.color.scheduleHyprsunsetEnd = end;
|
|
||||||
Hyprsunset.checkStartup();
|
|
||||||
PopupManager.requestClose();
|
|
||||||
}
|
|
||||||
onClose: PopupManager.requestClose()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: value => {
|
onAccepted: {
|
||||||
Config.general.color.scheduleHyprsunset = value;
|
Config.general.color.scheduleHyprsunsetStart = startCurrent;
|
||||||
|
Config.general.color.scheduleHyprsunsetEnd = endCurrent;
|
||||||
|
Hyprsunset.checkStartup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
pragma Singleton
|
|
||||||
|
|
||||||
import Quickshell
|
|
||||||
import QtQuick
|
|
||||||
|
|
||||||
Singleton {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property bool closed: true
|
|
||||||
property Component currentPopup: null
|
|
||||||
|
|
||||||
function requestClose(): void {
|
|
||||||
closed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function requestOpen(component: Component): void {
|
|
||||||
currentPopup = component;
|
|
||||||
closed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import ZShell.Config
|
|
||||||
import qs.Components
|
|
||||||
import qs.Services
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
readonly property bool closing: PopupManager.closed
|
|
||||||
readonly property var currentPopup: PopupManager.currentPopup
|
|
||||||
property bool shouldBeVisible: loader.status === Loader.Ready
|
|
||||||
|
|
||||||
color: Qt.alpha(Colors.palette.m3shadow, 0.3)
|
|
||||||
opacity: shouldBeVisible && !closing ? 1 : 0
|
|
||||||
visible: opacity > 0
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
Anim {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onVisibleChanged: if (!visible)
|
|
||||||
PopupManager.currentPopup = null
|
|
||||||
|
|
||||||
CustomMouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
preventStealing: true
|
|
||||||
propagateComposedEvents: false
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
const insideItemWidth = mouseX < loader.x + loader.item.width && mouseX > loader.x;
|
|
||||||
const insideItemHeight = mouseY < loader.y + loader.item.height && mouseY > loader.y;
|
|
||||||
if (insideItemHeight && insideItemWidth)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PopupManager.requestClose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: loader
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
sourceComponent: root.currentPopup
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,6 +16,7 @@ QtObject {
|
|||||||
property string searchText
|
property string searchText
|
||||||
property DesktopEntry selectedApp
|
property DesktopEntry selectedApp
|
||||||
property BluetoothDevice selectedBtDevice
|
property BluetoothDevice selectedBtDevice
|
||||||
|
property bool dimmed
|
||||||
property string selectedWallpaperCategory
|
property string selectedWallpaperCategory
|
||||||
property list<int> subPageIdxStack
|
property list<int> subPageIdxStack
|
||||||
|
|
||||||
|
|||||||
@@ -94,9 +94,8 @@ def list_presets(
|
|||||||
if v.accents:
|
if v.accents:
|
||||||
entry["accents"] = sorted(v.accents)
|
entry["accents"] = sorted(v.accents)
|
||||||
entry["default_accent"] = sorted(v.accents)[0]
|
entry["default_accent"] = sorted(v.accents)[0]
|
||||||
variants[v.id] = entry
|
variants[v.id.lower()] = entry
|
||||||
out[meta.name] = {
|
out[sid.lower()] = {
|
||||||
"id": sid,
|
|
||||||
"variants": variants,
|
"variants": variants,
|
||||||
}
|
}
|
||||||
print(json.dumps({"presets": out}, indent=2))
|
print(json.dumps({"presets": out}, indent=2))
|
||||||
@@ -670,7 +669,7 @@ def generate(
|
|||||||
name = palette_obj.scheme
|
name = palette_obj.scheme
|
||||||
flavor = palette_obj.variant
|
flavor = palette_obj.variant
|
||||||
|
|
||||||
display_name = schemes[p_scheme].name
|
display_name = schemes[p_scheme].id
|
||||||
config["colors"]["presets"] = {
|
config["colors"]["presets"] = {
|
||||||
"name": display_name,
|
"name": display_name,
|
||||||
"variant": p_variant,
|
"variant": p_variant,
|
||||||
|
|||||||
Reference in New Issue
Block a user