allow customizing handle size

This commit is contained in:
griffi-gh 2024-03-24 22:27:59 +01:00
parent a7f01b1a72
commit 7ce24185e5
2 changed files with 28 additions and 19 deletions

View file

@ -8,7 +8,6 @@ use hui::{
text::Text, text::Text,
UiElementExt, UiElementExt,
}, },
frame::FrameRect,
layout::{Alignment, Direction}, layout::{Alignment, Direction},
signal::Signal, signal::Signal,
size, size,

View file

@ -53,13 +53,19 @@ pub struct Slider {
#[setters(skip)] #[setters(skip)]
pub handle: Box<dyn Frame>, pub handle: Box<dyn Frame>,
/// Track height relative to the slider height\ /// Track height *relative to the slider height*\
/// ///
/// Range: 0.0..=1.0 /// Range: 0.0..=1.0
pub track_height_ratio: f32, pub track_height: f32,
/// Handle width in pixels /// Handle size
pub handle_width: f32, ///
/// Please be aware that:
///
/// - Width is *static* and specified in *pixels* (e.g. `15.0`)
/// - Height is *relative* to the slider height,\
/// ...and is specified as a *ratio* in range `0.0..=1.0`
pub handle_size: (f32, f32),
/// Follow mode /// Follow mode
pub follow_mode: SliderFollowMode, pub follow_mode: SliderFollowMode,
@ -76,8 +82,8 @@ impl Default for Slider {
handle: Box::new(FrameRect::color((0.0, 0.0, 1.))), handle: Box::new(FrameRect::color((0.0, 0.0, 1.))),
track: Box::new(FrameRect::color((0.5, 0.5, 0.5))), track: Box::new(FrameRect::color((0.5, 0.5, 0.5))),
track_active: Box::new(FrameRect::color((0.0, 0.0, 0.75))), track_active: Box::new(FrameRect::color((0.0, 0.0, 0.75))),
track_height_ratio: 0.25, track_height: 0.25,
handle_width: 15.0, handle_size: (15.0, 1.),
follow_mode: SliderFollowMode::default(), follow_mode: SliderFollowMode::default(),
on_change: None on_change: None
} }
@ -140,18 +146,18 @@ impl UiElement for Slider {
// } else { // } else {
// vec2(15., ctx.measure.size.y) // vec2(15., ctx.measure.size.y)
// }; // };
let handle_size = vec2(self.handle_width, ctx.measure.size.y); let handle_size = vec2(self.handle_size.0, self.handle_size.1 * ctx.measure.size.y);
//Draw the track //Draw the track
//If the active part is opaque and value >= 1., we don't need to draw the background as the active part will cover it //If the active part is opaque and value >= 1., we don't need to draw the background as the active part will cover it
//However, if the handle is not opaque, we need to draw the background as the active part won't quite reach the end //However, if the handle is not opaque, we need to draw the background as the active part won't quite reach the end
//Of corse, if it's fully transparent, we don't need to draw it either //Of corse, if it's fully transparent, we don't need to draw it either
// if !(self.track_color.is_transparent() || (self.track_active_color.is_opaque() && self.handle_color.is_opaque() && self.value >= 1.)) { // if !(self.track_color.is_transparent() || (self.track_active_color.is_opaque() && self.handle_color.is_opaque() && self.value >= 1.)) {
if !(self.track_active.covers_opaque() && self.handle.covers_opaque() && self.value >= 1.) { if !(self.track_active.covers_opaque() && self.handle.covers_opaque() && (self.handle_size.1 >= self.track_height) && self.value >= 1.) {
self.track.draw( self.track.draw(
ctx.draw, ctx.draw,
ctx.layout.position + ctx.measure.size * vec2(0., 0.5 - self.track_height_ratio / 2.), ctx.layout.position + ctx.measure.size * vec2(0., 0.5 - self.track_height / 2.),
ctx.measure.size * vec2(1., self.track_height_ratio), ctx.measure.size * vec2(1., self.track_height),
); );
} }
@ -159,11 +165,11 @@ impl UiElement for Slider {
//We can skip drawing it if it's fully transparent or value <= 0. //We can skip drawing it if it's fully transparent or value <= 0.
//But if the handle is not opaque, it should be visible even if value is zero //But if the handle is not opaque, it should be visible even if value is zero
// if !(self.track_active_color.is_transparent() || (self.value <= 0. && self.handle_color.is_opaque())) { // if !(self.track_active_color.is_transparent() || (self.value <= 0. && self.handle_color.is_opaque())) {
if !(self.handle.covers_opaque() && self.value <= 0.) { if !(self.handle.covers_opaque() && (self.handle_size.1 >= self.track_height) && self.value <= 0.) {
self.track_active.draw( self.track_active.draw(
ctx.draw, ctx.draw,
ctx.layout.position + ctx.measure.size * vec2(0., 0.5 - self.track_height_ratio / 2.), ctx.layout.position + ctx.measure.size * vec2(0., 0.5 - self.track_height / 2.),
(ctx.measure.size - handle_size * Vec2::X) * vec2(self.value, self.track_height_ratio) + handle_size * Vec2::X / 2., (ctx.measure.size - handle_size * Vec2::X) * vec2(self.value, self.track_height) + handle_size * Vec2::X / 2.,
); );
} }
@ -178,11 +184,15 @@ impl UiElement for Slider {
// rounded_corners: None, // rounded_corners: None,
// }); // });
// } // }
self.handle.draw( if (self.handle_size.0 > 0. && self.handle_size.1 > 0.) {
ctx.draw, self.handle.draw(
ctx.layout.position + ((ctx.measure.size.x - handle_size.x) * self.value) * Vec2::X, ctx.draw,
handle_size, ctx.layout.position +
); ((ctx.measure.size.x - handle_size.x) * self.value) * Vec2::X +
ctx.measure.size.y * ((1. - self.handle_size.1) * 0.5) * Vec2::Y,
handle_size,
);
}
//handle events //handle events
if let Some(res) = ctx.input.check_active(ctx.measure.rect(ctx.layout.position)) { if let Some(res) = ctx.input.check_active(ctx.measure.rect(ctx.layout.position)) {