use crate::{
core::layout::{Layout, Message},
pure::{geometry::Rect, Stack},
Xid,
};
use std::fmt;
pub struct Conditional {
name: String,
left: Box<dyn Layout>,
right: Box<dyn Layout>,
should_use_left: fn(&Stack<Xid>, Rect) -> bool,
left_is_active: bool,
}
impl fmt::Debug for Conditional {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Conditional")
.field("name", &self.name)
.field("left", &self.left.name())
.field("right", &self.right.name())
.field("left_is_active", &self.left_is_active)
.finish()
}
}
impl Conditional {
pub fn new<L: Layout + 'static, R: Layout + 'static>(
name: impl Into<String>,
left: L,
right: R,
should_use_left: fn(&Stack<Xid>, Rect) -> bool,
) -> Self {
Self {
name: name.into(),
left: Box::new(left),
right: Box::new(right),
should_use_left,
left_is_active: true,
}
}
pub fn boxed<L: Layout + 'static, R: Layout + 'static>(
name: impl Into<String>,
left: L,
right: R,
should_use_left: fn(&Stack<Xid>, Rect) -> bool,
) -> Box<dyn Layout> {
Box::new(Self::new(name, left, right, should_use_left))
}
}
impl Layout for Conditional {
fn name(&self) -> String {
self.name.clone()
}
fn boxed_clone(&self) -> Box<dyn Layout> {
Box::new(Self {
name: self.name.clone(),
left: self.left.boxed_clone(),
right: self.right.boxed_clone(),
should_use_left: self.should_use_left,
left_is_active: self.left_is_active,
})
}
fn layout(&mut self, s: &Stack<Xid>, r: Rect) -> (Option<Box<dyn Layout>>, Vec<(Xid, Rect)>) {
self.left_is_active = (self.should_use_left)(s, r);
if self.left_is_active {
self.left.layout(s, r)
} else {
self.right.layout(s, r)
}
}
fn handle_message(&mut self, m: &Message) -> Option<Box<dyn Layout>> {
if self.left_is_active {
self.left.handle_message(m)
} else {
self.right.handle_message(m)
}
}
}