toggle, widget: scale the pill with an explicit row height, and give elide a half-pixel tolerance
Toggle::height used to adjust only the row: the resolved value was floored at the theme track height and the pill kept its theme size, so a toggle capped below the fluid row height still rendered a full-size pill — on large surfaces, visibly out of scale next to controls that honour their cap. The floor is gone; when the resolved height falls below the theme row height, track and thumb now scale down proportionally (never up — the factor is capped at 1), and preferred_size reports the scaled track width so layout, focus ring and centring stay consistent. A toggle without an explicit height is untouched. elide compared measure( text ) <= max_w strictly, which breaks when the caller sized itself from the same measurement: a button reports text + 2×pad as its preferred width, the layout grants exactly that, and draw hands elide back rect.width − 2×pad. In f32 the add-then-subtract round-trip can land a few ULP under the original measurement, the strict comparison fails, and the truncation branch then costs the full width of the ellipsis — a sub-pixel deficit turned "Empezar" into "Empez...". The fit check now allows half a pixel of slack, which absorbs any mismatch of this class while leaving genuine overflows to truncate as before.
This commit is contained in:
@@ -128,7 +128,10 @@ pub( crate ) fn elide(
|
|||||||
{
|
{
|
||||||
return String::new();
|
return String::new();
|
||||||
}
|
}
|
||||||
if canvas.measure_text( text, size ) <= max_w
|
// Half-pixel slack: a parent that sized itself from this same
|
||||||
|
// measurement can hand back a width a few ULP short after its
|
||||||
|
// padding add-then-subtract round-trip.
|
||||||
|
if canvas.measure_text( text, size ) <= max_w + 0.5
|
||||||
{
|
{
|
||||||
return text.to_string();
|
return text.to_string();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,9 +89,10 @@ impl<Msg: Clone> Toggle<Msg>
|
|||||||
|
|
||||||
/// Override the preferred height (default: the theme row height,
|
/// Override the preferred height (default: the theme row height,
|
||||||
/// `theme::HEIGHT` design px). Accepts any [`Length`] so dense
|
/// `theme::HEIGHT` design px). Accepts any [`Length`] so dense
|
||||||
/// layouts can tie the row height to the viewport. The resolved
|
/// layouts can tie the row height to the viewport. When the resolved
|
||||||
/// value is floored at the track height so the pill never clips;
|
/// value falls below the theme row height, the pill (track and thumb)
|
||||||
/// the track keeps its theme size and stays vertically centred.
|
/// scales down proportionally so it never clips; it never grows
|
||||||
|
/// beyond its theme size.
|
||||||
pub fn height( mut self, h: impl Into<Length> ) -> Self
|
pub fn height( mut self, h: impl Into<Length> ) -> Self
|
||||||
{
|
{
|
||||||
self.height = Some( h.into() );
|
self.height = Some( h.into() );
|
||||||
@@ -105,7 +106,13 @@ impl<Msg: Clone> Toggle<Msg>
|
|||||||
/// label is set. Height is the theme-defined row height.
|
/// label is set. Height is the theme-defined row height.
|
||||||
pub fn preferred_size( &self, max_width: f32, canvas: &Canvas ) -> (f32, f32)
|
pub fn preferred_size( &self, max_width: f32, canvas: &Canvas ) -> (f32, f32)
|
||||||
{
|
{
|
||||||
let track_w = canvas.geom_px( theme::TRACK_W );
|
let h = match self.height
|
||||||
|
{
|
||||||
|
Some( l ) => canvas.resolve_geom( l ),
|
||||||
|
None => canvas.geom_px( theme::HEIGHT ),
|
||||||
|
};
|
||||||
|
let scale = ( h / canvas.geom_px( theme::HEIGHT ) ).min( 1.0 );
|
||||||
|
let track_w = canvas.geom_px( theme::TRACK_W ) * scale;
|
||||||
let w = if let Some( ref label ) = self.label
|
let w = if let Some( ref label ) = self.label
|
||||||
{
|
{
|
||||||
let text_w = canvas.measure_text( label, canvas.font_px( theme::FONT_SIZE ) );
|
let text_w = canvas.measure_text( label, canvas.font_px( theme::FONT_SIZE ) );
|
||||||
@@ -113,11 +120,6 @@ impl<Msg: Clone> Toggle<Msg>
|
|||||||
} else {
|
} else {
|
||||||
track_w.min( max_width )
|
track_w.min( max_width )
|
||||||
};
|
};
|
||||||
let h = match self.height
|
|
||||||
{
|
|
||||||
Some( l ) => canvas.resolve_geom( l ).max( canvas.geom_px( theme::TRACK_H ) ),
|
|
||||||
None => canvas.geom_px( theme::HEIGHT ),
|
|
||||||
};
|
|
||||||
( w, h )
|
( w, h )
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,9 +135,10 @@ impl<Msg: Clone> Toggle<Msg>
|
|||||||
|
|
||||||
pub fn draw( &self, canvas: &mut Canvas, rect: Rect, focused: bool )
|
pub fn draw( &self, canvas: &mut Canvas, rect: Rect, focused: bool )
|
||||||
{
|
{
|
||||||
let track_w = canvas.geom_px( theme::TRACK_W );
|
let scale = ( rect.height / canvas.geom_px( theme::HEIGHT ) ).min( 1.0 );
|
||||||
let track_h = canvas.geom_px( theme::TRACK_H );
|
let track_w = canvas.geom_px( theme::TRACK_W ) * scale;
|
||||||
let thumb_size = canvas.geom_px( theme::THUMB_SIZE );
|
let track_h = canvas.geom_px( theme::TRACK_H ) * scale;
|
||||||
|
let thumb_size = canvas.geom_px( theme::THUMB_SIZE ) * scale;
|
||||||
|
|
||||||
let track_x = if let Some( ref label ) = self.label
|
let track_x = if let Some( ref label ) = self.label
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user