veloren_voxygen/ui/ice/renderer/widget/
slider.rs1use super::super::{super::Rotation, IcedRenderer, Primitive, style};
2use common::util::srgba_to_linear;
3use core::ops::RangeInclusive;
4use iced::{Point, Rectangle, mouse, slider};
5use style::slider::{Bar, Cursor, Style};
6
7const CURSOR_DRAG_SHIFT: f32 = 0.7;
8
9impl slider::Renderer for IcedRenderer {
10 type Style = Style;
11
12 const DEFAULT_HEIGHT: u16 = 25;
13
14 fn draw(
15 &mut self,
16 bounds: Rectangle,
17 cursor_position: Point,
18 range: RangeInclusive<f32>,
19 value: f32,
20 is_dragging: bool,
21 style: &Self::Style,
22 ) -> Self::Output {
23 let bar_bounds = Rectangle {
24 height: style.bar_height as f32,
25 y: bounds.y + (bounds.height - style.bar_height as f32) / 2.0,
26 ..bounds
27 };
28 let bar = match style.bar {
29 Bar::Color(color) => Primitive::Rectangle {
30 bounds: bar_bounds,
31 linear_color: srgba_to_linear(color),
32 },
33 Bar::Image(handle, color, bar_pad) => Primitive::Image {
36 handle: (handle, Rotation::None),
37 bounds: Rectangle {
38 x: bar_bounds.x - bar_pad as f32,
39 width: bar_bounds.width + bar_pad as f32 * 2.0,
40 ..bar_bounds
41 },
42 color,
43 source_rect: None,
44 },
45 };
46
47 let (cursor_width, cursor_height) = style.cursor_size;
48 let (cursor_width, cursor_height) = (f32::from(cursor_width), f32::from(cursor_height));
49 let (min, max) = range.into_inner();
50 let offset = bounds.width * (value - min) / (max - min);
51 let cursor_bounds = Rectangle {
52 x: bounds.x + offset - cursor_width / 2.0,
53 y: bounds.y
54 + if is_dragging { CURSOR_DRAG_SHIFT } else { 0.0 }
55 + (bounds.height - cursor_height) / 2.0,
56 width: cursor_width,
57 height: cursor_height,
58 };
59 let cursor = match style.cursor {
60 Cursor::Color(color) => Primitive::Rectangle {
61 bounds: cursor_bounds,
62 linear_color: srgba_to_linear(color),
63 },
64 Cursor::Image(handle, color) => Primitive::Image {
65 handle: (handle, Rotation::None),
66 bounds: cursor_bounds,
67 color,
68 source_rect: None,
69 },
70 };
71
72 let interaction = if is_dragging {
73 mouse::Interaction::Grabbing
74 } else if cursor_bounds.contains(cursor_position) {
75 mouse::Interaction::Grab
76 } else if bar_bounds.contains(cursor_position) {
77 mouse::Interaction::Pointer
78 } else {
79 mouse::Interaction::Idle
80 };
81
82 let primitives = if style.labels {
83 vec![bar, cursor]
85 } else {
86 vec![bar, cursor]
88 };
89 (Primitive::Group { primitives }, interaction)
90 }
91}