Skip to content

Commit af2ce94

Browse files
committed
Support simple focusing of items with mouse and Tab key.
1 parent 7800deb commit af2ce94

File tree

1 file changed

+44
-7
lines changed

1 file changed

+44
-7
lines changed

src/lib.rs

+44-7
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use std::{
2222
rc::{Rc, Weak},
2323
};
2424

25-
use cursive_core::{event::EventResult, view::IntoBoxedView, Rect, Vec2, View, XY};
25+
use cursive_core::{event::{EventResult, Event, Key}, view::IntoBoxedView, Rect, Vec2, View, XY, direction::{Relative, Absolute, Direction}};
2626
use layout::{Layout, PlacedElement};
2727

2828
/// A container that can be used to display a list of items in a flexible way.
@@ -940,16 +940,43 @@ impl Flexbox {
940940
});
941941
result
942942
}
943+
944+
fn try_focus(&mut self, child_index: usize, source: Direction) -> Option<EventResult> {
945+
if let Some(view) = self.content.get(child_index) {
946+
if let Ok(result) = view.borrow_mut().view.take_focus(source) {
947+
self.focused = Some(child_index);
948+
return Some(result);
949+
}
950+
}
951+
None
952+
}
953+
954+
fn move_focus_rel(&mut self, target: Relative) -> EventResult {
955+
let adv: isize = if target == Relative::Front { -1 } else { 1 };
956+
let child_count = self.content.len();
957+
let get_next = |n| (n as isize + adv).rem_euclid(child_count as isize) as usize;
958+
let mut attempts = child_count - 1;
959+
let mut next = if let Some(n) = self.focused { get_next(n) } else { 0 };
960+
while attempts > 0 {
961+
if let Some(result) = self.try_focus(next, Direction::Rel(target)) {
962+
return result;
963+
}
964+
next = get_next(next);
965+
attempts -= 1;
966+
}
967+
EventResult::Ignored
968+
}
969+
943970
}
944971

945972
impl View for Flexbox {
946973
/// Draw this view using the printer.
947974
fn draw(&self, printer: &cursive_core::Printer<'_, '_>) {
948975
if let Some(ref layout) = self.layout {
949-
for placed_element in layout {
976+
for (i, placed_element) in layout.iter().enumerate() {
950977
RefCell::borrow(&placed_element.element)
951978
.view
952-
.draw(&printer.windowed(placed_element.position));
979+
.draw(&printer.windowed(placed_element.position).focused(Some(i) == self.focused));
953980
}
954981
}
955982
}
@@ -992,7 +1019,13 @@ impl View for Flexbox {
9921019
&mut self,
9931020
mut event: cursive_core::event::Event,
9941021
) -> cursive_core::event::EventResult {
995-
if let cursive_core::event::Event::Mouse {
1022+
if let Some(result) = match event {
1023+
Event::Shift(Key::Tab) => Some(self.move_focus_rel(Relative::Front)),
1024+
Event::Key(Key::Tab) => Some(self.move_focus_rel(Relative::Back)),
1025+
_ => None,
1026+
} {
1027+
result
1028+
} else if let cursive_core::event::Event::Mouse {
9961029
ref mut offset,
9971030
ref mut position,
9981031
..
@@ -1003,9 +1036,13 @@ impl View for Flexbox {
10031036
layout.element_at(global_to_view_coordinates(*position, *offset))
10041037
{
10051038
*offset = *offset + placed_element.position.top_left();
1006-
RefCell::borrow_mut(&placed_element.element)
1007-
.view
1008-
.on_event(event)
1039+
if let Some(index) = self.content.iter().position(|v| v.as_ptr() == placed_element.element.as_ptr()) {
1040+
self.try_focus(index, Direction::Abs(Absolute::None));
1041+
self.content[index].borrow_mut().view.on_event(event)
1042+
}
1043+
else {
1044+
RefCell::borrow_mut(&placed_element.element).view.on_event(event)
1045+
}
10091046
} else {
10101047
EventResult::Ignored
10111048
}

0 commit comments

Comments
 (0)