Introduce left and right colors for slider rails

This commit is contained in:
Night_Hunter 2023-01-06 14:55:09 +13:00 committed by Héctor Ramón Jiménez
parent ce8e92ca7a
commit de51bc3f41
No known key found for this signature in database
GPG key ID: 140CC052C94F138E
4 changed files with 130 additions and 80 deletions

View file

@ -8,13 +8,15 @@ use crate::renderer;
use crate::touch; use crate::touch;
use crate::widget::tree::{self, Tree}; use crate::widget::tree::{self, Tree};
use crate::{ use crate::{
Background, Clipboard, Color, Element, Layout, Length, Pixels, Point, Clipboard, Element, Layout, Length, Pixels, Point, Rectangle, Shell, Size,
Rectangle, Shell, Size, Widget, Widget,
}; };
use std::ops::RangeInclusive; use std::ops::RangeInclusive;
pub use iced_style::slider::{Appearance, Handle, HandleShape, StyleSheet}; pub use iced_style::slider::{
Appearance, Handle, HandleShape, Rail, StyleSheet,
};
/// An horizontal bar and a handle that selects a single value from a range of /// An horizontal bar and a handle that selects a single value from a range of
/// values. /// values.
@ -368,37 +370,7 @@ pub fn draw<T, R>(
style_sheet.active(style) style_sheet.active(style)
}; };
let rail_y = bounds.y + (bounds.height / 2.0).round(); let value = value.into() as f32;
renderer.fill_quad(
renderer::Quad {
bounds: Rectangle {
x: bounds.x,
y: rail_y - 1.0,
width: bounds.width,
height: 2.0,
},
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
},
style.rail_colors.0,
);
renderer.fill_quad(
renderer::Quad {
bounds: Rectangle {
x: bounds.x,
y: rail_y + 1.0,
width: bounds.width,
height: 2.0,
},
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
},
Background::Color(style.rail_colors.1),
);
let (handle_width, handle_height, handle_border_radius) = match style let (handle_width, handle_height, handle_border_radius) = match style
.handle .handle
@ -411,25 +383,69 @@ pub fn draw<T, R>(
} => (f32::from(width), bounds.height, border_radius), } => (f32::from(width), bounds.height, border_radius),
}; };
let value = value.into() as f32;
let (range_start, range_end) = { let (range_start, range_end) = {
let (start, end) = range.clone().into_inner(); let (start, end) = range.clone().into_inner();
(start.into() as f32, end.into() as f32) (start.into() as f32, end.into() as f32)
}; };
let handle_offset = if range_start >= range_end { let offset = if range_start >= range_end {
0.0 0.0
} else { } else {
(bounds.width - handle_width) * (value - range_start) (bounds.width - handle_width) * (value - range_start)
/ (range_end - range_start) / (range_end - range_start)
}; };
let line_y = bounds.y + bounds.height / 2.0 - style.rail.size / 2.0;
let line_offset = offset + handle_width / 2.0;
renderer.fill_quad( renderer.fill_quad(
renderer::Quad { renderer::Quad {
bounds: Rectangle { bounds: Rectangle {
x: bounds.x + handle_offset.round(), x: bounds.x,
y: rail_y - handle_height / 2.0, y: line_y,
width: line_offset,
height: style.rail.size,
},
border_radius: [
style.rail.border_radius,
0.0,
0.0,
style.rail.border_radius,
]
.into(),
border_width: style.rail.border_width,
border_color: style.rail.border_color,
},
style.rail.colors.0,
);
renderer.fill_quad(
renderer::Quad {
bounds: Rectangle {
x: bounds.x + line_offset.round(),
y: line_y,
width: bounds.width - line_offset,
height: style.rail.size,
},
border_radius: [
0.0,
style.rail.border_radius,
style.rail.border_radius,
0.0,
]
.into(),
border_width: style.rail.border_width,
border_color: style.rail.border_color,
},
style.rail.colors.1,
);
renderer.fill_quad(
renderer::Quad {
bounds: Rectangle {
x: bounds.x + offset.round(),
y: bounds.y + bounds.height / 2.0 - handle_height / 2.0,
width: handle_width, width: handle_width,
height: handle_height, height: handle_height,
}, },

View file

@ -8,8 +8,8 @@ pub use iced_style::slider::{Appearance, Handle, HandleShape, StyleSheet};
use crate::event::{self, Event}; use crate::event::{self, Event};
use crate::widget::tree::{self, Tree}; use crate::widget::tree::{self, Tree};
use crate::{ use crate::{
layout, mouse, renderer, touch, Background, Clipboard, Color, Element, layout, mouse, renderer, touch, Clipboard, Element, Layout, Length, Pixels,
Layout, Length, Pixels, Point, Rectangle, Shell, Size, Widget, Point, Rectangle, Shell, Size, Widget,
}; };
/// An vertical bar and a handle that selects a single value from a range of /// An vertical bar and a handle that selects a single value from a range of
@ -363,38 +363,6 @@ pub fn draw<T, R>(
style_sheet.active(style) style_sheet.active(style)
}; };
let rail_x = bounds.x + (bounds.width / 2.0).round();
renderer.fill_quad(
renderer::Quad {
bounds: Rectangle {
x: rail_x - 1.0,
y: bounds.y,
width: 2.0,
height: bounds.height,
},
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
},
style.rail_colors.0,
);
renderer.fill_quad(
renderer::Quad {
bounds: Rectangle {
x: rail_x + 1.0,
y: bounds.y,
width: 2.0,
height: bounds.height,
},
border_radius: 0.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
},
Background::Color(style.rail_colors.1),
);
let (handle_width, handle_height, handle_border_radius) = match style let (handle_width, handle_height, handle_border_radius) = match style
.handle .handle
.shape .shape
@ -413,18 +381,63 @@ pub fn draw<T, R>(
(start.into() as f32, end.into() as f32) (start.into() as f32, end.into() as f32)
}; };
let handle_offset = if range_start >= range_end { let offset = if range_start >= range_end {
0.0 0.0
} else { } else {
(bounds.height - handle_width) * (value - range_end) (bounds.height - handle_width) * (value - range_end)
/ (range_start - range_end) / (range_start - range_end)
}; };
let line_x = bounds.x + bounds.width / 2.0 - style.rail.size / 2.0;
let line_offset = offset + handle_width / 2.0;
renderer.fill_quad( renderer.fill_quad(
renderer::Quad { renderer::Quad {
bounds: Rectangle { bounds: Rectangle {
x: rail_x - (handle_height / 2.0), x: line_x,
y: bounds.y + handle_offset.round(), y: bounds.y,
width: style.rail.size,
height: line_offset,
},
border_radius: [
style.rail.border_radius,
style.rail.border_radius,
0.0,
0.0,
]
.into(),
border_width: style.rail.border_width,
border_color: style.rail.border_color,
},
style.rail.colors.1,
);
renderer.fill_quad(
renderer::Quad {
bounds: Rectangle {
x: line_x,
y: bounds.y + line_offset.round(),
width: style.rail.size,
height: bounds.height - line_offset,
},
border_radius: [
0.0,
0.0,
style.rail.border_radius,
style.rail.border_radius,
]
.into(),
border_width: style.rail.border_width,
border_color: style.rail.border_color,
},
style.rail.colors.0,
);
renderer.fill_quad(
renderer::Quad {
bounds: Rectangle {
x: bounds.x + bounds.width / 2.0 - handle_height / 2.0,
y: bounds.y + offset.round(),
width: handle_height, width: handle_height,
height: handle_width, height: handle_width,
}, },

View file

@ -5,11 +5,26 @@ use iced_core::Color;
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Appearance { pub struct Appearance {
/// The colors of the rail of the slider. /// The colors of the rail of the slider.
pub rail_colors: (Color, Color), pub rail: Rail,
/// The appearance of the [`Handle`] of the slider. /// The appearance of the [`Handle`] of the slider.
pub handle: Handle, pub handle: Handle,
} }
/// The appearance of a slider rail
#[derive(Debug, Clone, Copy)]
pub struct Rail {
/// The colors of the rail of the slider.
pub colors: (Color, Color),
/// The height of a slider rail and the width of a vertical slider.
pub size: f32,
/// The border radius of the slider.
pub border_radius: f32,
/// The border width of the slider.
pub border_width: f32,
/// The border [`Color`] of the slider.
pub border_color: Color,
}
/// The appearance of the handle of a slider. /// The appearance of the handle of a slider.
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Handle { pub struct Handle {

View file

@ -416,10 +416,16 @@ impl slider::StyleSheet for Theme {
}; };
slider::Appearance { slider::Appearance {
rail_colors: ( rail: slider::Rail {
palette.primary.base.color, colors: (
Color::TRANSPARENT, palette.primary.base.color,
), palette.primary.base.color,
),
size: 2.0,
border_radius: 0.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
},
handle: slider::Handle { handle: slider::Handle {
color: palette.background.base.color, color: palette.background.base.color,
border_color: palette.primary.base.color, border_color: palette.primary.base.color,