mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Fix bad initial focus
This commit is contained in:
parent
81e64da72a
commit
f2b1fac679
@ -7,11 +7,28 @@ use crate::{Printer, Vec2, View, With};
|
|||||||
/// Arranges its children in a fixed layout.
|
/// Arranges its children in a fixed layout.
|
||||||
///
|
///
|
||||||
/// Usually meant to use an external layout engine.
|
/// Usually meant to use an external layout engine.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use cursive_core::{
|
||||||
|
/// views::{FixedLayout, TextView, Button},
|
||||||
|
/// Rect,
|
||||||
|
/// };
|
||||||
|
///
|
||||||
|
/// let layout = FixedLayout::new()
|
||||||
|
/// .child(Rect::from_size((0,0), (1,1)), TextView::new("/"))
|
||||||
|
/// .child(Rect::from_size((14,0), (1,1)), TextView::new(r"\"))
|
||||||
|
/// .child(Rect::from_size((0,2), (1,1)), TextView::new(r"\"))
|
||||||
|
/// .child(Rect::from_size((14,2), (1,1)), TextView::new("/"))
|
||||||
|
/// .child(Rect::from_size((3,1), (11,1)), Button::new("Clickme", |s| s.quit()));
|
||||||
|
/// ````
|
||||||
pub struct FixedLayout {
|
pub struct FixedLayout {
|
||||||
children: Vec<Child>,
|
children: Vec<Child>,
|
||||||
focus: usize,
|
focus: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents a child view inside the FixedLayout.
|
||||||
struct Child {
|
struct Child {
|
||||||
view: Box<dyn View>,
|
view: Box<dyn View>,
|
||||||
position: Rect,
|
position: Rect,
|
||||||
@ -123,7 +140,21 @@ impl FixedLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_focus(&mut self, target: Absolute) -> EventResult {
|
fn move_focus_rel(&mut self, target: Relative) -> EventResult {
|
||||||
|
let source = Direction::Rel(target.swap());
|
||||||
|
for (i, c) in
|
||||||
|
Self::iter_mut(source, &mut self.children).skip(self.focus + 1)
|
||||||
|
{
|
||||||
|
if c.view.take_focus(source) {
|
||||||
|
self.focus = i;
|
||||||
|
return EventResult::Consumed(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EventResult::Ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_focus_abs(&mut self, target: Absolute) -> EventResult {
|
||||||
let source = Direction::Abs(target.opposite());
|
let source = Direction::Abs(target.opposite());
|
||||||
let (orientation, rel) = target.split();
|
let (orientation, rel) = target.split();
|
||||||
|
|
||||||
@ -198,6 +229,7 @@ impl View for FixedLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(&mut self, event: Event) -> EventResult {
|
fn on_event(&mut self, event: Event) -> EventResult {
|
||||||
|
eprintln!("Self focus: {:?}", self.focus);
|
||||||
if self.is_empty() {
|
if self.is_empty() {
|
||||||
return EventResult::Ignored;
|
return EventResult::Ignored;
|
||||||
}
|
}
|
||||||
@ -212,11 +244,12 @@ impl View for FixedLayout {
|
|||||||
|
|
||||||
match result {
|
match result {
|
||||||
EventResult::Ignored => match event {
|
EventResult::Ignored => match event {
|
||||||
Event::Key(Key::Tab) => unimplemented!(),
|
Event::Shift(Key::Tab) => self.move_focus_rel(Relative::Front),
|
||||||
Event::Key(Key::Left) => self.move_focus(Absolute::Left),
|
Event::Key(Key::Tab) => self.move_focus_rel(Relative::Back),
|
||||||
Event::Key(Key::Right) => self.move_focus(Absolute::Right),
|
Event::Key(Key::Left) => self.move_focus_abs(Absolute::Left),
|
||||||
Event::Key(Key::Up) => self.move_focus(Absolute::Up),
|
Event::Key(Key::Right) => self.move_focus_abs(Absolute::Right),
|
||||||
Event::Key(Key::Down) => self.move_focus(Absolute::Down),
|
Event::Key(Key::Up) => self.move_focus_abs(Absolute::Up),
|
||||||
|
Event::Key(Key::Down) => self.move_focus_abs(Absolute::Down),
|
||||||
_ => EventResult::Ignored,
|
_ => EventResult::Ignored,
|
||||||
},
|
},
|
||||||
res => res,
|
res => res,
|
||||||
@ -243,6 +276,7 @@ impl View for FixedLayout {
|
|||||||
|
|
||||||
fn take_focus(&mut self, source: Direction) -> bool {
|
fn take_focus(&mut self, source: Direction) -> bool {
|
||||||
// TODO: what if source = None?
|
// TODO: what if source = None?
|
||||||
|
eprintln!("Self focus: {:?}", self.focus);
|
||||||
match source {
|
match source {
|
||||||
Direction::Abs(Absolute::None) => {
|
Direction::Abs(Absolute::None) => {
|
||||||
// For now, take focus if any view is focusable.
|
// For now, take focus if any view is focusable.
|
||||||
|
@ -648,7 +648,7 @@ impl View for StackView {
|
|||||||
// The text view takes focus because it's scrolling, but it only
|
// The text view takes focus because it's scrolling, but it only
|
||||||
// knows that after a call to `layout()`.
|
// knows that after a call to `layout()`.
|
||||||
if layer.virgin {
|
if layer.virgin {
|
||||||
layer.view.take_focus(Direction::none());
|
layer.view.take_focus(Direction::front());
|
||||||
layer.virgin = false;
|
layer.virgin = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,20 @@
|
|||||||
|
use cursive::{
|
||||||
|
views::{Button, FixedLayout, TextView},
|
||||||
|
Rect,
|
||||||
|
};
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut siv = cursive::default();
|
let mut siv = cursive::default();
|
||||||
|
|
||||||
siv.add_layer(
|
siv.add_layer(
|
||||||
cursive::views::Dialog::around(
|
cursive::views::Dialog::around(
|
||||||
cursive::views::FixedLayout::new().child(
|
FixedLayout::new()
|
||||||
cursive::Rect::from_size((0, 0), (10, 1)),
|
.child(Rect::from_size((0, 0), (1, 1)), TextView::new("/"))
|
||||||
cursive::views::TextView::new("abc"),
|
.child(Rect::from_size((14, 0), (1, 1)), TextView::new(r"\"))
|
||||||
|
.child(Rect::from_size((0, 2), (1, 1)), TextView::new(r"\"))
|
||||||
|
.child(Rect::from_size((14, 2), (1, 1)), TextView::new("/"))
|
||||||
|
.child(
|
||||||
|
Rect::from_size((2, 1), (11, 1)),
|
||||||
|
Button::new("Click me!", |s| s.quit()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.button("Quit", |s| s.quit()),
|
.button("Quit", |s| s.quit()),
|
||||||
|
Loading…
Reference in New Issue
Block a user