refactor: split every monolithic module into focused submodules
Each source file that had grown beyond a single concern is replaced by an identically-named directory containing focused submodules. `src/event_loop/mod.rs` (878 lines) becomes a directory with clipboard, context_menu, cursor_shape, drag, focus, handlers, invalidation, overlays_reconcile, repeat, run, surface, text_editing, and tooltip. Every widget, input handler, and theme component follows the same split. Public interfaces are unchanged — only the internal file layout moves. image bumped from 0.25.2 to 0.25.9.
This commit is contained in:
116
src/widget/progress_bar/mod.rs
Normal file
116
src/widget/progress_bar/mod.rs
Normal file
@@ -0,0 +1,116 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-only
|
||||
// Copyright (C) 2026 Liberux Labs, S. L. <info@liberux.net>
|
||||
|
||||
use crate::types::{ Color, Rect };
|
||||
use crate::render::Canvas;
|
||||
use super::Element;
|
||||
|
||||
mod theme;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
/// A linear progress indicator for determinate operations.
|
||||
///
|
||||
/// Renders a horizontal track with a coloured fill from the left edge to
|
||||
/// `value × width`. `value` is clamped to `[0.0, 1.0]` at construction.
|
||||
/// For indeterminate progress (the operation has no ETA) prefer an
|
||||
/// animated spinner — `ltk` has no built-in spinner widget yet; build one
|
||||
/// from a [`Container`](super::container::Container) that rotates a glyph
|
||||
/// while [`crate::App::is_animating`] returns `true`.
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # use ltk::{ column, progress_bar, text, Element };
|
||||
/// # #[ derive( Clone ) ] enum Msg {}
|
||||
/// # struct App { progress: f32 }
|
||||
/// # impl App { fn _ex( &self ) -> Element<Msg> {
|
||||
/// // In view():
|
||||
/// column()
|
||||
/// .push( text( format!( "Downloading… {}%", ( self.progress * 100.0 ) as u32 ) ) )
|
||||
/// .push( progress_bar( self.progress ) )
|
||||
/// .into()
|
||||
/// # }}
|
||||
/// ```
|
||||
pub struct ProgressBar
|
||||
{
|
||||
/// Current progress in `[0.0, 1.0]`. Always clamped at construction.
|
||||
pub value: f32,
|
||||
/// Fill colour. Defaults to the theme's `accent` palette slot.
|
||||
pub fill: Color,
|
||||
}
|
||||
|
||||
impl ProgressBar
|
||||
{
|
||||
/// Create a progress bar at the given fraction. `value` outside
|
||||
/// `[0.0, 1.0]` is clamped silently.
|
||||
pub fn new( value: f32 ) -> Self
|
||||
{
|
||||
Self { value: value.clamp( 0.0, 1.0 ), fill: theme::fill() }
|
||||
}
|
||||
|
||||
/// Override the fill colour. Useful for "danger" / "success" variants
|
||||
/// (red for nearly-full disks, green for completed work).
|
||||
pub fn color( mut self, color: Color ) -> Self
|
||||
{
|
||||
self.fill = color;
|
||||
self
|
||||
}
|
||||
|
||||
/// Return the preferred `(width, height)`. Width fills the available
|
||||
/// `max_width`; height is the theme-defined row height.
|
||||
pub fn preferred_size( &self, max_width: f32 ) -> (f32, f32)
|
||||
{
|
||||
( max_width, theme::HEIGHT )
|
||||
}
|
||||
|
||||
pub fn draw( &self, canvas: &mut Canvas, rect: Rect )
|
||||
{
|
||||
let track_y = rect.y + ( rect.height - theme::TRACK_H ) / 2.0;
|
||||
let track_r = theme::TRACK_H / 2.0;
|
||||
|
||||
let track_rect = Rect
|
||||
{
|
||||
x: rect.x,
|
||||
y: track_y,
|
||||
width: rect.width,
|
||||
height: theme::TRACK_H,
|
||||
};
|
||||
canvas.fill_rect( track_rect, theme::track_bg(), track_r );
|
||||
|
||||
let fill_w = rect.width * self.value;
|
||||
if fill_w > 0.0
|
||||
{
|
||||
let fill_rect = Rect
|
||||
{
|
||||
x: rect.x,
|
||||
y: track_y,
|
||||
width: fill_w,
|
||||
height: theme::TRACK_H,
|
||||
};
|
||||
canvas.fill_rect( fill_rect, self.fill, track_r );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a [`ProgressBar`] at the given fraction (clamped to
|
||||
/// `[0.0, 1.0]`).
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # use ltk::{ progress_bar, ProgressBar };
|
||||
/// # struct App { download_fraction: f32 }
|
||||
/// # impl App { fn _ex( &self ) -> ProgressBar {
|
||||
/// progress_bar( self.download_fraction )
|
||||
/// # }}
|
||||
/// ```
|
||||
pub fn progress_bar( value: f32 ) -> ProgressBar
|
||||
{
|
||||
ProgressBar::new( value )
|
||||
}
|
||||
|
||||
impl<Msg: Clone> From<ProgressBar> for Element<Msg>
|
||||
{
|
||||
fn from( p: ProgressBar ) -> Self
|
||||
{
|
||||
Element::ProgressBar( p )
|
||||
}
|
||||
}
|
||||
21
src/widget/progress_bar/tests.rs
Normal file
21
src/widget/progress_bar/tests.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-only
|
||||
// Copyright (C) 2026 Liberux Labs, S. L. <info@liberux.net>
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn value_clamped_on_creation()
|
||||
{
|
||||
let p = progress_bar( 1.5 );
|
||||
assert_eq!( p.value, 1.0 );
|
||||
let p = progress_bar( -0.5 );
|
||||
assert_eq!( p.value, 0.0 );
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preferred_width_fills_available()
|
||||
{
|
||||
let p = progress_bar( 0.5 );
|
||||
let ( w, _ ) = p.preferred_size( 300.0 );
|
||||
assert_eq!( w, 300.0 );
|
||||
}
|
||||
8
src/widget/progress_bar/theme.rs
Normal file
8
src/widget/progress_bar/theme.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-only
|
||||
// Copyright (C) 2026 Liberux Labs, S. L. <info@liberux.net>
|
||||
|
||||
use crate::types::Color;
|
||||
pub fn track_bg() -> Color { crate::theme::palette().divider }
|
||||
pub fn fill() -> Color { crate::theme::palette().accent }
|
||||
pub const TRACK_H: f32 = 6.0;
|
||||
pub const HEIGHT: f32 = 20.0;
|
||||
Reference in New Issue
Block a user