Support viewport-relative widget sizing
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
// Copyright (C) 2026 Liberux Labs, S. L. <info@liberux.net>
|
||||
|
||||
use std::sync::Arc;
|
||||
use crate::types::Rect;
|
||||
use crate::types::{ Length, Rect };
|
||||
use crate::render::Canvas;
|
||||
use super::Element;
|
||||
use super::slider::intersect_clip;
|
||||
@@ -65,10 +65,10 @@ pub struct VSlider<Msg: Clone>
|
||||
/// Current value in `[0.0, 1.0]`. `0.0` paints no fill; `1.0` fills the
|
||||
/// whole pill.
|
||||
pub value: f32,
|
||||
/// Fixed width of the pill in pixels. Defaults to 56.
|
||||
pub width: f32,
|
||||
/// Fixed height of the pill in pixels. Defaults to 160.
|
||||
pub height: f32,
|
||||
/// Fixed width of the pill in logical units. Defaults to 56 px.
|
||||
pub width: Length,
|
||||
/// Fixed height of the pill in logical units. Defaults to 160 px.
|
||||
pub height: Length,
|
||||
/// Callback invoked with the new value when the slider is tapped or
|
||||
/// dragged. `Arc` (not `Box`) so the layout pass can clone it into the
|
||||
/// per-leaf handler snapshot for O(1) dispatch on input events.
|
||||
@@ -93,8 +93,8 @@ impl<Msg: Clone> VSlider<Msg>
|
||||
Self
|
||||
{
|
||||
value: value.clamp( 0.0, 1.0 ),
|
||||
width: theme::WIDTH,
|
||||
height: theme::HEIGHT,
|
||||
width: Length::px( theme::WIDTH ),
|
||||
height: Length::px( theme::HEIGHT ),
|
||||
on_change: None,
|
||||
track_surface: theme::SURFACE_TRACK,
|
||||
fill_surface: theme::SURFACE_FILL,
|
||||
@@ -117,12 +117,13 @@ impl<Msg: Clone> VSlider<Msg>
|
||||
self
|
||||
}
|
||||
|
||||
/// Override the fixed pill `(width, height)` in pixels. Both are clamped
|
||||
/// to a minimum of `2.0` so a rounded pill can always be drawn.
|
||||
pub fn size( mut self, width: f32, height: f32 ) -> Self
|
||||
/// Override the fixed pill `(width, height)` in logical units. Both are
|
||||
/// clamped to a minimum of `2.0` after viewport-relative values resolve,
|
||||
/// so a rounded pill can always be drawn.
|
||||
pub fn size( mut self, width: impl Into<Length>, height: impl Into<Length> ) -> Self
|
||||
{
|
||||
self.width = width.max( 2.0 );
|
||||
self.height = height.max( 2.0 );
|
||||
self.width = width.into();
|
||||
self.height = height.into();
|
||||
self
|
||||
}
|
||||
|
||||
@@ -135,9 +136,13 @@ impl<Msg: Clone> VSlider<Msg>
|
||||
|
||||
/// Return the preferred `(width, height)`. `max_width` is ignored — see
|
||||
/// the type-level docs on intrinsic sizing.
|
||||
pub fn preferred_size( &self, _max_width: f32, _canvas: &Canvas ) -> (f32, f32)
|
||||
pub fn preferred_size( &self, _max_width: f32, canvas: &Canvas ) -> (f32, f32)
|
||||
{
|
||||
( self.width, self.height )
|
||||
let viewport = canvas.viewport_logical();
|
||||
(
|
||||
self.width.resolve( viewport, Length::EM_BASE_DEFAULT ).max( 2.0 ),
|
||||
self.height.resolve( viewport, Length::EM_BASE_DEFAULT ).max( 2.0 ),
|
||||
)
|
||||
}
|
||||
|
||||
/// Compute the value `[0.0, 1.0]` from a tap/drag y position within `rect`.
|
||||
|
||||
@@ -100,8 +100,8 @@ fn preferred_size_ignores_max_width()
|
||||
fn default_dimensions_are_the_theme_constants()
|
||||
{
|
||||
let s: VSlider<()> = vslider( 0.0 );
|
||||
assert_eq!( s.width, theme::WIDTH );
|
||||
assert_eq!( s.height, theme::HEIGHT );
|
||||
assert_eq!( s.width, Length::px( theme::WIDTH ) );
|
||||
assert_eq!( s.height, Length::px( theme::HEIGHT ) );
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
|
||||
Reference in New Issue
Block a user