use std::collections::BTreeMap;
use typed_builder::*;
use crate::constants::DEFAULT_WIDGET_ID;
use crate::error::{BottomError, Result};
/// Represents a more usable representation of the layout, derived from the
/// config.
#[derive(Clone, Debug)]
pub struct BottomLayout {
pub rows: Vec<BottomRow>,
pub total_row_height_ratio: u32,
}
// Represents a start and end coordinate in some dimension.
type LineSegment = (u32, u32);
type WidgetMappings = (u32, BTreeMap<LineSegment, u64>);
type ColumnRowMappings = (u32, BTreeMap<LineSegment, WidgetMappings>);
type ColumnMappings = (u32, BTreeMap<LineSegment, ColumnRowMappings>);
impl BottomLayout {
pub fn get_movement_mappings(&mut self) {
#[allow(clippy::suspicious_operation_groupings)] // Have to enable this, clippy really doesn't like me doing this with tuples...
fn is_intersecting(a: LineSegment, b: LineSegment) -> bool {
a.0 >= b.0 && a.1 <= b.1
|| a.1 >= b.1 && a.0 <= b.0
|| a.0 <= b.0 && a.1 >= b.0
|| a.0 >= b.0 && a.0 < b.1 && a.1 >= b.1
}
fn get_distance(target: LineSegment, candidate: LineSegment) -> u32 {
if candidate.0 < target.0 {
candidate.1 - target.0
} else if candidate.1 < target.1 {
candidate.1 - candidate.0
} else {
target.1 - candidate.0
}
}
// Now we need to create the correct mapping for moving from a specific
// widget to another
let mut layout_mapping: BTreeMap<LineSegment, ColumnMappings> = BTreeMap::new();
let mut total_height = 0;
for row in &self.rows {
let mut row_width = 0;
let mut row_mapping: BTreeMap<LineSegment, ColumnRowMappings> = BTreeMap::new();
let mut is_valid_row = false;
for col in &row.children {
let mut col_row_height = 0;
let mut col_mapping: BTreeMap<LineSegment, WidgetMappings> = BTreeMap::new();
let mut is_valid_col = false;
for col_row in &col.children {
let mut widget_width = 0;
let mut col_row_mapping: BTreeMap<LineSegment, u64> = BTreeMap::new();
let mut is_valid_col_row = false;
for widget in &col_row.children {
match widget.widget_type {
BottomWidgetType::Empty => {}
_ => {
is_valid_col_row = true;
col_row_mapping.insert(
(
widget_width * 100 / col_row.total_widget_ratio,
(widget_width + widget.width_ratio) * 100
/ col_row.total_widget_ratio,
),
widget.widget_id,
);
}
}
widget_width += widget.width_ratio;
}
if is_valid_col_row {
col_mapping.insert(
(
col_row_height * 100 / col.total_col_row_ratio,
(col_row_height + col_row.col_row_height_ratio) * 100
/ col.total_col_row_ratio,
),
(col.total_col_row_ratio, col_row_mapping),
);
is_valid_col = true;
}
col_row_height += col_row.col_row_height_ratio;
}
if is_valid_col {
row_mapping.insert(
(
row_width * 100 / row.total_col_ratio,
(