Skip to content

Commit 5386ea8

Browse files
committed
Add OptionCycler component to org.asteroid.controls for configuration value cycling
- Introduced OptionCycler, a reusable QML component in org.asteroid.controls, analogous to LabeledSwitch, for cycling through configuration values system-wide. - Implemented title label (top-left-aligned) and value label (centered) for clear presentation of configuration options. - Enabled value cycling through a provided array on click, updating a specified configObject key and emitting a valueChanged signal. - Added conditional touch disabling via HighlightBar onClicked handler, preserving ListView scrolling and supporting external state checks (e.g., batteryAnimation). - Supported visual feedback with configurable opacity (e.g., 0.5 when disabled) for intuitive user interaction. - Provided comprehensive QML documentation with an example, following LabeledSwitch style. - Configured customizable layout with labelMargin, labelFontSize, and flexible height (typically rowHeight * 2 in use).
1 parent ac9ac0b commit 5386ea8

File tree

3 files changed

+161
-0
lines changed

3 files changed

+161
-0
lines changed

src/controls/qml/OptionCycler.qml

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/*
2+
* Copyright (C) 2025 Timo Könnecke <github.com/eLtMosen>
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
import QtQuick 2.9
19+
import org.asteroid.controls 1.0
20+
21+
/*!
22+
\qmltype OptionCycler
23+
\inqmlmodule org.asteroid.controls 1.0
24+
25+
\brief A component that displays and cycles through a list of configuration values.
26+
27+
This component displays a title label and a value label showing the current value from a provided array of configuration options.
28+
Clicking the component cycles to the next value in the array, looping back to the first value when the end is reached.
29+
It is designed to work with configuration settings, updating a specified configuration object when the value changes.
30+
31+
This example shows a centered \l OptionCycler that cycles through a list of design options, updating a configuration object.
32+
33+
\qml
34+
import QtQuick 2.9
35+
import org.asteroid.controls 1.0
36+
37+
Item {
38+
anchors.fill: parent
39+
property var config: ({ design: "diamonds" })
40+
property var designOptions: ["diamonds", "bubbles", "logos", "flashes"]
41+
42+
OptionCycler {
43+
anchors.centerIn: parent
44+
width: Dims.l(80)
45+
height: Dims.l(20)
46+
title: "Tap to cycle designs"
47+
configObject: config
48+
configKey: "design"
49+
valueArray: designOptions
50+
currentValue: config.design
51+
onValueChanged: {
52+
config.design = value
53+
}
54+
}
55+
}
56+
\endqml
57+
*/
58+
59+
Item {
60+
/*!
61+
\qmlproperty string OptionCycler::title
62+
The title text to display above the current value.
63+
*/
64+
property alias title: titleLabel.text
65+
66+
/*!
67+
\qmlproperty var OptionCycler::configObject
68+
The configuration object that holds the current value.
69+
*/
70+
property var configObject
71+
72+
/*!
73+
\qmlproperty string OptionCycler::configKey
74+
The key in the configuration object to update with the selected value.
75+
*/
76+
property string configKey
77+
78+
/*!
79+
\qmlproperty array OptionCycler::valueArray
80+
The array of values to cycle through.
81+
*/
82+
property var valueArray
83+
84+
/*!
85+
\qmlproperty string OptionCycler::currentValue
86+
The currently selected value, synchronized with the config object.
87+
*/
88+
property string currentValue
89+
90+
/*!
91+
\qmlsignal OptionCycler::valueChanged(string value)
92+
Emitted when the selected value changes, passing the new value.
93+
*/
94+
signal valueChanged(string value)
95+
96+
/*! Left and right margin for the label content */
97+
property int labelMargin: Dims.w(15)
98+
99+
/*! Size of the label text */
100+
property int labelFontSize: Dims.l(6)
101+
102+
/*! Default width is parent width */
103+
width: parent.width
104+
105+
/*! Default height is parent height */
106+
height: parent.height
107+
108+
Behavior on opacity {
109+
NumberAnimation {
110+
duration: 200
111+
easing.type: Easing.OutQuad
112+
}
113+
}
114+
115+
Label {
116+
id: titleLabel
117+
anchors {
118+
top: parent.top
119+
left: parent.left
120+
leftMargin: labelMargin
121+
}
122+
font.pixelSize: labelFontSize
123+
verticalAlignment: Text.AlignTop
124+
horizontalAlignment: Text.AlignLeft
125+
wrapMode: Text.Wrap
126+
height: parent.height / 2
127+
}
128+
129+
Label {
130+
id: valueLabel
131+
anchors {
132+
top: titleLabel.bottom
133+
horizontalCenter: parent.horizontalCenter
134+
}
135+
text: currentValue
136+
font.pixelSize: labelFontSize
137+
verticalAlignment: Text.AlignTop
138+
horizontalAlignment: Text.AlignRight
139+
wrapMode: Text.Wrap
140+
height: parent.height / 2
141+
}
142+
143+
HighlightBar {
144+
onClicked: {
145+
if (configObject && configObject.batteryAnimation) {
146+
var currentIndex = valueArray.indexOf(currentValue)
147+
var nextIndex = (currentIndex + 1) % valueArray.length
148+
var newValue = valueArray[nextIndex]
149+
currentValue = newValue
150+
if (configObject && configKey) {
151+
var newConfig = Object.assign({}, configObject)
152+
newConfig[configKey] = newValue
153+
configObject = newConfig
154+
}
155+
valueChanged(newValue)
156+
}
157+
}
158+
}
159+
}

src/controls/qmldir

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ LabeledSwitch 1.0 qrc:///org/asteroid/controls/qml/LabeledSwitch.qml
1717
LayerStack 1.0 qrc:///org/asteroid/controls/qml/LayerStack.qml
1818
ListItem 1.0 qrc:///org/asteroid/controls/qml/ListItem.qml
1919
Marquee 1.0 qrc:///org/asteroid/controls/qml/Marquee.qml
20+
OptionCycler 1.0 qrc:///org/asteroid/controls/qml/OptionCycler.qml
2021
PageDot 1.0 qrc:///org/asteroid/controls/qml/PageDot.qml
2122
PageHeader 1.0 qrc:///org/asteroid/controls/qml/PageHeader.qml
2223
SegmentedArc 1.0 qrc:///org/asteroid/controls/qml/SegmentedArc.qml

src/controls/resources.qrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<file>qml/LabeledSwitch.qml</file>
1616
<file>qml/LabeledActionButton.qml</file>
1717
<file>qml/PageDot.qml</file>
18+
<file>qml/OptionCycler.qml</file>
1819
<file>qml/PageHeader.qml</file>
1920
<file>qml/IntSelector.qml</file>
2021
<file>qml/SegmentedArc.qml</file>

0 commit comments

Comments
 (0)