From fb23445e1d86337c0434231e4221e1cf43ce5c48 Mon Sep 17 00:00:00 2001 From: Alexandre Bury Date: Mon, 26 Oct 2020 12:30:00 -0700 Subject: [PATCH] Add Cursive::screen_size based on last layout phase --- cursive-core/src/cursive.rs | 15 ++++++++++++++- cursive-core/src/cursive_run.rs | 2 ++ cursive-core/src/view/scroll/core.rs | 1 + cursive-core/src/view/scroll/raw.rs | 16 +++++----------- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/cursive-core/src/cursive.rs b/cursive-core/src/cursive.rs index 752881f..7f56aed 100644 --- a/cursive-core/src/cursive.rs +++ b/cursive-core/src/cursive.rs @@ -19,6 +19,8 @@ use crate::{ static DEBUG_VIEW_NAME: &str = "_cursive_debug_view"; +type RootView = views::OnEventView>; + /// Central part of the cursive library. /// /// It initializes ncurses on creation and cleans up on drop. @@ -30,7 +32,7 @@ pub struct Cursive { theme: theme::Theme, // The main view - root: views::OnEventView>, + root: RootView, menubar: views::Menubar, @@ -42,6 +44,8 @@ pub struct Cursive { cb_source: Receiver>, cb_sink: Sender>, + last_size: Vec2, + // User-provided data. user_data: Box, @@ -84,6 +88,7 @@ impl Cursive { views::StackView::new(), )), menubar: views::Menubar::new(), + last_size: Vec2::zero(), needs_clear: true, running: true, cb_source, @@ -96,7 +101,15 @@ impl Cursive { cursive } + /// Returns the screen size given in the last layout phase. + /// + /// Note: this will return `(0, 0)` before the first layout phase. + pub fn screen_size(&self) -> Vec2 { + self.last_size + } + pub(crate) fn layout(&mut self, size: Vec2) { + self.last_size = size; let offset = if self.menubar.autohide { 0 } else { 1 }; let size = size.saturating_sub((0, offset)); self.root.layout(size); diff --git a/cursive-core/src/cursive_run.rs b/cursive-core/src/cursive_run.rs index 9093f1c..e1c88c9 100644 --- a/cursive-core/src/cursive_run.rs +++ b/cursive-core/src/cursive_run.rs @@ -9,6 +9,8 @@ const INPUT_POLL_DELAY_MS: u64 = 30; /// /// You can get one from `Cursive::runner`, then either call `.run()`, or /// manually `.step()`. +/// +/// The `C` type is usually either `Cursive` or `&mut Cursive`. pub struct CursiveRunner { siv: C, backend: Box, diff --git a/cursive-core/src/view/scroll/core.rs b/cursive-core/src/view/scroll/core.rs index c5944b8..738e0fb 100644 --- a/cursive-core/src/view/scroll/core.rs +++ b/cursive-core/src/view/scroll/core.rs @@ -305,6 +305,7 @@ impl Core { && (self.offset.y + self.available_size().y < self.inner_size.y) => { + // No `min` check here - we allow going over the edge. self.offset.y += 5; } Event::Ctrl(Key::Down) | Event::Key(Key::Down) diff --git a/cursive-core/src/view/scroll/raw.rs b/cursive-core/src/view/scroll/raw.rs index c8c18b7..be498a9 100644 --- a/cursive-core/src/view/scroll/raw.rs +++ b/cursive-core/src/view/scroll/raw.rs @@ -210,19 +210,13 @@ where } /// Implements `View::on_event` on the given model. -pub fn on_event( +pub fn on_event( event: Event, model: &mut Model, - mut get_scroller: GetScroller, - mut on_event: OnEvent, - mut important_area: ImportantArea, -) -> EventResult -where - Model: ?Sized, - GetScroller: FnMut(&mut Model) -> &mut scroll::Core, - OnEvent: FnMut(&mut Model, Event) -> EventResult, - ImportantArea: FnMut(&Model, Vec2) -> Rect, -{ + mut get_scroller: impl FnMut(&mut Model) -> &mut scroll::Core, + mut on_event: impl FnMut(&mut Model, Event) -> EventResult, + mut important_area: impl FnMut(&Model, Vec2) -> Rect, +) -> EventResult { let mut relative_event = event.clone(); let inside = get_scroller(model).is_event_inside(&mut relative_event); let result = if inside {