-
Notifications
You must be signed in to change notification settings - Fork 16
Add components for quicksettings #58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
76d931e to
e701fef
Compare
… 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).
…eter animations - Introduced BatteryParticles, a reusable QML component in org.asteroid.controls, for animated particles in battery meter visualizations. - Supported multiple designs (diamonds, bubbles, logos, flashes) with dynamic size and opacity properties per design. - Implemented position, scale, and opacity animations, with self-destruction after a configurable lifetime. - Added QML documentation and example, styled like LabeledSwitch and OptionCycler, for system-wide use. - Registered component in org.asteroid.controls qmldir for module-based access.
- Updated designProperties for subtler particle sizes: - Diamonds/Bubbles: initialSize 0.3 (was 0.4), maxSize 0.9 (was 1.0). - Logos: initialSize 0.4 (was 0.5), maxSize 1.2. - Flashes: initialSize 0.6, maxSize 1.4 (unchanged). - Set maxOpacity to 0.6 across all designs for consistent appearance. - Removed console logs for PR readiness.
…tdowns
Introduce a new 'RemorseTimer' QML component in 'org.asteroid.controls', designed for system-wide use in confirming critical actions like power-off or reboot. The component displays a semi-transparent overlay with a customizable 'SegmentedArc' gauge, an action message, a countdown label, and a 'Tap to cancel' prompt. Key features include:
- Configurable countdown duration via the 'interval' property (default 3000ms).
- Customizable 'SegmentedArc' gauge with 'gaugeSegmentAmount' (default 6), 'gaugeStartDegree' (default -130), and 'gaugeEndFromStartDegree' (default 265) for flexible arc styling.
- Smooth arc progression using a 0-100 'inputValue' range, with segments depleting gradually over the interval.
- Precise second-by-second countdown display (e.g., 3->1 for 3000ms) synchronized with the arc.
- 300ms fade-in animation on start and fade-out on cancellation for a polished UX.
- Bold countdown label ('Dims.l(18)', 'SemiBoldCondensed') and action/cancel labels ('Dims.l(6)') with tight margins ('Dims.l(1)') for a modern look.
- Translated action and cancel messages using 'qsTrId' for internationalization.
- Signals for 'triggered' (on timeout) and 'cancelled' (on tap) to integrate with system actions.
- Introduced ValueMeter.qml, a reusable component in org.asteroid.controls for displaying values within a range, with properties for width, height, value bounds, current value, isIncreasing, animations, and particle design. - Generalized battery meter logic, supporting wave animation and particle effects via Particles.qml. - Added fillColor property to ValueMeter.qml, moving battery-specific color logic to callers. - Removed distracting color pulse animation from ValueMeter.qml for cleaner visuals. - Renamed BatteryParticles.qml to Particles.qml, generalizing nomenclature and changing isCharging to isIncreasing for consistency. - Updated ValueMeter.qml to reference Particles.qml, ensuring compatibility.
e701fef to
e4a7239
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't finished reviewing this yet. But thought I'd start here 😄
|
|
||
| HighlightBar { | ||
| onClicked: { | ||
| if (configObject && configObject.batteryAnimation) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two things:
- Can you invert this if statement such that nesting is reduced.
- what's
batteryAnimationthis PR references it only once, the documentation also doesn't mention it. Can it be removed?
| HighlightBar { | ||
| onClicked: { | ||
| if (configObject && configObject.batteryAnimation) { | ||
| var currentIndex = valueArray.indexOf(currentValue) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would happen if the same text occurs in the array? Would things break?
Is this intended behavior or could this be solved by keeping track of the current index globally?
| var nextIndex = (currentIndex + 1) % valueArray.length | ||
| var newValue = valueArray[nextIndex] | ||
| currentValue = newValue | ||
| if (configObject && configKey) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
configObject is already checked, why the additional check?
| valueArray: designOptions | ||
| currentValue: config.design | ||
| onValueChanged: { | ||
| config.design = value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this update config.design twice? Once via the internal logic using configObject and configKey?
If this is the case, then imo the better approach would be to just use the onValueChanged version.
| \qmlproperty string RemorseTimer::cancelText | ||
| The text displayed for the cancel prompt (e.g., "Tap to cancel"). Can be a translated string. | ||
| */ | ||
| property string cancelText: "Tap to cancel" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is untranslated.
We don't seem to allow translations in qml-asteroid. So maybe it would work if this is changed to an alias:
property alias text: cancelLabel.text|
|
||
| /*! | ||
| \qmlproperty string RemorseTimer::action | ||
| The action message displayed (e.g., "Powering Off"). Should be a translated string. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the distinction between Should be a translated string. and Can be a translated string. between the action and cancelText?
Either way, is it relevant that both should be translated? This is a detail for whoever decides to use it right?
| \qmlproperty string RemorseTimer::action | ||
| The action message displayed (e.g., "Powering Off"). Should be a translated string. | ||
| */ | ||
| property string action: "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can also be an alias right? That way you don't need to explicitly set it here. And it makes it probably consistent with the rest of the codebase.
|
|
||
| // Start the timer and show the overlay | ||
| function start() { | ||
| countdownSeconds = Math.floor(interval / 1000); // Reset to 3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the user doesn't use the interval = 3. Does it still reset to 3? 😉
|
|
||
| Timer { | ||
| id: syncTimer | ||
| interval: remorseTimer.interval / Math.floor(remorseTimer.interval / 1000) // 1000ms for 3000ms |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comment below, don't use your example value for something the user is probably going to override.
Since these types of comments are obvious, you might as well refrain from using them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additionally this always returns 1000. Might as well use that right?
Example
remorseTimer.interval = 3000
interval: 3000 / floor(3000 / 1000) -> 3000 / floor(3) -> 1000
remorseTimer.interval = 5000
interval: 5000 / floor(5000 / 1000) -> 5000 / floor(5) -> 1000
Additionally this introduces a bug when remorseTimer.interval is less than 1000 as Math.floor(remorseTimer.interval / 1000) would yield zero. And division by zero results in errors.
Add New QML Components for the QuickSettings Redesign
This pull request introduces four new QML components to the
qml-asteroidmodule, enhancing the AsteroidOS QuickSettings rework. These components are designed to provide polished, reusable UI elements for our smartwatch interface, integrated into theimport asteroid.controls 1.0context. Below is a brief specification and example use case for each component.1. OptionsCycler
Specification:

OptionsCycleris a QML component that allows users to cycle through a predefined array of configuration values for a specific key in a configuration object. It displays a title and the current value, updating the configuration when the user taps to cycle through options. The component supports dynamic value arrays and integrates withNemo.Configurationfor persistent settings. It features smooth opacity transitions (250ms) for visual feedback and is modelled after the LabeledSwitch for good touch interaction on small screens.Example Use Case:
In the QuickSettings configuration page,
OptionsCycleris used to select the particle animation design (e.g., "diamonds", "bubbles", "logos", "flashes") for the battery meter. Users tap to cycle through designs, with the selected value saved to theoptionsconfiguration for theValueMetercomponent.2. RemorseTimer
Specification:

RemorseTimeris a QML component that implements a countdown timer with a visual gauge for confirming or canceling actions. It supports customizable intervals (default 3000ms), gauge segments (default 6), and angular range (default: start: -130°, end: +265° from start). The component displays an action text and a cancel prompt (both translatable viaqsTrId), triggering a signal when the timer completes unless canceled by user tap. It is ideal for actions requiring confirmation, such as system shutdowns.Example Use Case:
In QuickSettings,
RemorseTimeris used for thepowerOffToggleandrebootToggle. When the user activates the power-off toggle, a 3-second countdown with a gauge appears, showing "Powering off in" and "Tap to cancel". If not canceled, it triggers alogin1DBuscall copied from the PowerPage.qml to power off the device.3. Particles
Specification:

Particlesis a QML component for rendering animated particles in meter or gauge visualizations. It supports multiple extendible designs (currently: "diamonds", "bubbles", "logos", "flashes") with customizable properties likemaxSize,targetX,lifetime(default 1200ms), andclipBounds. Particles animate their position, size, and opacity usingParallelAnimationwithInOutSineandOutQuad/InQuadeasing curves. The component self-destructs after its lifetime or if it moves outside the clip bounds, optimizing performance.Example Use Case:
In the
ValueMetercomponent,Particlesenhances the battery meter animation. When the battery is charging, particles (e.g., diamond-shaped) spawn and move across the meter, scaling, fading and changing speed and direction to visualize the charging state. The design is configurable via theparticleDesignoption, set throughOptionsCycler.4. ValueMeter
Specification:

ValueMeteris a QML component for displaying a dynamic meter that visualizes values like battery percentage, volume, or brightness. It supports a range (valueLowerBoundtovalueUpperBound), animated fill transitions (250ms,InOutQuadeasing), and optional colored fills based on value thresholds. The component integratesParticlesfor animations (enabled viaenableAnimations) and supports opacity transitions (250ms) and color animations (300ms). It includes timers for resetting display modes (resetTimer,fadeOutTimer,fadeInTimer) and emits aresetDirectionsignal for toggle synchronization.Example Use Case:
In QuickSettings,
ValueMeterdisplays the battery percentage by default, switching to brightness or volume when the respective toggles (brightnessToggle,soundToggle) are adjusted. For example, during volume adjustment, it shows a blue-tinted meter (#4C9800A6) reflecting the current volume level, with smooth fill animations and a 2-second reset to battery display.Changes
OptionsCycler.qml,RemorseTimer.qml,Particles.qml, andValueMeter.qmltoqml-asteroid.asteroid.controls 1.0for use inQuickSettings.qmlandQuickSettingsPage.qml.Commit Notes
This PR lays the foundation for an enhanced QuickSettings experience in AsteroidOS, making the interface more interactive and visually engaging.
Please review and provide feedback!