mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-27 19:26:09 +00:00
Add mouse support to LinearLayout
This commit is contained in:
parent
13059dae0b
commit
0150ebfc9e
@ -5,6 +5,7 @@ use direction;
|
|||||||
use event::{Event, EventResult, Key};
|
use event::{Event, EventResult, Key};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
|
use std::ops::Deref;
|
||||||
use vec::Vec2;
|
use vec::Vec2;
|
||||||
use view::{Selector, SizeCache};
|
use view::{Selector, SizeCache};
|
||||||
use view::View;
|
use view::View;
|
||||||
@ -36,6 +37,24 @@ impl Child {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ChildIterator<I> {
|
||||||
|
inner: I,
|
||||||
|
offset: usize,
|
||||||
|
orientation: direction::Orientation,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl <'a,T: Deref<Target=Child>, I: Iterator<Item=T>> Iterator for ChildIterator<I> {
|
||||||
|
type Item = (usize, T);
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.inner.next().map(|child| {
|
||||||
|
let previous = self.offset;
|
||||||
|
self.offset += child.size.get(self.orientation);
|
||||||
|
(previous, child)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn cap<'a, I: Iterator<Item = &'a mut usize>>(iter: I, max: usize) {
|
fn cap<'a, I: Iterator<Item = &'a mut usize>>(iter: I, max: usize) {
|
||||||
let mut available = max;
|
let mut available = max;
|
||||||
for item in iter {
|
for item in iter {
|
||||||
@ -163,6 +182,43 @@ impl LinearLayout {
|
|||||||
self.focus = i;
|
self.focus = i;
|
||||||
EventResult::Consumed(None)
|
EventResult::Consumed(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_focus_grab(&mut self, event: &Event) {
|
||||||
|
if let &Event::Mouse {
|
||||||
|
offset,
|
||||||
|
position,
|
||||||
|
event,
|
||||||
|
} = event
|
||||||
|
{
|
||||||
|
if !event.grabs_focus() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let position = match position.checked_sub(offset) {
|
||||||
|
None => return,
|
||||||
|
Some(pos) => pos,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Find the selected child
|
||||||
|
let position = *position.get(self.orientation);
|
||||||
|
let iterator = ChildIterator {
|
||||||
|
inner: self.children.iter_mut(),
|
||||||
|
offset: 0,
|
||||||
|
orientation: self.orientation,
|
||||||
|
};
|
||||||
|
for (i, (offset, child)) in iterator.enumerate() {
|
||||||
|
let child_size = child.size.get(self.orientation);
|
||||||
|
// eprintln!("Offset {:?}, size {:?}, position: {:?}", offset, child_size, position);
|
||||||
|
if offset + child_size > position {
|
||||||
|
if child.view.take_focus(direction::Direction::none()) {
|
||||||
|
// eprintln!("It's a match!");
|
||||||
|
self.focus = i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_focus(
|
fn try_focus(
|
||||||
@ -357,7 +413,19 @@ impl View for LinearLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn on_event(&mut self, event: Event) -> EventResult {
|
fn on_event(&mut self, event: Event) -> EventResult {
|
||||||
match self.children[self.focus].view.on_event(event.clone()) {
|
self.check_focus_grab(&event);
|
||||||
|
|
||||||
|
let result = {
|
||||||
|
let mut iterator = ChildIterator {
|
||||||
|
inner: self.children.iter_mut(),
|
||||||
|
offset: 0,
|
||||||
|
orientation: self.orientation,
|
||||||
|
};
|
||||||
|
let (offset, child) = iterator.nth(self.focus).unwrap();
|
||||||
|
let offset = self.orientation.make_vec(offset, 0);
|
||||||
|
child.view.on_event(event.relativized(offset))
|
||||||
|
};
|
||||||
|
match result {
|
||||||
EventResult::Ignored => match event {
|
EventResult::Ignored => match event {
|
||||||
Event::Shift(Key::Tab) if self.focus > 0 => {
|
Event::Shift(Key::Tab) if self.focus > 0 => {
|
||||||
self.move_focus(direction::Direction::back())
|
self.move_focus(direction::Direction::back())
|
||||||
|
Loading…
Reference in New Issue
Block a user