From 0150ebfc9eca7518e15de8fc2f7a8daaec43737e Mon Sep 17 00:00:00 2001 From: Alexandre Bury Date: Thu, 12 Oct 2017 17:29:19 -0700 Subject: [PATCH] Add mouse support to LinearLayout --- src/views/linear_layout.rs | 70 +++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/src/views/linear_layout.rs b/src/views/linear_layout.rs index 9de61f5..3f6be41 100644 --- a/src/views/linear_layout.rs +++ b/src/views/linear_layout.rs @@ -5,6 +5,7 @@ use direction; use event::{Event, EventResult, Key}; use std::any::Any; use std::cmp::min; +use std::ops::Deref; use vec::Vec2; use view::{Selector, SizeCache}; use view::View; @@ -36,6 +37,24 @@ impl Child { } } +struct ChildIterator { + inner: I, + offset: usize, + orientation: direction::Orientation, +} + +impl <'a,T: Deref, I: Iterator> Iterator for ChildIterator { + type Item = (usize, T); + + fn next(&mut self) -> Option { + self.inner.next().map(|child| { + let previous = self.offset; + self.offset += child.size.get(self.orientation); + (previous, child) + }) + } +} + fn cap<'a, I: Iterator>(iter: I, max: usize) { let mut available = max; for item in iter { @@ -163,6 +182,43 @@ impl LinearLayout { self.focus = i; 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( @@ -357,7 +413,19 @@ impl View for LinearLayout { } 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 { Event::Shift(Key::Tab) if self.focus > 0 => { self.move_focus(direction::Direction::back())