use crate::preludes::widget_creation::*;
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum ColAnchor {
Left,
Center,
Right,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum RowAnchor {
Top,
Center,
Bottom,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Anchor {
pub col: ColAnchor,
pub row: RowAnchor,
}
impl Anchor {
pub fn new(col: ColAnchor, row: RowAnchor) -> Self {
Self {
col,
row,
}
}
pub fn get_position(&self, parent_size: Size, child_size: Size) -> Position {
let mut col = match self.col {
ColAnchor::Left => 0,
ColAnchor::Center => parent_size.cols.saturating_sub(child_size.cols) >> 1,
ColAnchor::Right => parent_size.cols.saturating_sub(child_size.cols),
};
let mut row = match self.row {
RowAnchor::Top => 0,
RowAnchor::Center => parent_size.rows.saturating_sub(child_size.rows) >> 1,
RowAnchor::Bottom => parent_size.rows.saturating_sub(child_size.rows),
};
if child_size.cols > parent_size.cols {
col = 0;
}
if child_size.rows > parent_size.rows {
row = 0;
}
Position::new(col as i16, row as i16)
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum AnchorContainerWidgetSize {
Fixed(Size),
Ratio(Size),
Min,
Max,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct AnchorContainer<W: Widget> {
pub anchor: Anchor,
pub widget: W,
pub widget_size: AnchorContainerWidgetSize,
widget_data: WidgetData,
}
impl<W: Widget> AnchorContainer<W> {
pub fn new(
anchor: Anchor,
widget_size: AnchorContainerWidgetSize,
widget: W,
) -> Self {
Self {
anchor,
widget,
widget_size,
widget_data: WidgetData::new(),
}
}
}
impl<W: Widget> Widget for AnchorContainer<W> {
fn draw(&mut self, canvas: &mut Canvas, state_frame: Option<&EventStateFrame>) {
if canvas.is_visible() == false {
return;
}
let child_info = self.widget.widget_info();
let size = match self.widget_size {
AnchorContainerWidgetSize::Fixed(size) => size,
AnchorContainerWidgetSize::Ratio(ratio) => canvas.transform.size / ratio,
AnchorContainerWidgetSize::Min => child_info.size_info.get_min(),
AnchorContainerWidgetSize::Max => child_info.size_info.get_max(),
};
let mut inner = canvas.new_child(Transform::new(
self.anchor.get_position(canvas.transform.size, size),
size,
));
self.widget.draw(&mut inner, state_frame);
}
fn widget_info(&self) -> WidgetInfo {
let child_info = self.widget.widget_info();
WidgetInfo {
size_info: match child_info.size_info {
WidgetSizeInfo::Dynamic { min, .. } => {
WidgetSizeInfo::Dynamic {
min,
max: None,
}
},
WidgetSizeInfo::Fixed(size) => {
WidgetSizeInfo::Dynamic {
min: Some(size),
max: None,
}
},
},
}
}
fn widget_data(&mut self) -> &mut WidgetData {
return &mut self.widget_data;
}
}