Add Cursive::screen_size based on last layout phase

This commit is contained in:
Alexandre Bury 2020-10-26 12:30:00 -07:00
parent 58bbae5ec8
commit fb23445e1d
4 changed files with 22 additions and 12 deletions

View File

@ -19,6 +19,8 @@ use crate::{
static DEBUG_VIEW_NAME: &str = "_cursive_debug_view"; static DEBUG_VIEW_NAME: &str = "_cursive_debug_view";
type RootView = views::OnEventView<views::ScreensView<views::StackView>>;
/// Central part of the cursive library. /// Central part of the cursive library.
/// ///
/// It initializes ncurses on creation and cleans up on drop. /// It initializes ncurses on creation and cleans up on drop.
@ -30,7 +32,7 @@ pub struct Cursive {
theme: theme::Theme, theme: theme::Theme,
// The main view // The main view
root: views::OnEventView<views::ScreensView<views::StackView>>, root: RootView,
menubar: views::Menubar, menubar: views::Menubar,
@ -42,6 +44,8 @@ pub struct Cursive {
cb_source: Receiver<Box<dyn FnOnce(&mut Cursive) + Send>>, cb_source: Receiver<Box<dyn FnOnce(&mut Cursive) + Send>>,
cb_sink: Sender<Box<dyn FnOnce(&mut Cursive) + Send>>, cb_sink: Sender<Box<dyn FnOnce(&mut Cursive) + Send>>,
last_size: Vec2,
// User-provided data. // User-provided data.
user_data: Box<dyn Any>, user_data: Box<dyn Any>,
@ -84,6 +88,7 @@ impl Cursive {
views::StackView::new(), views::StackView::new(),
)), )),
menubar: views::Menubar::new(), menubar: views::Menubar::new(),
last_size: Vec2::zero(),
needs_clear: true, needs_clear: true,
running: true, running: true,
cb_source, cb_source,
@ -96,7 +101,15 @@ impl Cursive {
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) { pub(crate) fn layout(&mut self, size: Vec2) {
self.last_size = size;
let offset = if self.menubar.autohide { 0 } else { 1 }; let offset = if self.menubar.autohide { 0 } else { 1 };
let size = size.saturating_sub((0, offset)); let size = size.saturating_sub((0, offset));
self.root.layout(size); self.root.layout(size);

View File

@ -9,6 +9,8 @@ const INPUT_POLL_DELAY_MS: u64 = 30;
/// ///
/// You can get one from `Cursive::runner`, then either call `.run()`, or /// You can get one from `Cursive::runner`, then either call `.run()`, or
/// manually `.step()`. /// manually `.step()`.
///
/// The `C` type is usually either `Cursive` or `&mut Cursive`.
pub struct CursiveRunner<C> { pub struct CursiveRunner<C> {
siv: C, siv: C,
backend: Box<dyn backend::Backend>, backend: Box<dyn backend::Backend>,

View File

@ -305,6 +305,7 @@ impl Core {
&& (self.offset.y + self.available_size().y && (self.offset.y + self.available_size().y
< self.inner_size.y) => < self.inner_size.y) =>
{ {
// No `min` check here - we allow going over the edge.
self.offset.y += 5; self.offset.y += 5;
} }
Event::Ctrl(Key::Down) | Event::Key(Key::Down) Event::Ctrl(Key::Down) | Event::Key(Key::Down)

View File

@ -210,19 +210,13 @@ where
} }
/// Implements `View::on_event` on the given model. /// Implements `View::on_event` on the given model.
pub fn on_event<Model, GetScroller, OnEvent, ImportantArea>( pub fn on_event<Model: ?Sized>(
event: Event, event: Event,
model: &mut Model, model: &mut Model,
mut get_scroller: GetScroller, mut get_scroller: impl FnMut(&mut Model) -> &mut scroll::Core,
mut on_event: OnEvent, mut on_event: impl FnMut(&mut Model, Event) -> EventResult,
mut important_area: ImportantArea, mut important_area: impl FnMut(&Model, Vec2) -> Rect,
) -> EventResult ) -> EventResult {
where
Model: ?Sized,
GetScroller: FnMut(&mut Model) -> &mut scroll::Core,
OnEvent: FnMut(&mut Model, Event) -> EventResult,
ImportantArea: FnMut(&Model, Vec2) -> Rect,
{
let mut relative_event = event.clone(); let mut relative_event = event.clone();
let inside = get_scroller(model).is_event_inside(&mut relative_event); let inside = get_scroller(model).is_event_inside(&mut relative_event);
let result = if inside { let result = if inside {