diff --git a/docs/astro/src/content/docs/reference/std-widgets/basic-widgets/slider.mdx b/docs/astro/src/content/docs/reference/std-widgets/basic-widgets/slider.mdx index 5b3beab590a..1c5e46f2f8c 100644 --- a/docs/astro/src/content/docs/reference/std-widgets/basic-widgets/slider.mdx +++ b/docs/astro/src/content/docs/reference/std-widgets/basic-widgets/slider.mdx @@ -71,6 +71,7 @@ Slider { ### maximum The maximum value. +If the maximum value is lower than the minimum, the slider is inverted. ```slint "maximum: 10;" Slider { maximum: 10; diff --git a/examples/gallery/ui/pages/controls_page.slint b/examples/gallery/ui/pages/controls_page.slint index fb31f0b1d83..af1b42e4c58 100644 --- a/examples/gallery/ui/pages/controls_page.slint +++ b/examples/gallery/ui/pages/controls_page.slint @@ -123,15 +123,54 @@ export component ControlsPage inherits Page { } GroupBox { - title: @tr("Slider"); + title: @tr("Sliders"); vertical-stretch: 0; - - slider := Slider { - min-width: 160px; - minimum: -100; - maximum: 100; - value: 42; - enabled: GallerySettings.widgets-enabled; + HorizontalLayout{ + VerticalLayout { + Text { text: "Slider"; } + slider := Slider { + min-width: 160px; + minimum: -100; + maximum: 100; + value: 42; + enabled: GallerySettings.widgets-enabled; + } + Text { text: "Value: \{slider.value}"; } + + Text { text: "Inverted Slider"; } + slider-inv := Slider { + min-width: 160px; + minimum: 100; + maximum: -100; + value: 42; + enabled: GallerySettings.widgets-enabled; + } + Text { text: "Value: \{slider-inv.value}"; } + } + VerticalLayout { + Text { text: "Vertical slider"; } + v-slider := Slider { + min-height: 160px; + minimum: -100; + maximum: 100; + value: 42; + orientation: Orientation.vertical; + enabled: GallerySettings.widgets-enabled; + } + Text { text: "Value: \{v-slider.value}"; } + } + VerticalLayout { + Text { text: "Inverted vertical slider"; } + v-slider-inv := Slider { + min-height: 160px; + minimum: 100; + maximum: -100; + value: 42; + orientation: Orientation.vertical; + enabled: GallerySettings.widgets-enabled; + } + Text { text: "Value: \{v-slider-inv.value}"; } + } } } diff --git a/internal/backends/qt/qt_widgets/slider.rs b/internal/backends/qt/qt_widgets/slider.rs index c1a68c5dc59..0d50eb818f1 100644 --- a/internal/backends/qt/qt_widgets/slider.rs +++ b/internal/backends/qt/qt_widgets/slider.rs @@ -351,7 +351,8 @@ impl Item for NativeSlider { impl NativeSlider { fn set_value(self: Pin<&Self>, new_val: f32) { - let new_val = new_val.max(self.minimum()).min(self.maximum()); + let new_val = + new_val.max(self.minimum().min(self.maximum())).min(self.maximum().max(self.minimum())); self.value.set(new_val); Self::FIELD_OFFSETS.changed.apply_pin(self).call(&(new_val,)); } diff --git a/internal/compiler/widgets/common/slider-base.slint b/internal/compiler/widgets/common/slider-base.slint index 35f2445d690..904cdeff6f1 100644 --- a/internal/compiler/widgets/common/slider-base.slint +++ b/internal/compiler/widgets/common/slider-base.slint @@ -48,8 +48,9 @@ export component SliderBase { if (!root.handle-has-hover) { - root.set-value((!root.vertical ? root.size-to-value(touch-area.mouse-x, root.width) : - root.size-to-value(touch-area.mouse-y, root.height)) + root.minimum); + root.set-value( (!vertical ? root.size-to-value(touch-area.mouse-x + ((touch-area.mouse-x/root.width - 0.5)*root.ref-size ), root.width) : + root.size-to-value(touch-area.mouse-y + ((touch-area.mouse-y/root.height - 0.5)*root.ref-size ), root.height)) + ); } self.pressed-value = value; @@ -61,9 +62,8 @@ export component SliderBase { if (!self.enabled) { return; } - - root.set-value(self.pressed-value + (!vertical ? root.size-to-value(touch-area.mouse-x - touch-area.pressed-x, root.width - root.ref-size) : - root.size-to-value(touch-area.mouse-y - touch-area.pressed-y, root.height - root.ref-size)) + root.set-value( (!vertical ? root.size-to-value(touch-area.mouse-x + ((touch-area.mouse-x/root.width - 0.5)*root.ref-size ), root.width) : + root.size-to-value(touch-area.mouse-y + ((touch-area.mouse-y/root.height - 0.5)*root.ref-size ), root.height)) ); } } @@ -104,7 +104,7 @@ export component SliderBase { } pure function size-to-value(size: length, range: length) -> float { - size * (root.maximum - root.minimum) / range; + size / range * (root.maximum - root.minimum) + root.minimum } function set-value(value: float) { @@ -112,7 +112,7 @@ export component SliderBase { return; } - root.value = max(root.minimum, min(root.maximum, value)); + root.value = root.maximum>root.minimum ? max(root.minimum, min(root.maximum, value)) : max(root.maximum, min(root.minimum, value)); root.changed(root.value); } } diff --git a/internal/compiler/widgets/cosmic/slider.slint b/internal/compiler/widgets/cosmic/slider.slint index 12cd0816207..f7a7d5d8680 100644 --- a/internal/compiler/widgets/cosmic/slider.slint +++ b/internal/compiler/widgets/cosmic/slider.slint @@ -43,10 +43,12 @@ export component Slider { } track := Rectangle { - x: base.vertical ? (parent.width - self.width) / 2 : 0; - y: base.vertical ? 0 : (parent.height - self.height) / 2; - width: base.vertical ? rail.width : thumb.x + (thumb.width / 2); - height: base.vertical ? thumb.y + (thumb.height / 2) : rail.height; + x: base.vertical ? (parent.width - self.width) / 2 : + root.maximum>root.minimum ? 0 : thumb.x + (thumb.width / 2); + y: base.vertical ? root.maximum>root.minimum ? 0 : thumb.y + (thumb.height / 2) : (parent.height - self.height) / 2; + width: base.vertical ? rail.width : + root.maximum>root.minimum ? thumb.x + (thumb.width / 2) : parent.width - thumb.x - (thumb.width / 2); + height: base.vertical ? root.maximum>root.minimum ? thumb.y + (thumb.height / 2) : parent.height - thumb.y - (thumb.height / 2) : rail.height; background: CosmicPalette.secondary-accent-background; border-radius: rail.border-radius; } diff --git a/internal/compiler/widgets/cupertino/slider.slint b/internal/compiler/widgets/cupertino/slider.slint index e8d5122c100..7054dacf942 100644 --- a/internal/compiler/widgets/cupertino/slider.slint +++ b/internal/compiler/widgets/cupertino/slider.slint @@ -51,10 +51,12 @@ export component Slider { } track := Rectangle { - x: base.vertical ? (parent.width - self.width) / 2 : 0; - y: base.vertical ? 0 : (parent.height - self.height) / 2; - width: base.vertical ? rail.width : thumb.x + (thumb.width / 2); - height: base.vertical ? thumb.y + (thumb.height / 2) : rail.height; + x: base.vertical ? (parent.width - self.width) / 2 : + root.maximum>root.minimum ? 0 : thumb.x + (thumb.width / 2); + y: base.vertical ? root.maximum>root.minimum ? 0 : thumb.y + (thumb.height / 2) : (parent.height - self.height) / 2; + width: base.vertical ? rail.width : + root.maximum>root.minimum ? thumb.x + (thumb.width / 2) : parent.width - thumb.x - (thumb.width / 2); + height: base.vertical ? root.maximum>root.minimum ? thumb.y + (thumb.height / 2) : parent.height - thumb.y - (thumb.height / 2) : rail.height; background: CupertinoPalette.accent-background; border-radius: rail.border-radius; } diff --git a/internal/compiler/widgets/fluent/slider.slint b/internal/compiler/widgets/fluent/slider.slint index 36f59b04a50..bf79e73b507 100644 --- a/internal/compiler/widgets/fluent/slider.slint +++ b/internal/compiler/widgets/fluent/slider.slint @@ -53,10 +53,12 @@ export component Slider { } track := Rectangle { - x: base.vertical ? (parent.width - self.width) / 2 : 0; - y: base.vertical ? 0 : (parent.height - self.height) / 2; - width: base.vertical ? rail.width : thumb.x + (thumb.width / 2); - height: base.vertical ? thumb.y + (thumb.height / 2) : rail.height; + x: base.vertical ? (parent.width - self.width) / 2 : + root.maximum>root.minimum ? 0 : thumb.x + (thumb.width / 2); + y: base.vertical ? root.maximum>root.minimum ? 0 : thumb.y + (thumb.height / 2) : (parent.height - self.height) / 2; + width: base.vertical ? rail.width : + root.maximum>root.minimum ? thumb.x + (thumb.width / 2) : parent.width - thumb.x - (thumb.width / 2); + height: base.vertical ? root.maximum>root.minimum ? thumb.y + (thumb.height / 2) : parent.height - thumb.y - (thumb.height / 2) : rail.height; background: FluentPalette.accent-background; border-radius: rail.border-radius; } diff --git a/internal/compiler/widgets/material/slider.slint b/internal/compiler/widgets/material/slider.slint index e09a32647a7..42c74e19108 100644 --- a/internal/compiler/widgets/material/slider.slint +++ b/internal/compiler/widgets/material/slider.slint @@ -58,10 +58,13 @@ export component Slider { track := Rectangle { background: MaterialPalette.accent-background; - x: base.vertical ? (parent.width - self.width) / 2 : background.x; - y: base.vertical ? background.y : (parent.height - self.height) / 2; - width: base.vertical? background.width : handle.x + (handle.width / 2); - height: base.vertical? handle.y + (handle.height / 2) : background.height; + + x: base.vertical ? (parent.width - self.width) / 2 : + root.maximum>root.minimum ? background.x : handle.x + (handle.width / 2); + y: base.vertical ? root.maximum>root.minimum ? background.y : handle.y + (handle.height / 2) : (parent.height - self.height) / 2; + width: base.vertical ? background.width : + root.maximum>root.minimum ? handle.x + (handle.width / 2) : parent.width - handle.x - (handle.width / 2); + height: base.vertical ? root.maximum>root.minimum ? handle.y + (handle.height / 2) : parent.height - handle.y - (handle.height / 2) : background.height; border-radius: background.border-radius; }