diff --git a/voxygen/src/ui/ice/renderer/style/mod.rs b/voxygen/src/ui/ice/renderer/style/mod.rs index 370210eaaa..04297da836 100644 --- a/voxygen/src/ui/ice/renderer/style/mod.rs +++ b/voxygen/src/ui/ice/renderer/style/mod.rs @@ -1,3 +1,4 @@ pub mod button; pub mod container; pub mod scrollable; +pub mod slider; diff --git a/voxygen/src/ui/ice/renderer/style/slider.rs b/voxygen/src/ui/ice/renderer/style/slider.rs new file mode 100644 index 0000000000..6c6da652ac --- /dev/null +++ b/voxygen/src/ui/ice/renderer/style/slider.rs @@ -0,0 +1,32 @@ +use super::super::super::widget::image; +use vek::Rgba; + +#[derive(Clone, Copy)] +pub struct Style { + pub cursor: Cursor, + pub bar: Bar, + pub labels: bool, +} + +impl Default for Style { + fn default() -> Self { + Self { + cursor: Cursor::Color(Rgba::new(0.5, 0.5, 0.5, 1.0)), + bar: Bar::Color(Rgba::new(0.5, 0.5, 0.5, 1.0)), + labels: false, + } + } +} + +#[derive(Clone, Copy)] +pub enum Cursor { + Color(Rgba), + Image(image::Handle, Rgba), +} + +#[derive(Clone, Copy)] +pub enum Bar { + Color(Rgba), + Image(image::Handle, Rgba), +} + diff --git a/voxygen/src/ui/ice/renderer/widget/mod.rs b/voxygen/src/ui/ice/renderer/widget/mod.rs index 6fe01dac05..9cdb7b5e81 100644 --- a/voxygen/src/ui/ice/renderer/widget/mod.rs +++ b/voxygen/src/ui/ice/renderer/widget/mod.rs @@ -7,6 +7,7 @@ mod container; mod image; mod row; mod scrollable; +mod slider; mod space; mod text; mod text_input; diff --git a/voxygen/src/ui/ice/renderer/widget/slider.rs b/voxygen/src/ui/ice/renderer/widget/slider.rs new file mode 100644 index 0000000000..056c60b423 --- /dev/null +++ b/voxygen/src/ui/ice/renderer/widget/slider.rs @@ -0,0 +1,79 @@ +use super::super::{super::Rotation, style, IcedRenderer, Primitive}; +use common::util::srgba_to_linear; +use iced::{slider, mouse, Rectangle, Point}; +use core::ops::RangeInclusive; +use style::slider::{Bar, Cursor, Style}; + +const CURSOR_WIDTH: f32 = 10.0; +const CURSOR_HEIGHT: f32 = 16.0; +const BAR_HEIGHT: f32 = 18.0; + +impl slider::Renderer for IcedRenderer { + type Style = Style; + fn height(&self) -> u32 { 20 } + fn draw( + &mut self, + bounds: Rectangle, + cursor_position: Point, + range: RangeInclusive, + value: f32, + is_dragging: bool, + style: &Self::Style + ) -> Self::Output { + + let bar_bounds = Rectangle { + height: BAR_HEIGHT, + ..bounds + }; + let bar = match style.bar { + Bar::Color(color) => Primitive::Rectangle { + bounds: bar_bounds, + linear_color: srgba_to_linear(color), + }, + Bar::Image(handle, color) => Primitive::Image { + handle: (handle, Rotation::None), + bounds: bar_bounds, + color, + }, + }; + + let (max, min) = range.into_inner(); + let offset = bounds.width as f32 * (max - min ) / (value - min); + let cursor_bounds = Rectangle { + x: bounds.x + offset - CURSOR_WIDTH / 2.0, + y: bounds.y + if is_dragging { 2.0 } else { 0.0 }, + width: CURSOR_WIDTH, + height: CURSOR_HEIGHT, + }; + let cursor = match style.cursor { + Cursor::Color(color) => Primitive::Rectangle { + bounds: cursor_bounds, + linear_color: srgba_to_linear(color), + }, + Cursor::Image(handle, color) => Primitive::Image { + handle: (handle, Rotation::None), + bounds: cursor_bounds, + color, + }, + }; + + let interaction = if is_dragging { + mouse::Interaction::Grabbing + } else if cursor_bounds.contains(cursor_position) { + mouse::Interaction::Grab + } else if bar_bounds.contains(cursor_position) { + mouse::Interaction::Pointer + } else { + mouse::Interaction::Idle + }; + + let primitives = if style.labels { + // TODO text label on left and right ends + vec![bar, cursor] + } else { + // TODO Cursor text label + vec![bar, cursor] + }; + (Primitive::Group{primitives}, interaction) + } +}