|
| 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 | +} |
0 commit comments