settings
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import qs.Config
|
import qs.Config
|
||||||
|
import qs.Helpers
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: root
|
id: root
|
||||||
@@ -29,8 +30,29 @@ Row {
|
|||||||
property int type: CustomSplitButton.Filled
|
property int type: CustomSplitButton.Filled
|
||||||
property real verticalPadding: Appearance.padding.smaller
|
property real verticalPadding: Appearance.padding.smaller
|
||||||
|
|
||||||
|
function closeDropdown(): void {
|
||||||
|
SettingsDropdowns.close(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openDropdown(): void {
|
||||||
|
if (root.disabled)
|
||||||
|
return;
|
||||||
|
SettingsDropdowns.open(menu, root);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleDropdown(): void {
|
||||||
|
if (root.disabled)
|
||||||
|
return;
|
||||||
|
SettingsDropdowns.toggle(menu, root);
|
||||||
|
}
|
||||||
|
|
||||||
spacing: Math.floor(Appearance.spacing.small / 2)
|
spacing: Math.floor(Appearance.spacing.small / 2)
|
||||||
|
|
||||||
|
onExpandedChanged: {
|
||||||
|
if (!expanded)
|
||||||
|
SettingsDropdowns.forget(menu);
|
||||||
|
}
|
||||||
|
|
||||||
CustomRect {
|
CustomRect {
|
||||||
bottomRightRadius: Appearance.rounding.small / 2
|
bottomRightRadius: Appearance.rounding.small / 2
|
||||||
color: root.disabled ? root.disabledColor : root.color
|
color: root.disabled ? root.disabledColor : root.color
|
||||||
@@ -109,7 +131,7 @@ Row {
|
|||||||
id: expandStateLayer
|
id: expandStateLayer
|
||||||
|
|
||||||
function onClicked(): void {
|
function onClicked(): void {
|
||||||
root.expanded = !root.expanded;
|
root.toggleDropdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
color: root.textColor
|
color: root.textColor
|
||||||
|
|||||||
@@ -47,9 +47,10 @@ Item {
|
|||||||
|
|
||||||
menu.onItemSelected: item => {
|
menu.onItemSelected: item => {
|
||||||
root.selected(item);
|
root.selected(item);
|
||||||
|
splitButton.closeDropdown();
|
||||||
}
|
}
|
||||||
stateLayer.onClicked: {
|
stateLayer.onClicked: {
|
||||||
splitButton.expanded = !splitButton.expanded;
|
splitButton.toggleDropdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Path {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property real viewHeight
|
||||||
|
required property real viewWidth
|
||||||
|
|
||||||
|
startX: root.viewWidth / 2
|
||||||
|
startY: 0
|
||||||
|
|
||||||
|
PathAttribute {
|
||||||
|
name: "itemOpacity"
|
||||||
|
value: 0.25
|
||||||
|
}
|
||||||
|
|
||||||
|
PathLine {
|
||||||
|
x: root.viewWidth / 2
|
||||||
|
y: root.viewHeight * (1 / 6)
|
||||||
|
}
|
||||||
|
|
||||||
|
PathAttribute {
|
||||||
|
name: "itemOpacity"
|
||||||
|
value: 0.45
|
||||||
|
}
|
||||||
|
|
||||||
|
PathLine {
|
||||||
|
x: root.viewWidth / 2
|
||||||
|
y: root.viewHeight * (2 / 6)
|
||||||
|
}
|
||||||
|
|
||||||
|
PathAttribute {
|
||||||
|
name: "itemOpacity"
|
||||||
|
value: 0.70
|
||||||
|
}
|
||||||
|
|
||||||
|
PathLine {
|
||||||
|
x: root.viewWidth / 2
|
||||||
|
y: root.viewHeight * (3 / 6)
|
||||||
|
}
|
||||||
|
|
||||||
|
PathAttribute {
|
||||||
|
name: "itemOpacity"
|
||||||
|
value: 1.00
|
||||||
|
}
|
||||||
|
|
||||||
|
PathLine {
|
||||||
|
x: root.viewWidth / 2
|
||||||
|
y: root.viewHeight * (4 / 6)
|
||||||
|
}
|
||||||
|
|
||||||
|
PathAttribute {
|
||||||
|
name: "itemOpacity"
|
||||||
|
value: 0.70
|
||||||
|
}
|
||||||
|
|
||||||
|
PathLine {
|
||||||
|
x: root.viewWidth / 2
|
||||||
|
y: root.viewHeight * (5 / 6)
|
||||||
|
}
|
||||||
|
|
||||||
|
PathAttribute {
|
||||||
|
name: "itemOpacity"
|
||||||
|
value: 0.45
|
||||||
|
}
|
||||||
|
|
||||||
|
PathLine {
|
||||||
|
x: root.viewWidth / 2
|
||||||
|
y: root.viewHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
PathAttribute {
|
||||||
|
name: "itemOpacity"
|
||||||
|
value: 0.25
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Effects
|
||||||
|
import qs.Config
|
||||||
|
|
||||||
|
Elevation {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property int currentIndex
|
||||||
|
property bool expanded
|
||||||
|
required property int from
|
||||||
|
property color insideTextColor: DynamicColors.palette.m3onPrimary
|
||||||
|
property int itemHeight
|
||||||
|
property int listHeight: 200
|
||||||
|
property color outsideTextColor: DynamicColors.palette.m3onSurfaceVariant
|
||||||
|
readonly property var spinnerModel: root.range(root.from, root.to)
|
||||||
|
required property int to
|
||||||
|
property Item triggerItem
|
||||||
|
|
||||||
|
signal itemSelected(item: int)
|
||||||
|
|
||||||
|
function range(first, last) {
|
||||||
|
let out = [];
|
||||||
|
for (let i = first; i <= last; ++i)
|
||||||
|
out.push(i);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitHeight: root.expanded ? view.implicitHeight : 0
|
||||||
|
level: root.expanded ? 2 : 0
|
||||||
|
radius: itemHeight / 2
|
||||||
|
visible: implicitHeight > 0
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onExpandedChanged: {
|
||||||
|
if (!root.expanded)
|
||||||
|
root.itemSelected(view.currentIndex + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: spinnerDelegate
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: wrapper
|
||||||
|
|
||||||
|
readonly property color delegateTextColor: wrapper.PathView.view ? wrapper.PathView.view.delegateTextColor : "white"
|
||||||
|
required property var modelData
|
||||||
|
|
||||||
|
height: root.itemHeight
|
||||||
|
opacity: wrapper.PathView.itemOpacity
|
||||||
|
visible: wrapper.PathView.onPath
|
||||||
|
width: wrapper.PathView.view ? wrapper.PathView.view.width : 0
|
||||||
|
z: wrapper.PathView.isCurrentItem ? 100 : Math.round(wrapper.PathView.itemScale * 100)
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: wrapper.delegateTextColor
|
||||||
|
font.pointSize: Appearance.font.size.large
|
||||||
|
text: wrapper.modelData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomClippingRect {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: DynamicColors.palette.m3surfaceContainer
|
||||||
|
radius: parent.radius
|
||||||
|
|
||||||
|
// Main visible spinner: normal/outside text color
|
||||||
|
PathView {
|
||||||
|
id: view
|
||||||
|
|
||||||
|
property color delegateTextColor: root.outsideTextColor
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
clip: true
|
||||||
|
currentIndex: root.currentIndex - 1
|
||||||
|
delegate: spinnerDelegate
|
||||||
|
dragMargin: width
|
||||||
|
highlightRangeMode: PathView.StrictlyEnforceRange
|
||||||
|
implicitHeight: root.listHeight
|
||||||
|
model: root.spinnerModel
|
||||||
|
pathItemCount: 7
|
||||||
|
preferredHighlightBegin: 0.5
|
||||||
|
preferredHighlightEnd: 0.5
|
||||||
|
snapMode: PathView.SnapToItem
|
||||||
|
|
||||||
|
path: PathMenu {
|
||||||
|
viewHeight: view.height
|
||||||
|
viewWidth: view.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The selection rectangle itself
|
||||||
|
CustomRect {
|
||||||
|
id: selectionRect
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: DynamicColors.palette.m3primary
|
||||||
|
height: root.itemHeight
|
||||||
|
radius: root.itemHeight / 2
|
||||||
|
width: parent.width
|
||||||
|
z: 2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hidden source: same PathView, but with the "inside selection" text color
|
||||||
|
Item {
|
||||||
|
id: selectedTextSource
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
layer.enabled: true
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
PathView {
|
||||||
|
id: selectedTextView
|
||||||
|
|
||||||
|
property color delegateTextColor: root.insideTextColor
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
clip: true
|
||||||
|
currentIndex: view.currentIndex
|
||||||
|
delegate: spinnerDelegate
|
||||||
|
dragMargin: view.dragMargin
|
||||||
|
highlightRangeMode: view.highlightRangeMode
|
||||||
|
implicitHeight: root.listHeight
|
||||||
|
interactive: false
|
||||||
|
model: view.model
|
||||||
|
|
||||||
|
// Keep this PathView visually locked to the real one
|
||||||
|
offset: view.offset
|
||||||
|
pathItemCount: view.pathItemCount
|
||||||
|
preferredHighlightBegin: view.preferredHighlightBegin
|
||||||
|
preferredHighlightEnd: view.preferredHighlightEnd
|
||||||
|
snapMode: view.snapMode
|
||||||
|
|
||||||
|
path: PathMenu {
|
||||||
|
viewHeight: selectedTextView.height
|
||||||
|
viewWidth: selectedTextView.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mask matching the selection rectangle
|
||||||
|
Item {
|
||||||
|
id: selectionMask
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
layer.enabled: true
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
color: "white"
|
||||||
|
height: selectionRect.height
|
||||||
|
radius: selectionRect.radius
|
||||||
|
width: selectionRect.width
|
||||||
|
x: selectionRect.x
|
||||||
|
y: selectionRect.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only show the "inside selection" text where the mask exists
|
||||||
|
MultiEffect {
|
||||||
|
anchors.fill: selectedTextSource
|
||||||
|
maskEnabled: true
|
||||||
|
maskInverted: false
|
||||||
|
maskSource: selectionMask
|
||||||
|
source: selectedTextSource
|
||||||
|
z: 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
pragma Singleton
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property Item activeMenu: null
|
||||||
|
property Item activeTrigger: null
|
||||||
|
|
||||||
|
function close(menu) {
|
||||||
|
if (!menu)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (activeMenu === menu) {
|
||||||
|
activeMenu = null;
|
||||||
|
activeTrigger = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.expanded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeActive() {
|
||||||
|
if (activeMenu)
|
||||||
|
activeMenu.expanded = false;
|
||||||
|
|
||||||
|
activeMenu = null;
|
||||||
|
activeTrigger = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function forget(menu) {
|
||||||
|
if (activeMenu === menu) {
|
||||||
|
activeMenu = null;
|
||||||
|
activeTrigger = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hit(item, scenePos) {
|
||||||
|
if (!item || !item.visible)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const p = item.mapFromItem(null, scenePos.x, scenePos.y);
|
||||||
|
return item.contains(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
function open(menu, trigger) {
|
||||||
|
if (activeMenu && activeMenu !== menu)
|
||||||
|
activeMenu.expanded = false;
|
||||||
|
|
||||||
|
activeMenu = menu;
|
||||||
|
activeTrigger = trigger || null;
|
||||||
|
menu.expanded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggle(menu, trigger) {
|
||||||
|
if (activeMenu === menu && menu.expanded)
|
||||||
|
close(menu);
|
||||||
|
else
|
||||||
|
open(menu, trigger);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -94,11 +94,13 @@ Item {
|
|||||||
CustomListView {
|
CustomListView {
|
||||||
id: clayout
|
id: clayout
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.bottom: parent.bottom
|
||||||
contentHeight: contentItem.childrenRect.height
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.margins: Appearance.padding.smaller
|
||||||
|
anchors.top: parent.top
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
contentWidth: contentItem.childrenRect.width
|
contentWidth: contentItem.childrenRect.width
|
||||||
highlightFollowsCurrentItem: false
|
highlightFollowsCurrentItem: false
|
||||||
implicitHeight: contentItem.childrenRect.height
|
|
||||||
implicitWidth: contentItem.childrenRect.width
|
implicitWidth: contentItem.childrenRect.width
|
||||||
model: listModel
|
model: listModel
|
||||||
spacing: 5
|
spacing: 5
|
||||||
@@ -109,7 +111,7 @@ Item {
|
|||||||
color: DynamicColors.palette.m3primary
|
color: DynamicColors.palette.m3primary
|
||||||
implicitHeight: clayout.currentItem?.implicitHeight ?? 0
|
implicitHeight: clayout.currentItem?.implicitHeight ?? 0
|
||||||
implicitWidth: clayout.width
|
implicitWidth: clayout.width
|
||||||
radius: 4
|
radius: Appearance.rounding.normal - Appearance.padding.smaller
|
||||||
y: clayout.currentItem?.y ?? 0
|
y: clayout.currentItem?.y ?? 0
|
||||||
|
|
||||||
Behavior on y {
|
Behavior on y {
|
||||||
@@ -131,7 +133,7 @@ Item {
|
|||||||
|
|
||||||
implicitHeight: 42
|
implicitHeight: 42
|
||||||
implicitWidth: 200
|
implicitWidth: 200
|
||||||
radius: 4
|
radius: Appearance.rounding.normal - Appearance.padding.smaller
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: layout
|
id: layout
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import QtQuick.Layouts
|
|||||||
import qs.Components
|
import qs.Components
|
||||||
import qs.Modules as Modules
|
import qs.Modules as Modules
|
||||||
import qs.Modules.Settings.Controls
|
import qs.Modules.Settings.Controls
|
||||||
import qs.Modules.Settings.Categories.Appearance
|
|
||||||
import qs.Config
|
import qs.Config
|
||||||
import qs.Helpers
|
import qs.Helpers
|
||||||
|
|
||||||
@@ -14,13 +13,33 @@ CustomFlickable {
|
|||||||
|
|
||||||
contentHeight: clayout.implicitHeight
|
contentHeight: clayout.implicitHeight
|
||||||
|
|
||||||
|
TapHandler {
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
|
|
||||||
|
onTapped: function (eventPoint) {
|
||||||
|
const menu = SettingsDropdowns.activeMenu;
|
||||||
|
if (!menu)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const p = eventPoint.scenePosition;
|
||||||
|
|
||||||
|
if (SettingsDropdowns.hit(SettingsDropdowns.activeTrigger, p))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (SettingsDropdowns.hit(menu, p))
|
||||||
|
return;
|
||||||
|
|
||||||
|
SettingsDropdowns.closeActive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: clayout
|
id: clayout
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
CustomClippingRect {
|
CustomRect {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: colorLayout.implicitHeight + Appearance.padding.normal * 2
|
Layout.preferredHeight: colorLayout.implicitHeight + Appearance.padding.normal * 2
|
||||||
color: DynamicColors.tPalette.m3surfaceContainer
|
color: DynamicColors.tPalette.m3surfaceContainer
|
||||||
@@ -33,6 +52,7 @@ CustomFlickable {
|
|||||||
anchors.margins: Appearance.padding.large
|
anchors.margins: Appearance.padding.large
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Appearance.spacing.normal
|
||||||
|
|
||||||
Settings {
|
Settings {
|
||||||
name: "Color"
|
name: "Color"
|
||||||
@@ -56,19 +76,11 @@ CustomFlickable {
|
|||||||
Separator {
|
Separator {
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingInput {
|
SettingSpinner {
|
||||||
name: "Schedule dark mode start"
|
name: "Schedule dark mode"
|
||||||
object: Config.general.color
|
object: Config.general.color
|
||||||
setting: "scheduleDarkStart"
|
settings: ["scheduleDarkStart", "scheduleDarkEnd"]
|
||||||
}
|
z: 2
|
||||||
|
|
||||||
Separator {
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingInput {
|
|
||||||
name: "Schedule dark mode end"
|
|
||||||
object: Config.general.color
|
|
||||||
setting: "scheduleDarkEnd"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Separator {
|
Separator {
|
||||||
@@ -106,22 +118,6 @@ CustomFlickable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomClippingRect {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: idleLayout.implicitHeight + Appearance.padding.normal * 2
|
|
||||||
color: DynamicColors.tPalette.m3surfaceContainer
|
|
||||||
radius: Appearance.rounding.normal - Appearance.padding.smaller
|
|
||||||
|
|
||||||
Idle {
|
|
||||||
id: idleLayout
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.margins: Appearance.padding.large
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
component Settings: CustomRect {
|
component Settings: CustomRect {
|
||||||
@@ -135,9 +131,7 @@ CustomFlickable {
|
|||||||
CustomText {
|
CustomText {
|
||||||
id: text
|
id: text
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.fill: parent
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
font.bold: true
|
font.bold: true
|
||||||
font.pointSize: Appearance.font.size.large * 2
|
font.pointSize: Appearance.font.size.large * 2
|
||||||
text: settingsItem.name
|
text: settingsItem.name
|
||||||
|
|||||||
@@ -14,13 +14,6 @@ CustomRect {
|
|||||||
id: clayout
|
id: clayout
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
Settings {
|
|
||||||
name: "apps"
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
component Settings: CustomRect {
|
component Settings: CustomRect {
|
||||||
@@ -28,28 +21,17 @@ CustomRect {
|
|||||||
|
|
||||||
required property string name
|
required property string name
|
||||||
|
|
||||||
implicitHeight: 42
|
Layout.preferredHeight: 60
|
||||||
implicitWidth: 200
|
Layout.preferredWidth: 200
|
||||||
radius: 4
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: layout
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.margins: Appearance.padding.smaller
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
|
|
||||||
CustomText {
|
CustomText {
|
||||||
id: text
|
id: text
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
|
anchors.fill: parent
|
||||||
Layout.fillHeight: true
|
font.bold: true
|
||||||
Layout.fillWidth: true
|
font.pointSize: Appearance.font.size.large * 2
|
||||||
Layout.leftMargin: Appearance.spacing.normal
|
|
||||||
text: settingsItem.name
|
text: settingsItem.name
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
import Quickshell
|
||||||
|
import Quickshell.Widgets
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import qs.Components
|
||||||
|
import qs.Modules as Modules
|
||||||
|
import qs.Modules.Settings.Categories.Lockscreen
|
||||||
|
import qs.Config
|
||||||
|
import qs.Helpers
|
||||||
|
|
||||||
|
CustomFlickable {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
contentHeight: clayout.implicitHeight
|
||||||
|
|
||||||
|
TapHandler {
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
|
|
||||||
|
onTapped: function (eventPoint) {
|
||||||
|
const menu = SettingsDropdowns.activeMenu;
|
||||||
|
if (!menu)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const p = eventPoint.scenePosition;
|
||||||
|
|
||||||
|
if (SettingsDropdowns.hit(SettingsDropdowns.activeTrigger, p))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (SettingsDropdowns.hit(menu, p))
|
||||||
|
return;
|
||||||
|
|
||||||
|
SettingsDropdowns.closeActive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: clayout
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: idleLayout.implicitHeight + Appearance.padding.normal * 2
|
||||||
|
color: DynamicColors.tPalette.m3surfaceContainer
|
||||||
|
radius: Appearance.rounding.normal - Appearance.padding.smaller
|
||||||
|
z: -1
|
||||||
|
|
||||||
|
Idle {
|
||||||
|
id: idleLayout
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.margins: Appearance.padding.large
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component Settings: CustomRect {
|
||||||
|
id: settingsItem
|
||||||
|
|
||||||
|
required property string name
|
||||||
|
|
||||||
|
Layout.preferredHeight: 60
|
||||||
|
Layout.preferredWidth: 200
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: text
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
font.bold: true
|
||||||
|
font.pointSize: Appearance.font.size.large * 2
|
||||||
|
text: settingsItem.name
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+23
@@ -36,6 +36,10 @@ ColumnLayout {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
spacing: Appearance.spacing.smaller
|
spacing: Appearance.spacing.smaller
|
||||||
|
|
||||||
|
Settings {
|
||||||
|
name: "Idle Monitors"
|
||||||
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: [...Config.general.idle.timeouts]
|
model: [...Config.general.idle.timeouts]
|
||||||
|
|
||||||
@@ -57,4 +61,23 @@ ColumnLayout {
|
|||||||
|
|
||||||
onClicked: root.addTimeoutEntry()
|
onClicked: root.addTimeoutEntry()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
component Settings: CustomRect {
|
||||||
|
id: settingsItem
|
||||||
|
|
||||||
|
required property string name
|
||||||
|
|
||||||
|
Layout.preferredHeight: 60
|
||||||
|
Layout.preferredWidth: 200
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: text
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
font.bold: true
|
||||||
|
font.pointSize: Appearance.font.size.large * 2
|
||||||
|
text: settingsItem.name
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -23,13 +23,14 @@ Item {
|
|||||||
Connections {
|
Connections {
|
||||||
function onCurrentCategoryChanged() {
|
function onCurrentCategoryChanged() {
|
||||||
stack.pop();
|
stack.pop();
|
||||||
if (currentCategory === "general") {
|
if (currentCategory === "general")
|
||||||
stack.push(general);
|
stack.push(general);
|
||||||
} else if (currentCategory === "wallpaper") {
|
else if (currentCategory === "wallpaper")
|
||||||
stack.push(background);
|
stack.push(background);
|
||||||
} else if (currentCategory === "appearance") {
|
else if (currentCategory === "appearance")
|
||||||
stack.push(appearance);
|
stack.push(appearance);
|
||||||
}
|
else if (currentCategory === "lockscreen")
|
||||||
|
stack.push(lockscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
target: root
|
target: root
|
||||||
@@ -48,7 +49,6 @@ Item {
|
|||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
implicitHeight: layout.implicitHeight
|
|
||||||
implicitWidth: layout.implicitWidth
|
implicitWidth: layout.implicitWidth
|
||||||
|
|
||||||
Categories {
|
Categories {
|
||||||
@@ -100,4 +100,11 @@ Item {
|
|||||||
Cat.Appearance {
|
Cat.Appearance {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: lockscreen
|
||||||
|
|
||||||
|
Cat.Lockscreen {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -229,14 +229,20 @@ Item {
|
|||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
visible: root.modelData.activeAction === undefined
|
visible: root.modelData.activeAction === undefined
|
||||||
|
|
||||||
Item {
|
IconButton {
|
||||||
Layout.fillWidth: true
|
id: button
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignLeft
|
||||||
|
font.pointSize: Appearance.font.size.large
|
||||||
|
icon: "add"
|
||||||
|
|
||||||
|
onClicked: console.log(button.width)
|
||||||
|
// onClicked: root.addActiveActionRequested()
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomButton {
|
CustomText {
|
||||||
|
Layout.alignment: Qt.AlignLeft
|
||||||
text: qsTr("Add active action")
|
text: qsTr("Add active action")
|
||||||
|
|
||||||
onClicked: root.addActiveActionRequested()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import qs.Components
|
||||||
|
import qs.Config
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property string name
|
||||||
|
required property var object
|
||||||
|
required property list<string> settings
|
||||||
|
|
||||||
|
function commitChoice(choice: int, setting: string): void {
|
||||||
|
root.object[setting] = choice;
|
||||||
|
Config.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
function formattedValue(setting: string): string {
|
||||||
|
const value = root.object[setting];
|
||||||
|
|
||||||
|
console.log(value);
|
||||||
|
if (value === null || value === undefined)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
return String(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hourToAmPm(hour) {
|
||||||
|
var h = Number(hour) % 24;
|
||||||
|
var d = new Date(2000, 0, 1, h, 0, 0);
|
||||||
|
return Qt.formatTime(d, "h AP");
|
||||||
|
}
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: row.implicitHeight + Appearance.padding.smaller * 2
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: row
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.margins: Appearance.padding.small
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: text
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignLeft
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.pointSize: Appearance.font.size.larger
|
||||||
|
text: root.name
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
Layout.alignment: Qt.AlignLeft
|
||||||
|
color: DynamicColors.palette.m3onSurfaceVariant
|
||||||
|
font.pointSize: Appearance.font.size.normal
|
||||||
|
text: qsTr("Dark mode will turn on at %1, and turn off at %2.").arg(root.hourToAmPm(root.object[root.settings[0]])).arg(root.hourToAmPm(root.object[root.settings[1]]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SpinnerButton {
|
||||||
|
Layout.preferredHeight: Appearance.font.size.large + Appearance.padding.smaller * 2
|
||||||
|
Layout.preferredWidth: height * 2
|
||||||
|
currentIndex: root.object[root.settings[0]]
|
||||||
|
text: root.formattedValue(root.settings[0])
|
||||||
|
|
||||||
|
menu.onItemSelected: item => {
|
||||||
|
root.commitChoice(item, root.settings[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SpinnerButton {
|
||||||
|
Layout.preferredHeight: Appearance.font.size.large + Appearance.padding.smaller * 2
|
||||||
|
Layout.preferredWidth: height * 2
|
||||||
|
currentIndex: root.object[root.settings[1]]
|
||||||
|
text: root.formattedValue(root.settings[1])
|
||||||
|
|
||||||
|
menu.onItemSelected: item => {
|
||||||
|
root.commitChoice(item, root.settings[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import qs.Components
|
||||||
|
import qs.Helpers
|
||||||
|
import qs.Config
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property alias currentIndex: menu.currentIndex
|
||||||
|
property alias expanded: menu.expanded
|
||||||
|
property alias label: label
|
||||||
|
property alias menu: menu
|
||||||
|
property alias text: label.text
|
||||||
|
|
||||||
|
color: DynamicColors.palette.m3primary
|
||||||
|
radius: Appearance.rounding.full
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: label
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: DynamicColors.palette.m3onPrimary
|
||||||
|
font.pointSize: Appearance.font.size.large
|
||||||
|
}
|
||||||
|
|
||||||
|
StateLayer {
|
||||||
|
function onClicked(): void {
|
||||||
|
SettingsDropdowns.toggle(menu, root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PathViewMenu {
|
||||||
|
id: menu
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
from: 1
|
||||||
|
implicitWidth: root.width
|
||||||
|
itemHeight: root.height
|
||||||
|
to: 24
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user