mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-30 13:51:13 +00:00
Added Spinner widget (#3871)
This commit is contained in:
parent
3c9dca6daf
commit
110689bad1
14 changed files with 217 additions and 5 deletions
|
@ -27,6 +27,7 @@ All notable changes to this project are documented in this file.
|
||||||
- `SpinBox` value can now be incremented and decremented by scroll event
|
- `SpinBox` value can now be incremented and decremented by scroll event
|
||||||
- Added `focus-changed-event` callback to `FocusScope`
|
- Added `focus-changed-event` callback to `FocusScope`
|
||||||
- Added many new easing curves.
|
- Added many new easing curves.
|
||||||
|
- Added `Spinner`
|
||||||
|
|
||||||
### Rust
|
### Rust
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ Widgets
|
||||||
scrollview.md
|
scrollview.md
|
||||||
slider.md
|
slider.md
|
||||||
spinbox.md
|
spinbox.md
|
||||||
|
spinner.md
|
||||||
standardbutton.md
|
standardbutton.md
|
||||||
standardlistview.md
|
standardlistview.md
|
||||||
standardtableview.md
|
standardtableview.md
|
||||||
|
|
24
docs/reference/src/language/widgets/spinner.md
Normal file
24
docs/reference/src/language/widgets/spinner.md
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<!-- Copyright © SixtyFPS GmbH <info@slint.dev> ; SPDX-License-Identifier: MIT -->
|
||||||
|
|
||||||
|
## `Spinner`
|
||||||
|
|
||||||
|
The `Spinner` informs the user about the status of an on-going operation, such as loading data from the network. It provides the same properties as
|
||||||
|
[`ProgressIndicator`](./progressindicator.md) but differs in shape.
|
||||||
|
|
||||||
|
### Properties
|
||||||
|
|
||||||
|
- **`indeterminate`**: (_in_ _bool_): Set to true if the progress of the operation cannot be determined by value (default value: `false`).
|
||||||
|
- **`progress`** (_in_ _float_): Percentage of completion, as value between 0 and 1. Values less than 0 or greater than 1 are capped.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```slint
|
||||||
|
import { Spinner } from "std-widgets.slint";
|
||||||
|
export component Example inherits Window {
|
||||||
|
width: 200px;
|
||||||
|
height: 25px;
|
||||||
|
Spinner {
|
||||||
|
progress: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
|
@ -2,7 +2,7 @@
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
import { Button, GroupBox, SpinBox, ComboBox, CheckBox, LineEdit, TabWidget, VerticalBox, HorizontalBox,
|
import { Button, GroupBox, SpinBox, ComboBox, CheckBox, LineEdit, TabWidget, VerticalBox, HorizontalBox,
|
||||||
Slider, ProgressIndicator, SpinBox, Switch } from "std-widgets.slint";
|
Slider, ProgressIndicator, SpinBox, Switch, Spinner, GridBox } from "std-widgets.slint";
|
||||||
import { GallerySettings } from "../gallery_settings.slint";
|
import { GallerySettings } from "../gallery_settings.slint";
|
||||||
import { Page } from "page.slint";
|
import { Page } from "page.slint";
|
||||||
|
|
||||||
|
@ -106,19 +106,33 @@ export component ControlsPage inherits Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupBox {
|
GroupBox {
|
||||||
title: @tr("ProgressIndicator");
|
title: @tr("ProgressIndicator | Spinner");
|
||||||
vertical-stretch: 0;
|
vertical-stretch: 0;
|
||||||
|
|
||||||
VerticalLayout {
|
GridBox {
|
||||||
spacing: 16px;
|
spacing: 16px;
|
||||||
|
|
||||||
i-progress-indicator := ProgressIndicator {
|
i-progress-indicator := ProgressIndicator {
|
||||||
|
row: 0;
|
||||||
|
col: 0;
|
||||||
min-width: 160px;
|
min-width: 160px;
|
||||||
progress: (i-slider.value - i-slider.minimum) / (i-slider.maximum - i-slider.minimum);
|
progress: (i-slider.value - i-slider.minimum) / (i-slider.maximum - i-slider.minimum);
|
||||||
indeterminate: true;
|
indeterminate: true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
row: 0;
|
||||||
|
col: 1;
|
||||||
|
rowspan: 2;
|
||||||
|
Spinner {
|
||||||
|
progress: i-progress-indicator.progress;
|
||||||
|
indeterminate: i-progress-indicator.indeterminate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CheckBox {
|
CheckBox {
|
||||||
|
row: 1;
|
||||||
|
col: 0;
|
||||||
text: @tr("indeterminate");
|
text: @tr("indeterminate");
|
||||||
checked <=> i-progress-indicator.indeterminate;
|
checked <=> i-progress-indicator.indeterminate;
|
||||||
}
|
}
|
||||||
|
|
65
internal/compiler/widgets/common/spinner-base.slint
Normal file
65
internal/compiler/widgets/common/spinner-base.slint
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
||||||
|
|
||||||
|
export component SpinnerBase {
|
||||||
|
in property <float> progress;
|
||||||
|
in property <bool> indeterminate;
|
||||||
|
in property <length> stroke-width <=> path.stroke-width;
|
||||||
|
in property <brush> stroke <=> path.stroke;
|
||||||
|
|
||||||
|
path := Path {
|
||||||
|
private property <float> radius: min(self.viewbox-width, self.viewbox-height) / 2;
|
||||||
|
private property <float> start-x: self.viewbox-width / 2;
|
||||||
|
private property <float> start-y: self.viewbox-height / 2;
|
||||||
|
private property <float> thickness: 2;
|
||||||
|
private property <float> inner-radius: self.radius - self.thickness;
|
||||||
|
private property <float> start : !indeterminate ? 0 :
|
||||||
|
1 * mod(animation-tick(), 3s) / 3s;
|
||||||
|
// min is a workaground to get filled circle by 1.0
|
||||||
|
private property <float> progress: !root.indeterminate ? min(0.999, root.progress) :
|
||||||
|
min(0.99, max(0.25, 1 * abs(sin(360deg * animation-tick() / 1.5s))));
|
||||||
|
|
||||||
|
viewbox-width: 100;
|
||||||
|
viewbox-height: 100;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
MoveTo {
|
||||||
|
x: start-x - radius * sin(-path.start * 360deg);
|
||||||
|
y: start-y - radius * cos(-path.start * 360deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
LineTo {
|
||||||
|
x: start-x - path.inner-radius * sin(-path.start * 360deg);
|
||||||
|
y: start-y - path.inner-radius * cos(-path.start * 360deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArcTo {
|
||||||
|
radius-x: path.inner-radius;
|
||||||
|
radius-y: path.inner-radius;
|
||||||
|
x: start-x - path.inner-radius * sin(-(path.start + path.progress) * 360deg);
|
||||||
|
y: start-y - path.inner-radius * cos(-(path.start + path.progress) * 360deg);
|
||||||
|
sweep: path.progress > 0;
|
||||||
|
large-arc: path.progress > 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
LineTo {
|
||||||
|
x: start-x - radius * sin(-(path.start + path.progress) * 360deg);
|
||||||
|
y: start-y - radius * cos(-(path.start + path.progress) * 360deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArcTo {
|
||||||
|
radius-x: radius;
|
||||||
|
radius-y: radius;
|
||||||
|
x: start-x - radius * sin(-path.start * 360deg);
|
||||||
|
y: start-y - radius * cos(-path.start * 360deg);
|
||||||
|
sweep: path.progress < 0;
|
||||||
|
large-arc: path.progress > 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
LineTo {
|
||||||
|
x: start-x - radius * sin(-path.start * 360deg);
|
||||||
|
y: start-y - radius * cos(-path.start * 360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
internal/compiler/widgets/cupertino-base/spinner.slint
Normal file
24
internal/compiler/widgets/cupertino-base/spinner.slint
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
||||||
|
|
||||||
|
import { Palette } from "styling.slint";
|
||||||
|
import { SpinnerBase } from "../common/spinner-base.slint";
|
||||||
|
|
||||||
|
export component Spinner {
|
||||||
|
in property <float> progress <=> base.progress;
|
||||||
|
in property <bool> indeterminate <=> base.indeterminate;
|
||||||
|
|
||||||
|
min-width: 30px;
|
||||||
|
min-height: 30px;
|
||||||
|
horizontal-stretch: 0;
|
||||||
|
vertical-stretch: 0;
|
||||||
|
accessible-role: progress-indicator;
|
||||||
|
accessible-value: root.progress;
|
||||||
|
|
||||||
|
base := SpinnerBase {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
stroke-width: 2px;
|
||||||
|
stroke: Palette.accent;
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,9 @@ export { Slider }
|
||||||
import { SpinBox } from "spinbox.slint";
|
import { SpinBox } from "spinbox.slint";
|
||||||
export { SpinBox }
|
export { SpinBox }
|
||||||
|
|
||||||
|
import { Spinner } from "spinner.slint";
|
||||||
|
export { Spinner }
|
||||||
|
|
||||||
import { TabWidgetImpl, TabImpl, TabBarImpl, TabWidget } from "tabwidget.slint";
|
import { TabWidgetImpl, TabImpl, TabBarImpl, TabWidget } from "tabwidget.slint";
|
||||||
export { TabWidgetImpl, TabImpl, TabBarImpl, TabWidget }
|
export { TabWidgetImpl, TabImpl, TabBarImpl, TabWidget }
|
||||||
|
|
||||||
|
|
24
internal/compiler/widgets/fluent-base/spinner.slint
Normal file
24
internal/compiler/widgets/fluent-base/spinner.slint
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
||||||
|
|
||||||
|
import { Palette } from "styling.slint";
|
||||||
|
import { SpinnerBase } from "../common/spinner-base.slint";
|
||||||
|
|
||||||
|
export component Spinner {
|
||||||
|
in property <float> progress <=> base.progress;
|
||||||
|
in property <bool> indeterminate <=> base.indeterminate;
|
||||||
|
|
||||||
|
min-width: 30px;
|
||||||
|
min-height: 30px;
|
||||||
|
horizontal-stretch: 0;
|
||||||
|
vertical-stretch: 0;
|
||||||
|
accessible-role: progress-indicator;
|
||||||
|
accessible-value: root.progress;
|
||||||
|
|
||||||
|
base := SpinnerBase {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
stroke-width: 2px;
|
||||||
|
stroke: Palette.accent-default;
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,9 @@ export { Slider }
|
||||||
import { SpinBox } from "spinbox.slint";
|
import { SpinBox } from "spinbox.slint";
|
||||||
export { SpinBox }
|
export { SpinBox }
|
||||||
|
|
||||||
|
import { Spinner } from "spinner.slint";
|
||||||
|
export { Spinner }
|
||||||
|
|
||||||
import { TabWidgetImpl, TabImpl, TabBarImpl, TabWidget } from "tabwidget.slint";
|
import { TabWidgetImpl, TabImpl, TabBarImpl, TabWidget } from "tabwidget.slint";
|
||||||
export { TabWidgetImpl, TabImpl, TabBarImpl, TabWidget }
|
export { TabWidgetImpl, TabImpl, TabBarImpl, TabWidget }
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ export component ProgressIndicator {
|
||||||
min-height: 4px;
|
min-height: 4px;
|
||||||
horizontal-stretch: 1;
|
horizontal-stretch: 1;
|
||||||
vertical-stretch: 0;
|
vertical-stretch: 0;
|
||||||
accessible-role: none;
|
accessible-role: progress-indicator;
|
||||||
accessible-value: root.progress;
|
accessible-value: root.progress;
|
||||||
|
|
||||||
i-background := Rectangle {
|
i-background := Rectangle {
|
||||||
|
|
24
internal/compiler/widgets/material-base/spinner.slint
Normal file
24
internal/compiler/widgets/material-base/spinner.slint
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
||||||
|
|
||||||
|
import { Palette } from "styling.slint";
|
||||||
|
import { SpinnerBase } from "../common/spinner-base.slint";
|
||||||
|
|
||||||
|
export component Spinner {
|
||||||
|
in property <float> progress <=> base.progress;
|
||||||
|
in property <bool> indeterminate <=> base.indeterminate;
|
||||||
|
|
||||||
|
min-width: 30px;
|
||||||
|
min-height: 30px;
|
||||||
|
horizontal-stretch: 0;
|
||||||
|
vertical-stretch: 0;
|
||||||
|
accessible-role: progress-indicator;
|
||||||
|
accessible-value: root.progress;
|
||||||
|
|
||||||
|
base := SpinnerBase {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
stroke-width: 2px;
|
||||||
|
stroke: Palette.primary;
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,3 +21,6 @@ import { Switch } from "switch.slint";
|
||||||
export { StyleMetrics, ScrollView, Button, ComboBox, CheckBox, GroupBox, StandardButton, TextEdit, TabWidgetImpl,
|
export { StyleMetrics, ScrollView, Button, ComboBox, CheckBox, GroupBox, StandardButton, TextEdit, TabWidgetImpl,
|
||||||
TabImpl, TabBarImpl, TabWidget, LineEdit, AboutSlint, VerticalBox, HorizontalBox,
|
TabImpl, TabBarImpl, TabWidget, LineEdit, AboutSlint, VerticalBox, HorizontalBox,
|
||||||
GridBox, Slider, ListView, StandardListView, StandardTableView, SpinBox, ProgressIndicator, Switch }
|
GridBox, Slider, ListView, StandardListView, StandardTableView, SpinBox, ProgressIndicator, Switch }
|
||||||
|
|
||||||
|
import { Spinner } from "spinner.slint";
|
||||||
|
export { Spinner }
|
23
internal/compiler/widgets/qt/spinner.slint
Normal file
23
internal/compiler/widgets/qt/spinner.slint
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
||||||
|
|
||||||
|
import { SpinnerBase } from "../common/spinner-base.slint";
|
||||||
|
|
||||||
|
export component Spinner {
|
||||||
|
in property <float> progress <=> base.progress;
|
||||||
|
in property <bool> indeterminate <=> base.indeterminate;
|
||||||
|
|
||||||
|
min-width: 30px;
|
||||||
|
min-height: 30px;
|
||||||
|
horizontal-stretch: 0;
|
||||||
|
vertical-stretch: 0;
|
||||||
|
accessible-role: progress-indicator;
|
||||||
|
accessible-value: root.progress;
|
||||||
|
|
||||||
|
base := SpinnerBase {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
stroke-width: 2px;
|
||||||
|
stroke: NativeStyleMetrics.dark-color-scheme ? #60CDFF : #005FB8;
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,4 +40,7 @@ import { HorizontalBox, VerticalBox, GridBox } from "layouts.slint";
|
||||||
export { HorizontalBox, VerticalBox, GridBox }
|
export { HorizontalBox, VerticalBox, GridBox }
|
||||||
|
|
||||||
import { ProgressIndicator } from "progressindicator.slint";
|
import { ProgressIndicator } from "progressindicator.slint";
|
||||||
export { ProgressIndicator }
|
export { ProgressIndicator }
|
||||||
|
|
||||||
|
import { Spinner } from "spinner.slint";
|
||||||
|
export { Spinner }
|
Loading…
Add table
Add a link
Reference in a new issue