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:
204
src/input/dispatch/outcomes.rs
Normal file
204
src/input/dispatch/outcomes.rs
Normal file
@@ -0,0 +1,204 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-only
|
||||
// Copyright (C) 2026 Liberux Labs, S. L. <info@liberux.net>
|
||||
|
||||
use crate::app::App;
|
||||
use crate::event_loop::{ AppData, SurfaceFocus };
|
||||
|
||||
use crate::input::gesture::{ MoveOutcome, ReleaseEvent };
|
||||
|
||||
impl<A: App> AppData<A>
|
||||
{
|
||||
/// Apply the outcome of a motion event. Non-blocking side-effects
|
||||
/// only: push messages, call app callbacks, set redraw flags.
|
||||
pub( crate ) fn apply_move_outcome
|
||||
(
|
||||
&mut self,
|
||||
focus: SurfaceFocus,
|
||||
outcome: MoveOutcome<A::Message>,
|
||||
)
|
||||
{
|
||||
match outcome
|
||||
{
|
||||
MoveOutcome::Idle => {}
|
||||
MoveOutcome::Drag { pos } =>
|
||||
{
|
||||
let ( ox, oy ) = self.surface_offset_for( focus );
|
||||
self.app.on_drag_move( pos.x + ox, pos.y + oy );
|
||||
self.dirty_caches();
|
||||
self.surface_mut( focus ).request_redraw();
|
||||
self.main.request_redraw();
|
||||
for ss in self.overlays.values_mut()
|
||||
{
|
||||
ss.request_redraw();
|
||||
}
|
||||
}
|
||||
MoveOutcome::Slider { msg } =>
|
||||
{
|
||||
if let Some( m ) = msg
|
||||
{
|
||||
self.pending_msgs.push( m );
|
||||
}
|
||||
self.surface_mut( focus ).request_redraw();
|
||||
}
|
||||
MoveOutcome::Scroll =>
|
||||
{
|
||||
self.surface_mut( focus ).request_redraw();
|
||||
}
|
||||
MoveOutcome::Swipe { up, down, horizontal } =>
|
||||
{
|
||||
if let Some( v ) = up { self.app.on_swipe_progress( v ); }
|
||||
if let Some( v ) = down { self.app.on_swipe_down_progress( v ); }
|
||||
if let Some( v ) = horizontal { self.app.on_swipe_horizontal_progress( v ); }
|
||||
// Swipe-progress callbacks mutate app state outside
|
||||
// `update`, so the cached view tree is stale.
|
||||
self.dirty_caches();
|
||||
self.surface_mut( focus ).request_redraw();
|
||||
for ss in self.overlays.values_mut()
|
||||
{
|
||||
ss.request_redraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Apply the ordered list of events from a release. A single
|
||||
/// release can emit more than one event (e.g. horizontal
|
||||
/// fall-through followed by a vertical commit or fall-through), so
|
||||
/// we walk the list and run each event's side-effects in order.
|
||||
pub( crate ) fn apply_release_events
|
||||
(
|
||||
&mut self,
|
||||
focus: SurfaceFocus,
|
||||
events: Vec<ReleaseEvent<A::Message>>,
|
||||
)
|
||||
{
|
||||
for event in events
|
||||
{
|
||||
self.apply_release_event( focus, event );
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_release_event
|
||||
(
|
||||
&mut self,
|
||||
focus: SurfaceFocus,
|
||||
event: ReleaseEvent<A::Message>,
|
||||
)
|
||||
{
|
||||
match event
|
||||
{
|
||||
ReleaseEvent::Drop { pos } =>
|
||||
{
|
||||
let ( ox, oy ) = self.surface_offset_for( focus );
|
||||
if let Some( msg ) = self.app.on_drop( pos.x + ox, pos.y + oy )
|
||||
{
|
||||
self.pending_msgs.push( msg );
|
||||
}
|
||||
self.clear_long_press_drag();
|
||||
self.dirty_caches();
|
||||
self.main.request_redraw();
|
||||
self.main.frame_pending = false;
|
||||
for ss in self.overlays.values_mut()
|
||||
{
|
||||
ss.request_redraw();
|
||||
}
|
||||
}
|
||||
ReleaseEvent::SwipeLeft =>
|
||||
{
|
||||
if let Some( msg ) = self.app.on_swipe_left()
|
||||
{
|
||||
self.pending_msgs.push( msg );
|
||||
}
|
||||
// When the app handles the release internally (settle
|
||||
// animation, state-only mutation) it returns no
|
||||
// Message, so the update-driven redraw never fires.
|
||||
// Kick the main surface here so `is_animating()` has a
|
||||
// frame to latch onto.
|
||||
self.dirty_caches();
|
||||
self.main.request_redraw();
|
||||
self.main.frame_pending = false;
|
||||
}
|
||||
ReleaseEvent::SwipeRight =>
|
||||
{
|
||||
if let Some( msg ) = self.app.on_swipe_right()
|
||||
{
|
||||
self.pending_msgs.push( msg );
|
||||
}
|
||||
self.dirty_caches();
|
||||
self.main.request_redraw();
|
||||
self.main.frame_pending = false;
|
||||
}
|
||||
ReleaseEvent::SwipeUp =>
|
||||
{
|
||||
if let Some( msg ) = self.app.on_swipe_up()
|
||||
{
|
||||
self.pending_msgs.push( msg );
|
||||
}
|
||||
self.dirty_caches();
|
||||
self.main.request_redraw();
|
||||
self.main.frame_pending = false;
|
||||
for ss in self.overlays.values_mut()
|
||||
{
|
||||
ss.request_redraw();
|
||||
ss.frame_pending = false;
|
||||
}
|
||||
}
|
||||
ReleaseEvent::SwipeDown =>
|
||||
{
|
||||
if let Some( msg ) = self.app.on_swipe_down()
|
||||
{
|
||||
self.pending_msgs.push( msg );
|
||||
}
|
||||
self.dirty_caches();
|
||||
self.main.request_redraw();
|
||||
self.main.frame_pending = false;
|
||||
for ss in self.overlays.values_mut()
|
||||
{
|
||||
ss.request_redraw();
|
||||
ss.frame_pending = false;
|
||||
}
|
||||
}
|
||||
ReleaseEvent::HorizontalFellThrough =>
|
||||
{
|
||||
// Below threshold: pulse horizontal 0 so a
|
||||
// vertical-dominant gesture that drifted laterally
|
||||
// does not leave the app stuck on a stale horizontal
|
||||
// progress.
|
||||
self.app.on_swipe_horizontal_progress( 0.0 );
|
||||
self.dirty_caches();
|
||||
self.main.request_redraw();
|
||||
self.main.frame_pending = false;
|
||||
}
|
||||
ReleaseEvent::VerticalFellThrough =>
|
||||
{
|
||||
self.app.on_swipe_progress( 0.0 );
|
||||
self.app.on_swipe_down_progress( 0.0 );
|
||||
self.dirty_caches();
|
||||
}
|
||||
ReleaseEvent::PushMsg( msg ) =>
|
||||
{
|
||||
self.pending_msgs.push( msg );
|
||||
}
|
||||
ReleaseEvent::EmptyRelease =>
|
||||
{
|
||||
match focus
|
||||
{
|
||||
SurfaceFocus::Main =>
|
||||
{
|
||||
if let Some( msg ) = self.app.on_tap()
|
||||
{
|
||||
self.pending_msgs.push( msg );
|
||||
}
|
||||
}
|
||||
SurfaceFocus::Overlay( id ) =>
|
||||
{
|
||||
if let Some( msg ) = self.overlay_dismiss_msg( id )
|
||||
{
|
||||
self.pending_msgs.push( msg );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user