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:
109
src/widget/viewport/mod.rs
Normal file
109
src/widget/viewport/mod.rs
Normal file
@@ -0,0 +1,109 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-only
|
||||
// Copyright (C) 2026 Liberux Labs, S. L. <info@liberux.net>
|
||||
|
||||
use crate::render::Canvas;
|
||||
use crate::widget::Element;
|
||||
|
||||
/// A non-scrollable clipped viewport for revealing only part of a child tree.
|
||||
///
|
||||
/// Unlike `Scroll`, this widget does not own
|
||||
/// any gesture state. It simply renders its child into an off-screen canvas
|
||||
/// and blits the result into the allocated rect, clipping anything outside.
|
||||
pub struct Viewport<Msg: Clone>
|
||||
{
|
||||
/// The child element to render inside the viewport.
|
||||
pub child: Box<Element<Msg>>,
|
||||
/// Optional fixed width in logical pixels. When omitted the
|
||||
/// viewport reports `max_width` as its preferred width — i.e. it
|
||||
/// stretches to fill whatever horizontal slice the parent layout
|
||||
/// gives it. Set explicitly when the viewport has to coexist with
|
||||
/// `flex` siblings (the flex would otherwise lose every pixel to
|
||||
/// the viewport's `max_width` claim) or whenever the inner content
|
||||
/// has its own intrinsic width and the viewport is just a vertical
|
||||
/// clip.
|
||||
pub width: Option<f32>,
|
||||
/// Optional fixed height in logical pixels. When omitted the viewport
|
||||
/// reports the child's natural height.
|
||||
pub height: Option<f32>,
|
||||
/// Logical pixels at the bottom edge that fade to transparent during the
|
||||
/// blit. Zero leaves the bottom hard-edged. Useful for slide-in panels so
|
||||
/// the leading edge of the animation does not knife-cut against the layer
|
||||
/// below it.
|
||||
pub fade_bottom: f32,
|
||||
}
|
||||
|
||||
impl<Msg: Clone> Viewport<Msg>
|
||||
{
|
||||
pub fn new( child: impl Into<Element<Msg>> ) -> Self
|
||||
{
|
||||
Self { child: Box::new( child.into() ), width: None, height: None, fade_bottom: 0.0 }
|
||||
}
|
||||
|
||||
/// Set a fixed viewport width in logical pixels. Mirrors
|
||||
/// [`Self::height`]: with an explicit value the viewport
|
||||
/// reports `w` as its preferred width and the child is laid
|
||||
/// out against `w` rather than the parent-supplied `max_width`.
|
||||
pub fn width( mut self, w: f32 ) -> Self
|
||||
{
|
||||
self.width = Some( w.max( 0.0 ) );
|
||||
self
|
||||
}
|
||||
|
||||
/// Set a fixed viewport height in logical pixels.
|
||||
pub fn height( mut self, h: f32 ) -> Self
|
||||
{
|
||||
self.height = Some( h.max( 0.0 ) );
|
||||
self
|
||||
}
|
||||
|
||||
/// Feather the bottom `px` rows of the viewport so its lower edge dissolves
|
||||
/// to transparent. Drawn by the GLES blit shader as a linear alpha ramp
|
||||
/// over the bottom band; the software backend currently renders a hard
|
||||
/// edge regardless.
|
||||
pub fn fade_bottom( mut self, px: f32 ) -> Self
|
||||
{
|
||||
self.fade_bottom = px.max( 0.0 );
|
||||
self
|
||||
}
|
||||
|
||||
pub fn preferred_size( &self, max_width: f32, canvas: &Canvas ) -> ( f32, f32 )
|
||||
{
|
||||
let inner_w = self.width.unwrap_or( max_width );
|
||||
let child_h = self.child.preferred_size( inner_w, canvas ).1;
|
||||
( self.width.unwrap_or( max_width ), self.height.unwrap_or( child_h ) )
|
||||
}
|
||||
|
||||
/// No-op — rendering is handled by `layout_and_draw` in `draw.rs`.
|
||||
pub fn draw( &self ) {}
|
||||
|
||||
pub( crate ) fn map_msg<U>( self, f: &super::MapFn<Msg, U> ) -> Viewport<U>
|
||||
where
|
||||
U: Clone + 'static,
|
||||
Msg: 'static,
|
||||
{
|
||||
Viewport
|
||||
{
|
||||
child: Box::new( self.child.map_arc( f ) ),
|
||||
width: self.width,
|
||||
height: self.height,
|
||||
fade_bottom: self.fade_bottom,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Msg: Clone + 'static> From<Viewport<Msg>> for Element<Msg>
|
||||
{
|
||||
fn from( v: Viewport<Msg> ) -> Self
|
||||
{
|
||||
Element::Viewport( v )
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a clipped viewport wrapping `child`.
|
||||
pub fn viewport<Msg: Clone>( child: impl Into<Element<Msg>> ) -> Viewport<Msg>
|
||||
{
|
||||
Viewport::new( child )
|
||||
}
|
||||
|
||||
#[ cfg( test ) ]
|
||||
mod tests;
|
||||
Reference in New Issue
Block a user