extern crate cursive;
extern crate failure;
extern crate indextree;
#[macro_use]
extern crate failure_derive;
#[macro_use]
extern crate log;
mod error;
use cursive::direction::{Absolute, Direction};
use cursive::event::{Event, EventResult, Key};
use cursive::view::{Selector, View};
use cursive::Printer;
use cursive::Vec2;
use error::{AddViewError, RemoveViewError, SwitchError};
use std::convert::TryFrom;
#[derive(Debug)]
pub enum Path {
LeftOrUp(Box<Option<Path>>),
RightOrDown(Box<Option<Path>>),
}
#[derive(Debug, PartialEq)]
enum Orientation {
Vertical,
Horizontal,
}
#[derive(Debug, PartialEq)]
enum SearchPath {
Left,
Right,
Up,
Down,
}
pub type Id = indextree::NodeId;
pub struct Mux {
tree: indextree::Arena<Node>,
root: indextree::NodeId,
focus: indextree::NodeId,
focus_up: Event,
focus_down: Event,
focus_left: Event,
focus_right: Event,
resize_left: Event,
resize_right: Event,
resize_up: Event,
resize_down: Event,
}
pub struct MuxBuilder {
focus_up: Event,
focus_down: Event,
focus_left: Event,
focus_right: Event,
resize_left: Event,
resize_right: Event,
resize_up: Event,
resize_down: Event,
}
impl MuxBuilder {
pub fn new() -> Self {
MuxBuilder {
focus_up: Event::Shift(Key::Up),
focus_down: Event::Shift(Key::Down),
focus_left: Event::Shift(Key::Left),
focus_right: Event::Shift(Key::Right),
resize_up: Event::Ctrl(Key::Up),
resize_down: Event::Ctrl(Key::Down),
resize_left: Event::Ctrl(Key::Left),
resize_right: Event::Ctrl(Key::Right),
}
}
pub fn build<T>(&self, v: T) -> (Mux, Id)
where
T: View,
{
let root_node = Node {
view: None,
split_ratio_offset: 0,
orientation: Orientation::Horizontal,
};
let mut new_tree = indextree::Arena::new();
let new_root = new_tree.new_node(root_node);
let mut new_mux = Mux {
tree: new_tree,
root: new_root,
focus: new_root,
focus_up: self.focus_up.clone(),
focus_down: self.focus_down.clone(),
focus_left: self.focus_left.clone(),
focus_right: self.focus_right.clone(),
resize_left: self.resize_left.clone(),
resize_right: self.resize_right.clone(),
resize_up: self.resize_up.clone(),
resize_down: self.resize_down.clone(),
};
let fst_view = new_mux.add_horizontal_id(v, new_root).unwrap();
(new_mux, fst_view)
}
pub fn focus_up(&mut self, evt: Event) -> &mut Self {
self.focus_up = evt;
self
}
pub fn focus_down(&mut self, evt: Event) -> &mut Self {
self.focus_down = evt;
self
}
pub fn focus_left(&mut self, evt: Event) -> &mut Self {
self.focus_left = evt;
self
}
pub fn focus_right(&mut self, evt: Event) -> &mut Self {
self.focus_right = evt;
self
}
pub fn resize_left(&mut self, evt: Event) -> &mut Self {
self.resize_left = evt;
self
}
pub fn resize_right(&mut self, evt: Event) -> &mut Self {
self.resize_right = evt;
self
}
pub fn resize_up(&mut self, evt: Event) -> &mut Self {
self.resize_up = evt;
self
}
pub fn resize_down(&mut self, evt: Event) -> &mut Self {
self.resize_down = evt;
self
}
}
impl View for Mux {
fn draw(&self, printer: &Printer) {
debug!("Current Focus: {}", self.focus);
self.rec_draw(printer, self.root)
}
fn needs_relayout(&self) -> bool {
true
}
fn required_size(&mut self, constraint: Vec2) -> Vec2 {
constraint
}
fn layout(&mut self, constraint: Vec2) {
self.rec_layout(self.root, constraint);
}
fn take_focus(&mut self, _source: Direction) -> bool {
true
}
fn focus_view(&mut self, _: &Selector) -> Result<(), ()> {
Ok(())
}
fn on_event(&mut self, evt: Event) -> EventResult {
let result = self
.tree
.get_mut(self.focus)
.unwrap()
.get_mut()
.on_event(evt.relativized(Vec2::new(0, 0)));
match result {
EventResult::Ignored => match evt {
_ if self.focus_left == evt => self.move_focus(Absolute::Left),
_ if self.focus_right == evt => self.move_focus(Absolute::Right),
_ if self.focus_up == evt => self.move_focus(Absolute::Up),
_ if self.focus_down == evt => self.move_focus(Absolute::Down),
_ if self.resize_left == evt => self.resize(Absolute::Left),
_ if self.resize_right == evt => self.resize(Absolute::Right),
_ if self.resize_up == evt => self.resize(Absolute::Up),
_ if self.resize_down == evt => self.resize(Absolute::Down),
_ => EventResult::Ignored,
},
result => result,
}
}
}
struct Node {
view: Option<Box<dyn View>>,
orientation: Orientation,
split_ratio_offset: i16,
}
impl Node {
fn new<T>(v: T, orit: Orientation) -> Self
where
T: View,
{
Self {
view: Some(Box::new(v)),
orientation: orit,
split_ratio_offset: 0,
}
}
fn has_view(&self) -> bool {
match self.view {
Some(_) => true,
None => false,
}
}
fn layout_view(&mut self, vec: Vec2) {
if let Some(x) = self.view.as_mut() {
x.layout(vec);
}
}
fn on_event(&mut self, evt: Event) -> EventResult {
if let Some(view) = self.view.as_mut() {
view.on_event(evt)
} else {
EventResult::Ignored
}
}
fn draw(&self, printer: &Printer) {
match self.view {
Some(ref view) => {
view.draw(printer);
}
None => {}
}
}
fn take_focus(&mut self) -> bool {
if let Some(view) = self.view.as_mut() {
view.take_focus(Direction::none())
} else {
false
}
}
}
impl Mux {
pub fn get_focus(&self) -> Id {
self.focus
}
fn resize(&mut self, direction: Absolute) -> EventResult {
let orit = {
match direction {
Absolute::Left | Absolute::Right => Orientation::Horizontal,
Absolute::Up | Absolute::Down => Orientation::Vertical,
_ => Orientation::Horizontal,
}
};
let mut parent = self.focus.ancestors(&self.tree).nth(1);
while parent.is_some() {
if let Some(view) = self.tree.get_mut(parent.unwrap()) {
if view.get().orientation == orit {
match direction {
Absolute::Left | Absolute::Up => {
view.get_mut().split_ratio_offset -= 1;
return EventResult::Consumed(None);
}
Absolute::Right | Absolute::Down => {
view.get_mut().split_ratio_offset += 1;
return EventResult::Consumed(None);
}
_ => {}
}
} else {
parent = parent.unwrap().ancestors(&self.tree).nth(1);
}
}
}
EventResult::Ignored
}
fn rec_layout(&mut self, root: Id, constraint: Vec2) {
match root.children(&self.tree).count() {
1 => self.rec_layout(root.children(&self.tree).next().unwrap(), constraint),
2 => {
let left = root.children(&self.tree).next().unwrap();
let right = root.children(&self.tree).last().unwrap();
let const1;
let const2;
let root_data = &self.tree.get(root).unwrap().get();
match root_data.orientation {
Orientation::Horizontal => {
const1 = Vec2::new(
Mux::add_offset(constraint.x / 2, root_data.split_ratio_offset),
constraint.y,
);
const2 = Vec2::new(
Mux::add_offset(constraint.x / 2, -root_data.split_ratio_offset) + 1,
constraint.y,
);
if const1.x <= 3 {
self.tree.get_mut(root).unwrap().get_mut().split_ratio_offset += 1;
} else if const1.x >= constraint.x - 3 {
self.tree.get_mut(root).unwrap().get_mut().split_ratio_offset -= 1;
}
}
Orientation::Vertical => {
const1 = Vec2::new(
constraint.x,
Mux::add_offset(constraint.y / 2, root_data.split_ratio_offset),
);
const2 = Vec2::new(
constraint.x,
Mux::add_offset(constraint.y / 2, -root_data.split_ratio_offset) + 1,
);
if const1.y <= 3 {
self.tree.get_mut(root).unwrap().get_mut().split_ratio_offset += 1;
} else if const1.y >= constraint.y - 3 {
self.tree.get_mut(root).unwrap().get_mut().split_ratio_offset -= 1;
}
}
}
self.rec_layout(left, const1);
self.rec_layout(right, const2);
}
0 => {
self.tree
.get_mut(root)
.unwrap()
.get_mut()
.layout_view(constraint);
}
_ => debug!("Illegal Number of Child Nodes"),
}
}
fn add_offset(split: usize, offset: i16) -> usize {
if offset < 0 {
match usize::try_from(offset.abs()) {
Ok(u) => {
if split < u {
split
} else {
split - u
}
}
Err(_) => split,
}
} else {
match usize::try_from(offset) {
Ok(u) => split + u,
Err(_) => split,
}
}
}
fn rec_draw(&self, printer: &Printer, root: Id) {
match root.children(&self.tree).count() {
1 => self.rec_draw(printer, root.children(&self.tree).next().unwrap()),
2 => {
debug!("Print Children Nodes");
let left = root.children(&self.tree).next().unwrap();
let right = root.children(&self.tree).last().unwrap();
let printer1;
let printer2;
let root_data = &self.tree.get(root).unwrap().get();
match root_data.orientation {
Orientation::Horizontal => {
printer1 = printer.cropped(Vec2::new(
Mux::add_offset(printer.size.x / 2, root_data.split_ratio_offset),
printer.size.y,
));
printer2 = printer
.offset(Vec2::new(
Mux::add_offset(printer.size.x / 2, root_data.split_ratio_offset)
+ 1,
0,
))
.cropped(Vec2::new(
Mux::add_offset(printer.size.x / 2, -root_data.split_ratio_offset),
printer.size.y,
));
}
Orientation::Vertical => {
printer1 = printer.cropped(Vec2::new(
printer.size.x,
Mux::add_offset(printer.size.y / 2, root_data.split_ratio_offset),
));
printer2 = printer
.offset(Vec2::new(
0,
Mux::add_offset(printer.size.y / 2, root_data.split_ratio_offset)
+ 1,
))
.cropped(Vec2::new(
printer.size.x,
Mux::add_offset(printer.size.y / 2, -root_data.split_ratio_offset),
));
}
}
self.rec_draw(&printer1, left);
match self.tree.get(root).unwrap().get().orientation {
Orientation::Vertical => {
if printer.size.y > 1 {
printer.print_hline(
Vec2::new(
0,
Mux::add_offset(
printer.size.y / 2,
root_data.split_ratio_offset,
),
),
printer.size.x,
"─",
);
}
}
Orientation::Horizontal => {
if printer.size.x > 1 {
printer.print_vline(
Vec2::new(
Mux::add_offset(
printer.size.x / 2,
root_data.split_ratio_offset,
),
0,
),
printer.size.y,
"│",
);
}
}
}
self.rec_draw(&printer2, right);
}
0 => {
self.tree
.get(root)
.unwrap()
.get()
.draw(&printer.focused(self.focus == root));
}
_ => debug!("Illegal Number of Child Nodes"),
}
}
pub fn add_horizontal_path<T>(&mut self, v: T, path: Path) -> Result<Id, AddViewError>
where
T: View,
{
self.add_node_path(v, Some(path), Orientation::Horizontal, self.root)
}
pub fn add_vertical_path<T>(&mut self, v: T, path: Path) -> Result<Id, AddViewError>
where
T: View,
{
self.add_node_path(v, Some(path), Orientation::Vertical, self.root)
}
fn add_node_path<T>(
&mut self,
v: T,
path: Option<Path>,
orientation: Orientation,
cur_node: indextree::NodeId,
) -> Result<Id, AddViewError>
where
T: View,
{
match path {
Some(path_val) => {
match path_val {
Path::LeftOrUp(ch) => {
match cur_node.children(&self.tree).nth(0) {
Some(node) => self.add_node_path(v, *ch, orientation, node),
None => {
self.add_node_path(v, None, orientation, cur_node)
}
}
}
Path::RightOrDown(ch) => {
if cur_node.children(&self.tree).count() < 2 {
match cur_node.children(&self.tree).last() {
Some(node) => {
self.add_node_path(v, *ch, orientation, node)
}
None => {
self.add_node_path(v, None, orientation, cur_node)
}
}
} else {
Err(AddViewError::InvalidPath { path: ch.unwrap() })
}
}
}
}
None if cur_node.following_siblings(&self.tree).count()
+ cur_node.preceding_siblings(&self.tree).count()
< 2 =>
{
let new_node = self.tree.new_node(Node::new(v, Orientation::Horizontal));
cur_node.insert_after(new_node, &mut self.tree);
self.focus = new_node;
debug!("Changed Focus: {}", new_node);
Ok(new_node)
}
None => {
let parent = cur_node.ancestors(&self.tree).nth(1).unwrap();
cur_node.detach(&mut self.tree);
let new_intermediate = self.tree.new_node(Node {
view: None,
split_ratio_offset: 0,
orientation: Orientation::Horizontal,
});
parent.append(new_intermediate, &mut self.tree);
new_intermediate.append(cur_node, &mut self.tree);
let new_node = self.tree.new_node(Node::new(v, Orientation::Horizontal));
new_intermediate.append(new_node, &mut self.tree);
self.focus = new_node;
debug!("Changed Focus: {}", new_node);
Ok(new_node)
}
}
}
pub fn add_horizontal_id<T>(&mut self, v: T, id: Id) -> Result<Id, AddViewError>
where
T: View,
{
self.add_node_id(v, id, Orientation::Horizontal)
}
fn add_node_id<T>(&mut self, v: T, id: Id, orientation: Orientation) -> Result<Id, AddViewError>
where
T: View,
{
let new_node = self.tree.new_node(Node::new(v, Orientation::Horizontal));
let mut node_id;
if let Some(parent) = id.ancestors(&self.tree).nth(1) {
node_id = parent;
} else {
node_id = id;
}
if node_id.children(&self.tree).count() < 2
&& !self.tree.get(node_id).unwrap().get().has_view()
{
node_id.append(new_node, &mut self.tree);
self.tree.get_mut(node_id).unwrap().get_mut().orientation = orientation;
} else {
let parent = node_id;
node_id = id;
let position: Path;
if parent.children(&self.tree).next().unwrap() == node_id {
position = Path::LeftOrUp(Box::new(None));
} else {
position = Path::RightOrDown(Box::new(None));
}
node_id.detach(&mut self.tree);
let new_intermediate = self.tree.new_node(Node {
view: None,
split_ratio_offset: 0,
orientation: orientation,
});
match position {
Path::RightOrDown(_) => {
parent.append(new_intermediate, &mut self.tree);
}
Path::LeftOrUp(_) => {
parent.prepend(new_intermediate, &mut self.tree);
}
}
new_intermediate.append(node_id, &mut self.tree);
new_intermediate.append(new_node, &mut self.tree);
debug!("Changed order");
}
self.focus = new_node;
debug!("Changed Focus: {}", new_node);
Ok(new_node)
}
pub fn add_vertical_id<T>(&mut self, v: T, id: Id) -> Result<Id, AddViewError>
where
T: View,
{
self.add_node_id(v, id, Orientation::Vertical)
}
pub fn remove_id(&mut self, id: Id) -> Result<Id, RemoveViewError> {
let desc: Vec<Id> = self.root.descendants(&self.tree).collect();
if desc.contains(&id) {
let sib_id: Id;
if id.preceding_siblings(&self.tree).count() > 1 {
sib_id = id.preceding_siblings(&self.tree).nth(1).unwrap();
} else if id.following_siblings(&self.tree).count() > 1 {
sib_id = id.following_siblings(&self.tree).nth(1).unwrap();
} else {
return Err(RemoveViewError::Generic {});
}
let parent = id.ancestors(&self.tree).nth(1).unwrap();
id.detach(&mut self.tree);
if let Some(anker) = parent.ancestors(&self.tree).nth(1) {
if anker.children(&self.tree).next().unwrap() == parent {
parent.detach(&mut self.tree);
anker.prepend(sib_id, &mut self.tree);
self.focus = sib_id;
Ok(id)
} else {
parent.detach(&mut self.tree);
anker.append(sib_id, &mut self.tree);
self.focus = sib_id;
Ok(id)
}
} else {
self.root = sib_id;
self.focus = sib_id;
Ok(id)
}
} else {
Err(RemoveViewError::InvalidId { id: id })
}
}
pub fn switch_views(&mut self, fst: Id, snd: Id) -> Result<(), SwitchError> {
if let Some(parent1) = fst.ancestors(&self.tree).nth(1) {
if let Some(parent2) = snd.ancestors(&self.tree).nth(1) {
if parent1.children(&self.tree).next().unwrap() == fst {
fst.detach(&mut self.tree);
if parent2.children(&self.tree).next().unwrap() == snd {
snd.detach(&mut self.tree);
parent1.prepend(snd, &mut self.tree);
parent2.prepend(fst, &mut self.tree);
Ok(())
} else {
snd.detach(&mut self.tree);
parent1.prepend(snd, &mut self.tree);
parent2.append(fst, &mut self.tree);
Ok(())
}
} else {
fst.detach(&mut self.tree);
if parent2.children(&self.tree).next().unwrap() == snd {
snd.detach(&mut self.tree);
parent1.append(snd, &mut self.tree);
parent2.prepend(fst, &mut self.tree);
Ok(())
} else {
snd.detach(&mut self.tree);
parent1.append(snd, &mut self.tree);
parent2.append(fst, &mut self.tree);
Ok(())
}
}
} else {
Err(SwitchError::NoParent { from: snd, to: fst })
}
} else {
Err(SwitchError::NoParent { from: fst, to: snd })
}
}
fn move_focus(&mut self, direction: Absolute) -> EventResult {
match self.search_focus_path(
direction,
self.focus.ancestors(&self.tree).nth(1).unwrap(),
self.focus,
) {
Ok((path, turn_point)) => {
if let Some(focus) = self.traverse_search_path(path, turn_point) {
if self.tree.get_mut(focus).unwrap().get_mut().take_focus() {
self.focus = focus;
EventResult::Consumed(None)
} else {
debug!("Focus rejected by {}", focus);
EventResult::Ignored
}
} else {
EventResult::Ignored
}
}
Err(_) => EventResult::Ignored,
}
}
fn traverse_search_path(&self, mut path: Vec<SearchPath>, turn_point: Id) -> Option<Id> {
let mut cur_node = turn_point;
while let Some(step) = path.pop() {
match self.traverse_single_node(step, turn_point, cur_node) {
Some(node) => {
cur_node = node;
}
None => {
break;
}
}
}
while !self.tree.get(cur_node).unwrap().get().has_view() {
match cur_node.children(&self.tree).next() {
Some(node) => cur_node = node,
None => return None,
}
}
Some(cur_node)
}
fn traverse_single_node(&self, action: SearchPath, turn_point: Id, cur_node: Id) -> Option<Id> {
let left = || -> Option<Id> {
if let Some(left) = cur_node.children(&self.tree).next() {
Some(left)
} else {
None
}
};
let right = || -> Option<Id> {
if let Some(right) = cur_node.children(&self.tree).last() {
Some(right)
} else {
None
}
};
let up = left;
let down = right;
match self.tree.get(turn_point).unwrap().get().orientation {
Orientation::Horizontal => {
match action {
SearchPath::Right
if self.tree.get(cur_node).unwrap().get().orientation
== Orientation::Horizontal =>
{
left()
}
SearchPath::Left
if self.tree.get(cur_node).unwrap().get().orientation
== Orientation::Horizontal =>
{
right()
}
SearchPath::Up
if self.tree.get(cur_node).unwrap().get().orientation
== Orientation::Vertical =>
{
up()
}
SearchPath::Down
if self.tree.get(cur_node).unwrap().get().orientation
== Orientation::Vertical =>
{
down()
}
_ => None,
}
}
Orientation::Vertical => {
match action {
SearchPath::Right
if self.tree.get(cur_node).unwrap().get().orientation
== Orientation::Horizontal =>
{
right()
}
SearchPath::Left
if self.tree.get(cur_node).unwrap().get().orientation
== Orientation::Horizontal =>
{
left()
}
SearchPath::Up
if self.tree.get(cur_node).unwrap().get().orientation
== Orientation::Vertical =>
{
down()
}
SearchPath::Down
if self.tree.get(cur_node).unwrap().get().orientation
== Orientation::Vertical =>
{
up()
}
_ => None,
}
}
}
}
fn search_focus_path(
&self,
direction: Absolute,
nodeid: Id,
fromid: Id,
) -> Result<(Vec<SearchPath>, Id), ()> {
let mut cur_node = Some(nodeid);
let mut from_node = fromid;
let mut path = Vec::new();
while cur_node.is_some() {
match self.tree.get(cur_node.unwrap()).unwrap().get().orientation {
Orientation::Horizontal
if direction == Absolute::Left || direction == Absolute::Right =>
{
if cur_node.unwrap().children(&self.tree).next().unwrap() == from_node {
path.push(SearchPath::Left);
from_node = cur_node.unwrap();
if direction == Absolute::Left {
cur_node = cur_node.unwrap().ancestors(&self.tree).nth(1);
} else {
cur_node = None;
}
} else {
path.push(SearchPath::Right);
from_node = cur_node.unwrap();
if direction == Absolute::Right {
cur_node = cur_node.unwrap().ancestors(&self.tree).nth(1);
} else {
cur_node = None;
}
}
}
Orientation::Vertical
if direction == Absolute::Up || direction == Absolute::Down =>
{
if cur_node.unwrap().children(&self.tree).next().unwrap() == from_node {
path.push(SearchPath::Up);
from_node = cur_node.unwrap();
if direction == Absolute::Up {
cur_node = cur_node.unwrap().ancestors(&self.tree).nth(1);
} else {
cur_node = None;
}
} else {
path.push(SearchPath::Down);
from_node = cur_node.unwrap();
if direction == Absolute::Down {
cur_node = cur_node.unwrap().ancestors(&self.tree).nth(1);
} else {
cur_node = None;
}
}
}
Orientation::Horizontal => {
if cur_node.unwrap().children(&self.tree).next().unwrap() == from_node {
path.push(SearchPath::Left);
from_node = cur_node.unwrap();
cur_node = cur_node.unwrap().ancestors(&self.tree).nth(1);
} else {
path.push(SearchPath::Right);
from_node = cur_node.unwrap();
cur_node = cur_node.unwrap().ancestors(&self.tree).nth(1);
}
}
Orientation::Vertical => {
if cur_node.unwrap().children(&self.tree).next().unwrap() == from_node {
path.push(SearchPath::Up);
from_node = cur_node.unwrap();
cur_node = cur_node.unwrap().ancestors(&self.tree).nth(1);
} else {
path.push(SearchPath::Down);
from_node = cur_node.unwrap();
cur_node = cur_node.unwrap().ancestors(&self.tree).nth(1);
}
}
}
}
match self.tree.get(from_node).unwrap().get().orientation {
Orientation::Horizontal if direction == Absolute::Up || direction == Absolute::Down => {
Err(())
}
Orientation::Vertical
if direction == Absolute::Left || direction == Absolute::Right =>
{
Err(())
}
_ => Ok((path, from_node)),
}
}
}
#[cfg(test)]
mod tree {
use super::{Mux, MuxBuilder};
use cursive::event::{Event, Key};
use cursive::traits::View;
use cursive::views::{DummyView, TextArea};
#[test]
fn test_remove() {
let (mut test_mux, node1) = MuxBuilder::new().build(DummyView);
let node2 = test_mux.add_vertical_id(DummyView, node1).unwrap();
let node3 = test_mux.add_vertical_id(DummyView, node2).unwrap();
print_tree(&test_mux);
test_mux.remove_id(node3).unwrap();
print_tree(&test_mux);
match test_mux.remove_id(node3) {
Ok(_) => {
print_tree(&test_mux);
println!("Delete should have removed: {}", node3);
assert!(false);
}
Err(_) => {}
}
}
#[test]
fn test_switch() {
let (mut mux, node1) = MuxBuilder::new().build(DummyView);
let node2 = mux.add_horizontal_id(DummyView, node1).unwrap();
let node3 = mux.add_vertical_id(DummyView, node2).unwrap();
mux.switch_views(node1, node3).unwrap();
}
#[test]
fn test_nesting() {
println!("Nesting Test");
let (mut mux, _) = MuxBuilder::new().build(DummyView);
let mut nodes = Vec::new();
for _ in 0..10 {
print_tree(&mux);
match mux.add_horizontal_id(
DummyView,
if let Some(x) = nodes.last() {
*x
} else {
mux.root
},
) {
Ok(node) => {
nodes.push(node);
}
Err(_) => {
assert!(false);
}
}
match mux.add_vertical_id(DummyView, *nodes.last().unwrap()) {
Ok(node) => {
nodes.push(node);
}
Err(_) => {
assert!(false);
}
}
}
for node in nodes.iter() {
mux.focus = *node;
direction_test(&mut mux);
}
}
fn print_tree(mux: &Mux) {
print!("Current Tree: ");
for node in mux.root.descendants(&mux.tree) {
print!("{},", node);
}
println!("");
}
fn direction_test(mux: &mut Mux) {
mux.on_event(Event::Key(Key::Up));
mux.on_event(Event::Key(Key::Left));
mux.on_event(Event::Key(Key::Down));
mux.on_event(Event::Key(Key::Right));
mux.on_event(Event::Key(Key::Up));
mux.on_event(Event::Key(Key::Left));
mux.on_event(Event::Key(Key::Left));
mux.on_event(Event::Key(Key::Down));
mux.on_event(Event::Key(Key::Right));
mux.on_event(Event::Key(Key::Up));
mux.on_event(Event::Key(Key::Left));
}
}