mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-04-08 17:05:59 +02:00
fully migrate over custom layout creation
This commit is contained in:
parent
a68a7346c3
commit
000ea7cce4
@ -5,7 +5,7 @@ use tui::layout::Direction;
|
||||
use crate::canvas::LayoutConstraint;
|
||||
use crate::constants::DEFAULT_WIDGET_ID;
|
||||
use crate::error::{BottomError, Result};
|
||||
use crate::options::layout_options::Row;
|
||||
use crate::options::layout_options::{Row, RowChildren};
|
||||
use crate::utils::error;
|
||||
|
||||
/// Represents a start and end coordinate in some dimension.
|
||||
@ -15,29 +15,11 @@ type WidgetMappings = (u32, BTreeMap<LineSegment, u64>);
|
||||
type ColumnRowMappings = (u32, BTreeMap<LineSegment, WidgetMappings>);
|
||||
type ColumnMappings = (u32, BTreeMap<LineSegment, ColumnRowMappings>);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Node {
|
||||
/// A container type, containing more [`Node`] children.
|
||||
Container(Container),
|
||||
|
||||
/// A leaf node, containing a [`BottomWidget`].
|
||||
Widget(BottomWidget),
|
||||
}
|
||||
|
||||
impl Node {
|
||||
pub fn constraint(&self) -> LayoutConstraint {
|
||||
match self {
|
||||
Node::Container(c) => c.constraint,
|
||||
Node::Widget(w) => w.constraint,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A "container" that contains more [`Node`]s.
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct Container {
|
||||
/// The children elements.
|
||||
pub(crate) children: Vec<usize>,
|
||||
pub(crate) children: Vec<NodeId>,
|
||||
|
||||
/// How the container should be sized.
|
||||
pub(crate) constraint: LayoutConstraint,
|
||||
@ -47,7 +29,7 @@ pub(crate) struct Container {
|
||||
}
|
||||
|
||||
impl Container {
|
||||
pub(crate) fn row(children: Vec<usize>, sizing: LayoutConstraint) -> Self {
|
||||
pub(crate) fn row(children: Vec<NodeId>, sizing: LayoutConstraint) -> Self {
|
||||
Self {
|
||||
children,
|
||||
constraint: sizing,
|
||||
@ -55,7 +37,7 @@ impl Container {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn col(children: Vec<usize>, constraint: LayoutConstraint) -> Self {
|
||||
pub(crate) fn col(children: Vec<NodeId>, constraint: LayoutConstraint) -> Self {
|
||||
Self {
|
||||
children,
|
||||
constraint,
|
||||
@ -88,42 +70,301 @@ impl From<ContainerDirection> for Direction {
|
||||
}
|
||||
}
|
||||
|
||||
/// An ID for a node in a [`BottomLayout`].
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum NodeId {
|
||||
/// The ID for a [`Container`].
|
||||
Container(usize),
|
||||
|
||||
/// The ID for a [`BottomWidget`].
|
||||
Widget(usize),
|
||||
}
|
||||
|
||||
fn new_cpu(
|
||||
layout: &mut BottomLayout, left_legend: bool, iter_id: &mut u64, width: u32, total: u32,
|
||||
) -> NodeId {
|
||||
let cpu_id = *iter_id;
|
||||
*iter_id += 1;
|
||||
let legend_id = *iter_id;
|
||||
|
||||
if left_legend {
|
||||
let cpu_legend = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::CpuLegend, legend_id)
|
||||
.parent_reflector(Some((WidgetDirection::Right, 1))),
|
||||
);
|
||||
let cpu = layout.add_widget(BottomWidget::new_handled(BottomWidgetType::Cpu, cpu_id));
|
||||
|
||||
layout.add_container(Container::row(
|
||||
vec![cpu_legend, cpu],
|
||||
LayoutConstraint::Ratio { a: width, b: total },
|
||||
))
|
||||
} else {
|
||||
let cpu = layout.add_widget(BottomWidget::new_handled(BottomWidgetType::Cpu, cpu_id));
|
||||
let cpu_legend = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::CpuLegend, legend_id)
|
||||
.parent_reflector(Some((WidgetDirection::Left, 1))),
|
||||
);
|
||||
|
||||
layout.add_container(Container::row(
|
||||
vec![cpu, cpu_legend],
|
||||
LayoutConstraint::Ratio { a: width, b: total },
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn new_proc(layout: &mut BottomLayout, iter_id: &mut u64, width: u32, total: u32) -> NodeId {
|
||||
let main_id = *iter_id;
|
||||
let search_id = *iter_id + 1;
|
||||
*iter_id += 2;
|
||||
let sort_id = *iter_id;
|
||||
|
||||
let main = layout.add_widget(BottomWidget::new_fill(BottomWidgetType::Proc, main_id));
|
||||
|
||||
let search = layout.add_widget(
|
||||
BottomWidget::new_fill(BottomWidgetType::ProcSearch, search_id)
|
||||
.parent_reflector(Some((WidgetDirection::Up, 1))),
|
||||
);
|
||||
|
||||
let sort = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::ProcSort, sort_id)
|
||||
.parent_reflector(Some((WidgetDirection::Right, 2))),
|
||||
);
|
||||
|
||||
let top = layout.add_container(Container::row(
|
||||
vec![sort, main],
|
||||
LayoutConstraint::CanvasHandled,
|
||||
));
|
||||
|
||||
layout.add_container(Container::col(
|
||||
vec![top, search],
|
||||
LayoutConstraint::Ratio { a: width, b: total },
|
||||
))
|
||||
}
|
||||
|
||||
fn new_widget(
|
||||
layout: &mut BottomLayout, widget_type: BottomWidgetType, iter_id: &mut u64, width: u32,
|
||||
total_ratio: u32, left_legend: bool,
|
||||
) -> NodeId {
|
||||
*iter_id += 1;
|
||||
|
||||
match widget_type {
|
||||
BottomWidgetType::Cpu => new_cpu(layout, left_legend, iter_id, width, total_ratio),
|
||||
BottomWidgetType::Proc => new_proc(layout, iter_id, width, total_ratio),
|
||||
_ => layout.add_widget(BottomWidget::new(
|
||||
widget_type,
|
||||
*iter_id,
|
||||
LayoutConstraint::Ratio {
|
||||
a: width,
|
||||
b: total_ratio,
|
||||
},
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a more usable representation of the layout, derived from the
|
||||
/// config.
|
||||
///
|
||||
/// Internally represented by an arena-backed tree.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct BottomLayout {
|
||||
arena: Vec<Node>,
|
||||
containers: Vec<Container>,
|
||||
widgets: Vec<BottomWidget>,
|
||||
}
|
||||
|
||||
impl BottomLayout {
|
||||
/// Add a node to the layout arena. The ID is returned.
|
||||
pub fn add_node(&mut self, node: Node) -> usize {
|
||||
let id = self.arena.len();
|
||||
self.arena.push(node);
|
||||
/// Add a container to the layout arena. The ID is returned.
|
||||
pub fn add_container(&mut self, container: Container) -> NodeId {
|
||||
let id = self.containers.len();
|
||||
self.containers.push(container);
|
||||
|
||||
id
|
||||
NodeId::Container(id)
|
||||
}
|
||||
|
||||
/// Add a node to the layout arena. The ID is returned.
|
||||
pub fn add_widget(&mut self, widget: BottomWidget) -> NodeId {
|
||||
let id = self.widgets.len();
|
||||
self.widgets.push(widget);
|
||||
|
||||
NodeId::Widget(id)
|
||||
}
|
||||
|
||||
/// Get the node with the corresponding ID.
|
||||
pub fn get_node(&self, id: usize) -> Option<&Node> {
|
||||
self.arena.get(id)
|
||||
pub fn get_container(&self, id: usize) -> Option<&Container> {
|
||||
self.containers.get(id)
|
||||
}
|
||||
|
||||
/// Returns the number of elements in the layout.
|
||||
/// Get the node with the corresponding ID.
|
||||
pub fn get_widget(&self, id: usize) -> Option<&BottomWidget> {
|
||||
self.widgets.get(id)
|
||||
}
|
||||
|
||||
/// Returns an iterator of all widgets.
|
||||
pub fn widgets_iter(&self) -> impl Iterator<Item = &BottomWidget> {
|
||||
self.widgets.iter()
|
||||
}
|
||||
|
||||
/// Returns the root ID if there is one. If there are no nodes, it will return [`None`].
|
||||
pub fn root_id(&self) -> Option<NodeId> {
|
||||
if self.containers.is_empty() {
|
||||
if self.widgets.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(NodeId::Widget(self.widgets.len() - 1))
|
||||
}
|
||||
} else {
|
||||
Some(NodeId::Container(self.containers.len() - 1))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the number of elements (widgets + containers) in the layout.
|
||||
pub fn len(&self) -> usize {
|
||||
self.arena.len()
|
||||
self.widgets.len() + self.containers.len()
|
||||
}
|
||||
|
||||
/// Creates a new [`BottomLayout`] given a slice of [`Row`]s.
|
||||
pub fn from_rows(rows: &[Row]) -> error::Result<Self> {
|
||||
let mut num_widgets = 0;
|
||||
/// Returns the number of widgets in the layout.
|
||||
pub fn widgets_len(&self) -> usize {
|
||||
self.widgets.len()
|
||||
}
|
||||
|
||||
// TODO: Create the thing; use num_widgets to count how many widgets were inserted.
|
||||
/// Creates a new [`BottomLayout`] given a slice of [`Row`]s, as well as the default widget ID.
|
||||
pub fn from_rows(
|
||||
rows: &[Row], default_widget_type: Option<BottomWidgetType>, mut default_widget_count: u64,
|
||||
left_legend: bool,
|
||||
) -> error::Result<(Self, u64)> {
|
||||
let mut layout = Self::default();
|
||||
let mut default_widget_id = 1;
|
||||
let mut iter_id = 0; // TODO: In the future, remove this in favour of using the layout's ID system.
|
||||
|
||||
if num_widgets > 0 {
|
||||
todo!()
|
||||
let outer_col_total_ratio = rows.iter().map(|row| row.ratio.unwrap_or(1)).sum();
|
||||
let mut outer_col_children = Vec::with_capacity(rows.len());
|
||||
|
||||
for row in rows {
|
||||
// This code is all ported from the old row-to-bottom_row code, and converted
|
||||
// to work with our new system.
|
||||
|
||||
// TODO: In the future we want to also add percentages.
|
||||
// But for MVP, we aren't going to bother.
|
||||
|
||||
let row_ratio = row.ratio.unwrap_or(1);
|
||||
|
||||
if let Some(children) = &row.child {
|
||||
let mut row_children = Vec::with_capacity(children.len());
|
||||
|
||||
let rows_total_ratio = children
|
||||
.iter()
|
||||
.map(|c| match c {
|
||||
RowChildren::Widget(w) => w.ratio.unwrap_or(1),
|
||||
RowChildren::Col { ratio, .. } => ratio.unwrap_or(1),
|
||||
})
|
||||
.sum();
|
||||
|
||||
for child in children {
|
||||
match child {
|
||||
RowChildren::Widget(widget) => {
|
||||
let width = widget.ratio.unwrap_or(1);
|
||||
let widget_type = widget.widget_type.parse::<BottomWidgetType>()?;
|
||||
|
||||
if let Some(default_widget_type_val) = default_widget_type {
|
||||
if default_widget_type_val == widget_type
|
||||
&& default_widget_count > 0
|
||||
{
|
||||
default_widget_count -= 1;
|
||||
if default_widget_count == 0 {
|
||||
default_widget_id = iter_id;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Check default flag
|
||||
if let Some(default_widget_flag) = widget.default {
|
||||
if default_widget_flag {
|
||||
default_widget_id = iter_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let widget = new_widget(
|
||||
&mut layout,
|
||||
widget_type,
|
||||
&mut iter_id,
|
||||
width,
|
||||
rows_total_ratio,
|
||||
left_legend,
|
||||
);
|
||||
|
||||
row_children.push(widget);
|
||||
}
|
||||
RowChildren::Col {
|
||||
ratio,
|
||||
child: children,
|
||||
} => {
|
||||
let col_ratio = ratio.unwrap_or(1);
|
||||
let mut col_children = vec![];
|
||||
|
||||
let inner_col_total_ratio =
|
||||
children.iter().map(|w| w.ratio.unwrap_or(1)).sum();
|
||||
for widget in children {
|
||||
let widget_type = widget.widget_type.parse::<BottomWidgetType>()?;
|
||||
let height = widget.ratio.unwrap_or(1);
|
||||
|
||||
if let Some(default_widget_type_val) = default_widget_type {
|
||||
if default_widget_type_val == widget_type
|
||||
&& default_widget_count > 0
|
||||
{
|
||||
default_widget_count -= 1;
|
||||
if default_widget_count == 0 {
|
||||
default_widget_id = iter_id;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Check default flag
|
||||
if let Some(default_widget_flag) = widget.default {
|
||||
if default_widget_flag {
|
||||
default_widget_id = iter_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let widget = new_widget(
|
||||
&mut layout,
|
||||
widget_type,
|
||||
&mut iter_id,
|
||||
height,
|
||||
inner_col_total_ratio,
|
||||
left_legend,
|
||||
);
|
||||
|
||||
col_children.push(widget);
|
||||
}
|
||||
|
||||
row_children.push(layout.add_container(Container::col(
|
||||
col_children,
|
||||
LayoutConstraint::Ratio {
|
||||
a: col_ratio,
|
||||
b: rows_total_ratio,
|
||||
},
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
outer_col_children.push(layout.add_container(Container::row(
|
||||
row_children,
|
||||
LayoutConstraint::Ratio {
|
||||
a: row_ratio,
|
||||
b: outer_col_total_ratio,
|
||||
},
|
||||
)));
|
||||
};
|
||||
}
|
||||
|
||||
layout.add_container(Container::col(
|
||||
outer_col_children,
|
||||
LayoutConstraint::FlexGrow,
|
||||
));
|
||||
|
||||
if layout.widgets_len() > 0 {
|
||||
layout.get_movement_mappings();
|
||||
Ok((layout, default_widget_id))
|
||||
} else {
|
||||
Err(error::BottomError::ConfigError(
|
||||
"please have at least one widget under the '[[row]]' section.".to_string(),
|
||||
@ -133,153 +374,162 @@ impl BottomLayout {
|
||||
|
||||
/// Creates a new [`BottomLayout`] following the basic layout.
|
||||
pub fn new_basic(use_battery: bool) -> Self {
|
||||
let mut layout = BottomLayout::default();
|
||||
|
||||
let table_widgets = if use_battery {
|
||||
let disk_widget = BottomWidget::new_handled(BottomWidgetType::Disk, 4)
|
||||
.up_neighbour(Some(100))
|
||||
.left_neighbour(Some(8))
|
||||
.right_neighbour(Some(DEFAULT_WIDGET_ID + 2));
|
||||
|
||||
let proc_sort =
|
||||
BottomWidget::new_handled(BottomWidgetType::ProcSort, DEFAULT_WIDGET_ID + 2)
|
||||
let disk = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::Disk, 4)
|
||||
.up_neighbour(Some(100))
|
||||
.down_neighbour(Some(DEFAULT_WIDGET_ID + 1))
|
||||
.left_neighbour(Some(4))
|
||||
.right_neighbour(Some(DEFAULT_WIDGET_ID))
|
||||
.parent_reflector(Some((WidgetDirection::Right, 2)));
|
||||
.left_neighbour(Some(8))
|
||||
.right_neighbour(Some(DEFAULT_WIDGET_ID + 2)),
|
||||
);
|
||||
|
||||
let proc = BottomWidget::new_handled(BottomWidgetType::Proc, DEFAULT_WIDGET_ID)
|
||||
.up_neighbour(Some(100))
|
||||
.down_neighbour(Some(DEFAULT_WIDGET_ID + 1))
|
||||
.left_neighbour(Some(DEFAULT_WIDGET_ID + 2))
|
||||
.right_neighbour(Some(7));
|
||||
let proc = {
|
||||
let proc_sort = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::ProcSort, DEFAULT_WIDGET_ID + 2)
|
||||
.up_neighbour(Some(100))
|
||||
.down_neighbour(Some(DEFAULT_WIDGET_ID + 1))
|
||||
.left_neighbour(Some(4))
|
||||
.right_neighbour(Some(DEFAULT_WIDGET_ID))
|
||||
.parent_reflector(Some((WidgetDirection::Right, 2))),
|
||||
);
|
||||
|
||||
let proc_search =
|
||||
BottomWidget::new_handled(BottomWidgetType::ProcSearch, DEFAULT_WIDGET_ID + 1)
|
||||
.up_neighbour(Some(DEFAULT_WIDGET_ID))
|
||||
.left_neighbour(Some(4))
|
||||
.right_neighbour(Some(7))
|
||||
.parent_reflector(Some((WidgetDirection::Up, 1)));
|
||||
let main_proc = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::Proc, DEFAULT_WIDGET_ID)
|
||||
.up_neighbour(Some(100))
|
||||
.down_neighbour(Some(DEFAULT_WIDGET_ID + 1))
|
||||
.left_neighbour(Some(DEFAULT_WIDGET_ID + 2))
|
||||
.right_neighbour(Some(7)),
|
||||
);
|
||||
|
||||
let temp = BottomWidget::new_handled(BottomWidgetType::Temp, 7)
|
||||
.up_neighbour(Some(100))
|
||||
.left_neighbour(Some(DEFAULT_WIDGET_ID))
|
||||
.right_neighbour(Some(8));
|
||||
let proc_search = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::ProcSearch, DEFAULT_WIDGET_ID + 1)
|
||||
.up_neighbour(Some(DEFAULT_WIDGET_ID))
|
||||
.left_neighbour(Some(4))
|
||||
.right_neighbour(Some(7))
|
||||
.parent_reflector(Some((WidgetDirection::Up, 1))),
|
||||
);
|
||||
|
||||
let battery = BottomWidget::new_handled(BottomWidgetType::Battery, 8)
|
||||
.up_neighbour(Some(100))
|
||||
.left_neighbour(Some(7))
|
||||
.right_neighbour(Some(4));
|
||||
let top = layout.add_container(Container::row(
|
||||
vec![proc_sort, main_proc],
|
||||
LayoutConstraint::CanvasHandled,
|
||||
));
|
||||
layout.add_container(Container::col(
|
||||
vec![top, proc_search],
|
||||
LayoutConstraint::CanvasHandled,
|
||||
))
|
||||
};
|
||||
|
||||
vec![
|
||||
BottomCol::new(vec![
|
||||
BottomColRow::new(vec![disk_widget]).canvas_handle_height(true)
|
||||
])
|
||||
.canvas_handle_width(true),
|
||||
BottomCol::new(vec![
|
||||
BottomColRow::new(vec![proc_sort, proc])
|
||||
.canvas_handle_height(true)
|
||||
.total_widget_ratio(3),
|
||||
BottomColRow::new(vec![proc_search]).canvas_handle_height(true),
|
||||
])
|
||||
.canvas_handle_width(true),
|
||||
BottomCol::new(vec![
|
||||
BottomColRow::new(vec![temp]).canvas_handle_height(true)
|
||||
])
|
||||
.canvas_handle_width(true),
|
||||
BottomCol::new(vec![
|
||||
BottomColRow::new(vec![battery]).canvas_handle_height(true)
|
||||
])
|
||||
.canvas_handle_width(true),
|
||||
]
|
||||
let temp = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::Temp, 7)
|
||||
.up_neighbour(Some(100))
|
||||
.left_neighbour(Some(DEFAULT_WIDGET_ID))
|
||||
.right_neighbour(Some(8)),
|
||||
);
|
||||
|
||||
let battery = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::Battery, 8)
|
||||
.up_neighbour(Some(100))
|
||||
.left_neighbour(Some(7))
|
||||
.right_neighbour(Some(4)),
|
||||
);
|
||||
|
||||
layout.add_container(Container::row(
|
||||
vec![disk, proc, temp, battery],
|
||||
LayoutConstraint::CanvasHandled,
|
||||
))
|
||||
} else {
|
||||
let disk = BottomWidget::new_handled(BottomWidgetType::Disk, 4)
|
||||
.up_neighbour(Some(100))
|
||||
.left_neighbour(Some(7))
|
||||
.right_neighbour(Some(DEFAULT_WIDGET_ID + 2));
|
||||
|
||||
let proc_sort =
|
||||
BottomWidget::new_handled(BottomWidgetType::ProcSort, DEFAULT_WIDGET_ID + 2)
|
||||
let disk = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::Disk, 4)
|
||||
.up_neighbour(Some(100))
|
||||
.down_neighbour(Some(DEFAULT_WIDGET_ID + 1))
|
||||
.left_neighbour(Some(4))
|
||||
.right_neighbour(Some(DEFAULT_WIDGET_ID))
|
||||
.parent_reflector(Some((WidgetDirection::Right, 2)));
|
||||
.left_neighbour(Some(7))
|
||||
.right_neighbour(Some(DEFAULT_WIDGET_ID + 2)),
|
||||
);
|
||||
|
||||
let proc = BottomWidget::new_handled(BottomWidgetType::Proc, DEFAULT_WIDGET_ID)
|
||||
.up_neighbour(Some(100))
|
||||
.down_neighbour(Some(DEFAULT_WIDGET_ID + 1))
|
||||
.left_neighbour(Some(DEFAULT_WIDGET_ID + 2))
|
||||
.right_neighbour(Some(7));
|
||||
let proc = {
|
||||
let proc_sort = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::ProcSort, DEFAULT_WIDGET_ID + 2)
|
||||
.up_neighbour(Some(100))
|
||||
.down_neighbour(Some(DEFAULT_WIDGET_ID + 1))
|
||||
.left_neighbour(Some(4))
|
||||
.right_neighbour(Some(DEFAULT_WIDGET_ID))
|
||||
.parent_reflector(Some((WidgetDirection::Right, 2))),
|
||||
);
|
||||
|
||||
let proc_search =
|
||||
BottomWidget::new_handled(BottomWidgetType::ProcSearch, DEFAULT_WIDGET_ID + 1)
|
||||
.up_neighbour(Some(DEFAULT_WIDGET_ID))
|
||||
.left_neighbour(Some(4))
|
||||
.right_neighbour(Some(7))
|
||||
.parent_reflector(Some((WidgetDirection::Up, 1)));
|
||||
let main_proc = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::Proc, DEFAULT_WIDGET_ID)
|
||||
.up_neighbour(Some(100))
|
||||
.down_neighbour(Some(DEFAULT_WIDGET_ID + 1))
|
||||
.left_neighbour(Some(DEFAULT_WIDGET_ID + 2))
|
||||
.right_neighbour(Some(7)),
|
||||
);
|
||||
|
||||
let temp = BottomWidget::new_handled(BottomWidgetType::Temp, 7)
|
||||
.up_neighbour(Some(100))
|
||||
.left_neighbour(Some(DEFAULT_WIDGET_ID))
|
||||
.right_neighbour(Some(4));
|
||||
let proc_search = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::ProcSearch, DEFAULT_WIDGET_ID + 1)
|
||||
.up_neighbour(Some(DEFAULT_WIDGET_ID))
|
||||
.left_neighbour(Some(4))
|
||||
.right_neighbour(Some(7))
|
||||
.parent_reflector(Some((WidgetDirection::Up, 1))),
|
||||
);
|
||||
|
||||
vec![
|
||||
BottomCol::new(vec![
|
||||
BottomColRow::new(vec![disk]).canvas_handle_height(true)
|
||||
])
|
||||
.canvas_handle_width(true),
|
||||
BottomCol::new(vec![
|
||||
BottomColRow::new(vec![proc_sort, proc]).canvas_handle_height(true),
|
||||
BottomColRow::new(vec![proc_search]).canvas_handle_height(true),
|
||||
])
|
||||
.canvas_handle_width(true),
|
||||
BottomCol::new(vec![
|
||||
BottomColRow::new(vec![temp]).canvas_handle_height(true)
|
||||
])
|
||||
.canvas_handle_width(true),
|
||||
]
|
||||
let top = layout.add_container(Container::row(
|
||||
vec![proc_sort, main_proc],
|
||||
LayoutConstraint::CanvasHandled,
|
||||
));
|
||||
layout.add_container(Container::col(
|
||||
vec![top, proc_search],
|
||||
LayoutConstraint::CanvasHandled,
|
||||
))
|
||||
};
|
||||
|
||||
let temp = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::Temp, 7)
|
||||
.up_neighbour(Some(100))
|
||||
.left_neighbour(Some(DEFAULT_WIDGET_ID))
|
||||
.right_neighbour(Some(4)),
|
||||
);
|
||||
|
||||
layout.add_container(Container::row(
|
||||
vec![disk, proc, temp],
|
||||
LayoutConstraint::CanvasHandled,
|
||||
))
|
||||
};
|
||||
|
||||
let cpu = BottomWidget::new_handled(BottomWidgetType::BasicCpu, 1).down_neighbour(Some(2));
|
||||
let cpu = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::BasicCpu, 1).down_neighbour(Some(2)),
|
||||
);
|
||||
|
||||
let mem = BottomWidget::new_handled(BottomWidgetType::BasicMem, 2)
|
||||
.up_neighbour(Some(1))
|
||||
.down_neighbour(Some(100))
|
||||
.right_neighbour(Some(3));
|
||||
let mem = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::BasicMem, 2)
|
||||
.up_neighbour(Some(1))
|
||||
.down_neighbour(Some(100))
|
||||
.right_neighbour(Some(3)),
|
||||
);
|
||||
|
||||
let net = BottomWidget::new_handled(BottomWidgetType::BasicNet, 3)
|
||||
.up_neighbour(Some(1))
|
||||
.down_neighbour(Some(100))
|
||||
.left_neighbour(Some(2));
|
||||
let net = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::BasicNet, 3)
|
||||
.up_neighbour(Some(1))
|
||||
.down_neighbour(Some(100))
|
||||
.left_neighbour(Some(2)),
|
||||
);
|
||||
|
||||
let table =
|
||||
BottomWidget::new_handled(BottomWidgetType::BasicTables, 100).up_neighbour(Some(2));
|
||||
let net = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::BasicTables, 100).up_neighbour(Some(2)),
|
||||
);
|
||||
|
||||
let mut layout = BottomLayout::default();
|
||||
// TODO: Add nodes; should we instead back with a hashmap?
|
||||
let middle_bars = layout.add_container(Container::row(
|
||||
vec![mem, net],
|
||||
LayoutConstraint::CanvasHandled,
|
||||
));
|
||||
|
||||
// BottomLayout {
|
||||
// total_row_height_ratio: 3,
|
||||
// rows: vec![
|
||||
// BottomRow::new(vec![BottomCol::new(vec![
|
||||
// BottomColRow::new(vec![cpu]).canvas_handle_height(true)
|
||||
// ])
|
||||
// .canvas_handle_width(true)])
|
||||
// .canvas_handle_height(true),
|
||||
// BottomRow::new(vec![BottomCol::new(vec![BottomColRow::new(vec![
|
||||
// mem, net,
|
||||
// ])
|
||||
// .canvas_handle_height(true)])
|
||||
// .canvas_handle_width(true)])
|
||||
// .canvas_handle_height(true),
|
||||
// BottomRow::new(vec![BottomCol::new(vec![
|
||||
// BottomColRow::new(vec![table]).canvas_handle_height(true)
|
||||
// ])
|
||||
// .canvas_handle_width(true)])
|
||||
// .canvas_handle_height(true),
|
||||
// BottomRow::new(table_widgets).canvas_handle_height(true),
|
||||
// ],
|
||||
// }
|
||||
let table = layout.add_widget(
|
||||
BottomWidget::new_handled(BottomWidgetType::BasicTables, 100).up_neighbour(Some(2)),
|
||||
);
|
||||
|
||||
layout.add_container(Container::col(
|
||||
vec![cpu, middle_bars, table, table_widgets],
|
||||
LayoutConstraint::CanvasHandled,
|
||||
));
|
||||
|
||||
layout
|
||||
}
|
||||
@ -1000,7 +1250,7 @@ impl BottomWidget {
|
||||
Self::new(
|
||||
widget_type,
|
||||
widget_id,
|
||||
LayoutConstraint::Ratio { lhs: 1, rhs: 1 },
|
||||
LayoutConstraint::Ratio { a: 1, b: 1 },
|
||||
)
|
||||
}
|
||||
|
||||
@ -1036,7 +1286,7 @@ impl BottomWidget {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash, Default)]
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Default)]
|
||||
pub enum BottomWidgetType {
|
||||
#[default]
|
||||
Empty,
|
||||
|
@ -13,7 +13,7 @@ use tui::{
|
||||
use crate::{
|
||||
app::{
|
||||
self,
|
||||
layout_manager::{BottomColRow, BottomLayout, BottomWidget, BottomWidgetType, Node},
|
||||
layout_manager::{BottomColRow, BottomLayout, BottomWidget, BottomWidgetType, NodeId},
|
||||
App,
|
||||
},
|
||||
constants::*,
|
||||
@ -72,7 +72,7 @@ pub struct Painter {
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum LayoutConstraint {
|
||||
/// Denotes that the canvas should follow the given ratio of `lhs:rhs` to determine spacing for the element.
|
||||
Ratio { lhs: u32, rhs: u32 },
|
||||
Ratio { a: u32, b: u32 },
|
||||
|
||||
/// Denotes that the canvas should let this element grow to take up whatever remaining space is left after
|
||||
/// sizing the other sibling elements.
|
||||
@ -94,7 +94,7 @@ impl Painter {
|
||||
width: 0,
|
||||
styled_help_text: Vec::default(),
|
||||
widget_layout,
|
||||
derived_widget_draw_locs: Vec::default(),
|
||||
derived_widget_draw_locs: HashMap::default(),
|
||||
};
|
||||
|
||||
painter.complete_painter_init();
|
||||
@ -496,7 +496,7 @@ impl Painter {
|
||||
constraints.zip(sizes.iter_mut()).enumerate()
|
||||
{
|
||||
match constraint {
|
||||
LayoutConstraint::Ratio { lhs, rhs } => {
|
||||
LayoutConstraint::Ratio { a: lhs, b: rhs } => {
|
||||
match direction {
|
||||
Direction::Horizontal => {
|
||||
let amount = (((area.width as u32) * lhs) / rhs) as u16;
|
||||
@ -612,45 +612,60 @@ impl Painter {
|
||||
}
|
||||
|
||||
// Do a preorder traversal through the tree in, and calculate the draw [`Rect`]s for each widget.
|
||||
let root_id = self.widget_layout.len().saturating_sub(1);
|
||||
let mut queue = vec![(root_id, terminal_size)];
|
||||
while let Some((current_id, rect)) = queue.pop() {
|
||||
if let Some(widget) = self.widget_layout.get_node(current_id) {
|
||||
match widget {
|
||||
Node::Container(container) => {
|
||||
let constraints = container.children.iter().map(|child| {
|
||||
if let Some(node) = self.widget_layout.get_node(*child) {
|
||||
node.constraint()
|
||||
} else {
|
||||
LayoutConstraint::FlexGrow
|
||||
}
|
||||
});
|
||||
|
||||
let rects =
|
||||
get_rects(container.direction().into(), constraints, rect);
|
||||
|
||||
// If it's a container, push in reverse order to the stack.
|
||||
for child in container
|
||||
.children
|
||||
.iter()
|
||||
.cloned()
|
||||
.zip(rects.into_iter())
|
||||
.rev()
|
||||
if let Some(root_id) = self.widget_layout.root_id() {
|
||||
let mut queue = vec![(root_id, terminal_size)];
|
||||
while let Some((current_id, rect)) = queue.pop() {
|
||||
match current_id {
|
||||
NodeId::Container(current_id) => {
|
||||
if let Some(container) =
|
||||
self.widget_layout.get_container(current_id)
|
||||
{
|
||||
queue.push(child);
|
||||
let constraints = container.children.iter().map(|child| {
|
||||
match child {
|
||||
NodeId::Container(child) => self
|
||||
.widget_layout
|
||||
.get_container(*child)
|
||||
.map(|c| c.constraint),
|
||||
NodeId::Widget(child) => self
|
||||
.widget_layout
|
||||
.get_widget(*child)
|
||||
.map(|w| w.constraint),
|
||||
}
|
||||
.unwrap_or(LayoutConstraint::FlexGrow)
|
||||
});
|
||||
|
||||
let rects = get_rects(
|
||||
container.direction().into(),
|
||||
constraints,
|
||||
rect,
|
||||
);
|
||||
|
||||
// If it's a container, push in reverse order to the stack.
|
||||
for child in container
|
||||
.children
|
||||
.iter()
|
||||
.cloned()
|
||||
.zip(rects.into_iter())
|
||||
.rev()
|
||||
{
|
||||
queue.push(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
Node::Widget(widget) => {
|
||||
// If we're instead on a widget, we can instead assign the rect to the widget.
|
||||
self.derived_widget_draw_locs.insert(current_id, rect);
|
||||
NodeId::Widget(current_id) => {
|
||||
if let Some(widget) = self.widget_layout.get_widget(current_id)
|
||||
{
|
||||
// If we're instead on a widget, we can instead assign the rect to the widget.
|
||||
self.derived_widget_draw_locs.insert(current_id, rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (id, rect) in &self.derived_widget_draw_locs {
|
||||
match &self.widget_layout.get_node(*id) {
|
||||
Some(Node::Widget(widget)) => {
|
||||
match self.widget_layout.get_widget(*id) {
|
||||
Some(widget) => {
|
||||
self.draw_widget(f, app_state, widget, *rect);
|
||||
}
|
||||
_ => {
|
||||
|
228
src/options.rs
228
src/options.rs
@ -274,116 +274,110 @@ pub fn build_app(
|
||||
is_command: is_default_command,
|
||||
};
|
||||
|
||||
for row in &widget_layout.rows {
|
||||
for col in &row.children {
|
||||
for col_row in &col.children {
|
||||
for widget in &col_row.children {
|
||||
widget_map.insert(widget.widget_id, widget.clone());
|
||||
if let Some(default_widget_type) = &default_widget_type_option {
|
||||
if !is_custom_layout || use_basic_mode {
|
||||
match widget.widget_type {
|
||||
BasicCpu => {
|
||||
if let Cpu = *default_widget_type {
|
||||
initial_widget_id = widget.widget_id;
|
||||
initial_widget_type = Cpu;
|
||||
}
|
||||
}
|
||||
BasicMem => {
|
||||
if let Mem = *default_widget_type {
|
||||
initial_widget_id = widget.widget_id;
|
||||
initial_widget_type = Cpu;
|
||||
}
|
||||
}
|
||||
BasicNet => {
|
||||
if let Net = *default_widget_type {
|
||||
initial_widget_id = widget.widget_id;
|
||||
initial_widget_type = Cpu;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if *default_widget_type == widget.widget_type {
|
||||
initial_widget_id = widget.widget_id;
|
||||
initial_widget_type = widget.widget_type.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Determine the initial widget ID/type + initialize states.
|
||||
for widget in widget_layout.widgets_iter() {
|
||||
widget_map.insert(widget.widget_id, widget.clone());
|
||||
if let Some(default_widget_type) = &default_widget_type_option {
|
||||
if !is_custom_layout || use_basic_mode {
|
||||
match widget.widget_type {
|
||||
BasicCpu => {
|
||||
if let Cpu = *default_widget_type {
|
||||
initial_widget_id = widget.widget_id;
|
||||
initial_widget_type = Cpu;
|
||||
}
|
||||
}
|
||||
|
||||
used_widget_set.insert(widget.widget_type.clone());
|
||||
|
||||
match widget.widget_type {
|
||||
Cpu => {
|
||||
cpu_state_map.insert(
|
||||
widget.widget_id,
|
||||
CpuWidgetState::new(
|
||||
&app_config_fields,
|
||||
default_time_value,
|
||||
autohide_timer,
|
||||
styling,
|
||||
),
|
||||
);
|
||||
BasicMem => {
|
||||
if let Mem = *default_widget_type {
|
||||
initial_widget_id = widget.widget_id;
|
||||
initial_widget_type = Cpu;
|
||||
}
|
||||
Mem => {
|
||||
mem_state_map.insert(
|
||||
widget.widget_id,
|
||||
MemWidgetState::init(default_time_value, autohide_timer),
|
||||
);
|
||||
}
|
||||
BasicNet => {
|
||||
if let Net = *default_widget_type {
|
||||
initial_widget_id = widget.widget_id;
|
||||
initial_widget_type = Cpu;
|
||||
}
|
||||
Net => {
|
||||
net_state_map.insert(
|
||||
widget.widget_id,
|
||||
NetWidgetState::init(default_time_value, autohide_timer),
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
if *default_widget_type == widget.widget_type {
|
||||
initial_widget_id = widget.widget_id;
|
||||
initial_widget_type = widget.widget_type.clone();
|
||||
}
|
||||
Proc => {
|
||||
let mode = if is_grouped {
|
||||
ProcWidgetMode::Grouped
|
||||
} else if is_default_tree {
|
||||
ProcWidgetMode::Tree {
|
||||
collapsed_pids: Default::default(),
|
||||
}
|
||||
} else {
|
||||
ProcWidgetMode::Normal
|
||||
};
|
||||
|
||||
proc_state_map.insert(
|
||||
widget.widget_id,
|
||||
ProcWidgetState::new(
|
||||
&app_config_fields,
|
||||
mode,
|
||||
table_config,
|
||||
styling,
|
||||
&proc_columns,
|
||||
),
|
||||
);
|
||||
}
|
||||
Disk => {
|
||||
disk_state_map.insert(
|
||||
widget.widget_id,
|
||||
DiskTableWidget::new(&app_config_fields, styling),
|
||||
);
|
||||
}
|
||||
Temp => {
|
||||
temp_state_map.insert(
|
||||
widget.widget_id,
|
||||
TempWidgetState::new(&app_config_fields, styling),
|
||||
);
|
||||
}
|
||||
Battery => {
|
||||
battery_state_map
|
||||
.insert(widget.widget_id, BatteryWidgetState::default());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
used_widget_set.insert(widget.widget_type.clone());
|
||||
|
||||
match widget.widget_type {
|
||||
Cpu => {
|
||||
cpu_state_map.insert(
|
||||
widget.widget_id,
|
||||
CpuWidgetState::new(
|
||||
&app_config_fields,
|
||||
default_time_value,
|
||||
autohide_timer,
|
||||
styling,
|
||||
),
|
||||
);
|
||||
}
|
||||
Mem => {
|
||||
mem_state_map.insert(
|
||||
widget.widget_id,
|
||||
MemWidgetState::init(default_time_value, autohide_timer),
|
||||
);
|
||||
}
|
||||
Net => {
|
||||
net_state_map.insert(
|
||||
widget.widget_id,
|
||||
NetWidgetState::init(default_time_value, autohide_timer),
|
||||
);
|
||||
}
|
||||
Proc => {
|
||||
let mode = if is_grouped {
|
||||
ProcWidgetMode::Grouped
|
||||
} else if is_default_tree {
|
||||
ProcWidgetMode::Tree {
|
||||
collapsed_pids: Default::default(),
|
||||
}
|
||||
} else {
|
||||
ProcWidgetMode::Normal
|
||||
};
|
||||
|
||||
proc_state_map.insert(
|
||||
widget.widget_id,
|
||||
ProcWidgetState::new(
|
||||
&app_config_fields,
|
||||
mode,
|
||||
table_config,
|
||||
styling,
|
||||
&proc_columns,
|
||||
),
|
||||
);
|
||||
}
|
||||
Disk => {
|
||||
disk_state_map.insert(
|
||||
widget.widget_id,
|
||||
DiskTableWidget::new(&app_config_fields, styling),
|
||||
);
|
||||
}
|
||||
Temp => {
|
||||
temp_state_map.insert(
|
||||
widget.widget_id,
|
||||
TempWidgetState::new(&app_config_fields, styling),
|
||||
);
|
||||
}
|
||||
Battery => {
|
||||
battery_state_map.insert(widget.widget_id, BatteryWidgetState::default());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let basic_table_widget_state = if use_basic_mode {
|
||||
Some(match initial_widget_type {
|
||||
Proc | Disk | Temp => BasicTableWidgetState {
|
||||
Proc | Disk | Temp | Battery => BasicTableWidgetState {
|
||||
currently_displayed_widget_type: initial_widget_type,
|
||||
currently_displayed_widget_id: initial_widget_id,
|
||||
widget_id: 100,
|
||||
@ -464,14 +458,15 @@ pub fn get_widget_layout(
|
||||
) -> error::Result<(BottomLayout, u64, Option<BottomWidgetType>)> {
|
||||
let left_legend = is_flag_enabled!(left_legend, matches, config);
|
||||
|
||||
let (default_widget_type, mut default_widget_count) =
|
||||
let (default_widget_type, default_widget_count) =
|
||||
get_default_widget_and_count(matches, config)?;
|
||||
let mut default_widget_id = 1;
|
||||
|
||||
let bottom_layout = if is_flag_enabled!(basic, matches, config) {
|
||||
default_widget_id = DEFAULT_WIDGET_ID;
|
||||
|
||||
BottomLayout::new_basic(get_use_battery(matches, config))
|
||||
if is_flag_enabled!(basic, matches, config) {
|
||||
Ok((
|
||||
BottomLayout::new_basic(get_use_battery(matches, config)),
|
||||
DEFAULT_WIDGET_ID,
|
||||
default_widget_type,
|
||||
))
|
||||
} else {
|
||||
let ref_row: Vec<Row>; // Required to handle reference
|
||||
let rows = match &config.row {
|
||||
@ -489,30 +484,11 @@ pub fn get_widget_layout(
|
||||
}
|
||||
};
|
||||
|
||||
let mut iter_id = 0; // A lazy way of forcing unique IDs *shrugs*
|
||||
let mut total_height_ratio = 0;
|
||||
let (layout, default_widget_id) =
|
||||
BottomLayout::from_rows(rows, default_widget_type, default_widget_count, left_legend)?;
|
||||
|
||||
// let mut ret_bottom_layout = BottomLayout {
|
||||
// arena: todo!(),
|
||||
// arena: rows
|
||||
// .iter()
|
||||
// .map(|row| {
|
||||
// row.convert_row_to_bottom_row(
|
||||
// &mut iter_id,
|
||||
// &mut total_height_ratio,
|
||||
// &mut default_widget_id,
|
||||
// &default_widget_type,
|
||||
// &mut default_widget_count,
|
||||
// left_legend,
|
||||
// )
|
||||
// })
|
||||
// .collect::<error::Result<Vec<_>>>()?,
|
||||
// };
|
||||
|
||||
BottomLayout::from_rows(rows)?
|
||||
};
|
||||
|
||||
Ok((bottom_layout, default_widget_id, default_widget_type))
|
||||
Ok((layout, default_widget_id, default_widget_type))
|
||||
}
|
||||
}
|
||||
|
||||
fn get_update_rate_in_milliseconds(matches: &ArgMatches, config: &Config) -> error::Result<u64> {
|
||||
|
@ -1,9 +1,6 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::app::layout_manager::*;
|
||||
use crate::error::Result;
|
||||
|
||||
/// Represents a row. This has a length of some sort (optional) and a vector
|
||||
/// Represents a row. This has a length of some sort (optional) and a vector
|
||||
/// of children.
|
||||
#[derive(Clone, Deserialize, Debug, Serialize)]
|
||||
#[serde(rename = "row")]
|
||||
@ -12,209 +9,9 @@ pub struct Row {
|
||||
pub child: Option<Vec<RowChildren>>,
|
||||
}
|
||||
|
||||
fn new_cpu(left_legend: bool, iter_id: &mut u64) -> BottomColRow {
|
||||
let cpu_id = *iter_id;
|
||||
*iter_id += 1;
|
||||
let legend_id = *iter_id;
|
||||
|
||||
if left_legend {
|
||||
BottomColRow::new(vec![
|
||||
BottomWidget::new_handled(BottomWidgetType::CpuLegend, legend_id)
|
||||
.parent_reflector(Some((WidgetDirection::Right, 1))),
|
||||
BottomWidget::new_handled(BottomWidgetType::Cpu, cpu_id),
|
||||
])
|
||||
} else {
|
||||
BottomColRow::new(vec![
|
||||
BottomWidget::new_handled(BottomWidgetType::Cpu, cpu_id),
|
||||
BottomWidget::new_handled(BottomWidgetType::CpuLegend, legend_id)
|
||||
.parent_reflector(Some((WidgetDirection::Left, 1))),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
fn new_proc_sort(sort_id: u64) -> BottomWidget {
|
||||
BottomWidget::new_handled(BottomWidgetType::ProcSort, sort_id)
|
||||
.parent_reflector(Some((WidgetDirection::Right, 2)))
|
||||
}
|
||||
|
||||
fn new_proc(proc_id: u64) -> BottomWidget {
|
||||
BottomWidget::new_fill(BottomWidgetType::Proc, proc_id)
|
||||
}
|
||||
|
||||
fn new_proc_search(search_id: u64) -> BottomWidget {
|
||||
BottomWidget::new_fill(BottomWidgetType::ProcSearch, search_id)
|
||||
.parent_reflector(Some((WidgetDirection::Up, 1)))
|
||||
}
|
||||
|
||||
impl Row {
|
||||
pub fn convert_row_to_bottom_row(
|
||||
&self, iter_id: &mut u64, total_height_ratio: &mut u32, default_widget_id: &mut u64,
|
||||
default_widget_type: &Option<BottomWidgetType>, default_widget_count: &mut u64,
|
||||
left_legend: bool,
|
||||
) -> Result<BottomRow> {
|
||||
// TODO: In the future we want to also add percentages.
|
||||
// But for MVP, we aren't going to bother.
|
||||
let row_ratio = self.ratio.unwrap_or(1);
|
||||
let mut children = Vec::new();
|
||||
|
||||
*total_height_ratio += row_ratio;
|
||||
|
||||
let mut total_col_ratio = 0;
|
||||
if let Some(row_children) = &self.child {
|
||||
for row_child in row_children {
|
||||
match row_child {
|
||||
RowChildren::Widget(widget) => {
|
||||
*iter_id += 1;
|
||||
let width_ratio = widget.ratio.unwrap_or(1);
|
||||
total_col_ratio += width_ratio;
|
||||
let widget_type = widget.widget_type.parse::<BottomWidgetType>()?;
|
||||
|
||||
if let Some(default_widget_type_val) = default_widget_type {
|
||||
if *default_widget_type_val == widget_type && *default_widget_count > 0
|
||||
{
|
||||
*default_widget_count -= 1;
|
||||
if *default_widget_count == 0 {
|
||||
*default_widget_id = *iter_id;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Check default flag
|
||||
if let Some(default_widget_flag) = widget.default {
|
||||
if default_widget_flag {
|
||||
*default_widget_id = *iter_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
children.push(match widget_type {
|
||||
BottomWidgetType::Cpu => {
|
||||
BottomCol::new(vec![new_cpu(left_legend, iter_id)])
|
||||
.col_width_ratio(width_ratio)
|
||||
}
|
||||
BottomWidgetType::Proc => {
|
||||
let proc_id = *iter_id;
|
||||
let proc_search_id = *iter_id + 1;
|
||||
*iter_id += 2;
|
||||
BottomCol::new(vec![
|
||||
BottomColRow::new(vec![
|
||||
new_proc_sort(*iter_id),
|
||||
new_proc(proc_id),
|
||||
])
|
||||
.total_widget_ratio(3)
|
||||
.flex_grow(true),
|
||||
BottomColRow::new(vec![new_proc_search(proc_search_id)])
|
||||
.canvas_handle_height(true),
|
||||
])
|
||||
.total_col_row_ratio(2)
|
||||
.col_width_ratio(width_ratio)
|
||||
}
|
||||
_ => BottomCol::new(vec![BottomColRow::new(vec![
|
||||
BottomWidget::new_fill(widget_type, *iter_id),
|
||||
])])
|
||||
.col_width_ratio(width_ratio),
|
||||
});
|
||||
}
|
||||
RowChildren::Col { ratio, child } => {
|
||||
let col_width_ratio = ratio.unwrap_or(1);
|
||||
total_col_ratio += col_width_ratio;
|
||||
let mut total_col_row_ratio = 0;
|
||||
let mut contains_proc = false;
|
||||
|
||||
let mut col_row_children: Vec<BottomColRow> = Vec::new();
|
||||
|
||||
for widget in child {
|
||||
let widget_type = widget.widget_type.parse::<BottomWidgetType>()?;
|
||||
*iter_id += 1;
|
||||
let col_row_height_ratio = widget.ratio.unwrap_or(1);
|
||||
total_col_row_ratio += col_row_height_ratio;
|
||||
|
||||
if let Some(default_widget_type_val) = default_widget_type {
|
||||
if *default_widget_type_val == widget_type
|
||||
&& *default_widget_count > 0
|
||||
{
|
||||
*default_widget_count -= 1;
|
||||
if *default_widget_count == 0 {
|
||||
*default_widget_id = *iter_id;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Check default flag
|
||||
if let Some(default_widget_flag) = widget.default {
|
||||
if default_widget_flag {
|
||||
*default_widget_id = *iter_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match widget_type {
|
||||
BottomWidgetType::Cpu => {
|
||||
col_row_children.push(
|
||||
new_cpu(left_legend, iter_id)
|
||||
.col_row_height_ratio(col_row_height_ratio),
|
||||
);
|
||||
}
|
||||
BottomWidgetType::Proc => {
|
||||
contains_proc = true;
|
||||
let proc_id = *iter_id;
|
||||
let proc_search_id = *iter_id + 1;
|
||||
*iter_id += 2;
|
||||
col_row_children.push(
|
||||
BottomColRow::new(vec![
|
||||
new_proc_sort(*iter_id),
|
||||
new_proc(proc_id),
|
||||
])
|
||||
.col_row_height_ratio(col_row_height_ratio)
|
||||
.total_widget_ratio(3),
|
||||
);
|
||||
col_row_children.push(
|
||||
BottomColRow::new(vec![new_proc_search(proc_search_id)])
|
||||
.canvas_handle_height(true)
|
||||
.col_row_height_ratio(col_row_height_ratio),
|
||||
);
|
||||
}
|
||||
_ => col_row_children.push(
|
||||
BottomColRow::new(vec![BottomWidget::new_fill(
|
||||
widget_type,
|
||||
*iter_id,
|
||||
)])
|
||||
.col_row_height_ratio(col_row_height_ratio),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
if contains_proc {
|
||||
// Must adjust ratios to work with proc
|
||||
total_col_row_ratio *= 2;
|
||||
for child in &mut col_row_children {
|
||||
// Multiply all non-proc or proc-search ratios by 2
|
||||
if !child.children.is_empty() {
|
||||
match child.children[0].widget_type {
|
||||
BottomWidgetType::ProcSearch => {}
|
||||
_ => child.col_row_height_ratio *= 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
children.push(
|
||||
BottomCol::new(col_row_children)
|
||||
.total_col_row_ratio(total_col_row_ratio)
|
||||
.col_width_ratio(col_width_ratio),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(BottomRow::new(children)
|
||||
.total_col_ratio(total_col_ratio)
|
||||
.row_height_ratio(row_ratio))
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a child of a Row - either a Col (column) or a FinalWidget.
|
||||
///
|
||||
/// A Col can also have an optional length and children. We only allow columns
|
||||
/// A Col can also have an optional length and children. We only allow columns
|
||||
/// to have FinalWidgets as children, lest we get some amount of mutual
|
||||
/// recursion between Row and Col.
|
||||
#[derive(Clone, Deserialize, Debug, Serialize)]
|
||||
|
@ -1,469 +1,469 @@
|
||||
//! Mocks layout management, so we can check if we broke anything.
|
||||
// //! Mocks layout management, so we can check if we broke anything.
|
||||
|
||||
use bottom::app::layout_manager::{BottomLayout, BottomWidgetType};
|
||||
#[cfg(feature = "battery")]
|
||||
use bottom::constants::DEFAULT_BATTERY_LAYOUT;
|
||||
use bottom::constants::{DEFAULT_LAYOUT, DEFAULT_WIDGET_ID};
|
||||
use bottom::options::{layout_options::Row, Config};
|
||||
use bottom::utils::error;
|
||||
use toml_edit::de::from_str;
|
||||
// use bottom::app::layout_manager::{BottomLayout, BottomWidgetType};
|
||||
// #[cfg(feature = "battery")]
|
||||
// use bottom::constants::DEFAULT_BATTERY_LAYOUT;
|
||||
// use bottom::constants::{DEFAULT_LAYOUT, DEFAULT_WIDGET_ID};
|
||||
// use bottom::options::{layout_options::Row, Config};
|
||||
// use bottom::utils::error;
|
||||
// use toml_edit::de::from_str;
|
||||
|
||||
// FIXME: Move these into the library!
|
||||
// // FIXME: Move these tests into the library!
|
||||
|
||||
const PROC_LAYOUT: &str = r##"
|
||||
[[row]]
|
||||
[[row.child]]
|
||||
type="proc"
|
||||
[[row]]
|
||||
[[row.child]]
|
||||
type="proc"
|
||||
[[row.child]]
|
||||
type="proc"
|
||||
[[row]]
|
||||
[[row.child]]
|
||||
type="proc"
|
||||
[[row.child]]
|
||||
type="proc"
|
||||
"##;
|
||||
// const PROC_LAYOUT: &str = r##"
|
||||
// [[row]]
|
||||
// [[row.child]]
|
||||
// type="proc"
|
||||
// [[row]]
|
||||
// [[row.child]]
|
||||
// type="proc"
|
||||
// [[row.child]]
|
||||
// type="proc"
|
||||
// [[row]]
|
||||
// [[row.child]]
|
||||
// type="proc"
|
||||
// [[row.child]]
|
||||
// type="proc"
|
||||
// "##;
|
||||
|
||||
fn test_create_layout(
|
||||
rows: &[Row], default_widget_id: u64, default_widget_type: Option<BottomWidgetType>,
|
||||
default_widget_count: u64, left_legend: bool,
|
||||
) -> BottomLayout {
|
||||
let mut iter_id = 0; // A lazy way of forcing unique IDs *shrugs*
|
||||
let mut total_height_ratio = 0;
|
||||
let mut default_widget_count = default_widget_count;
|
||||
let mut default_widget_id = default_widget_id;
|
||||
// fn test_create_layout(
|
||||
// rows: &[Row], default_widget_id: u64, default_widget_type: Option<BottomWidgetType>,
|
||||
// default_widget_count: u64, left_legend: bool,
|
||||
// ) -> BottomLayout {
|
||||
// let mut iter_id = 0; // A lazy way of forcing unique IDs *shrugs*
|
||||
// let mut total_height_ratio = 0;
|
||||
// let mut default_widget_count = default_widget_count;
|
||||
// let mut default_widget_id = default_widget_id;
|
||||
|
||||
let mut ret_bottom_layout = BottomLayout {
|
||||
rows: rows
|
||||
.iter()
|
||||
.map(|row| {
|
||||
row.convert_row_to_bottom_row(
|
||||
&mut iter_id,
|
||||
&mut total_height_ratio,
|
||||
&mut default_widget_id,
|
||||
&default_widget_type,
|
||||
&mut default_widget_count,
|
||||
left_legend,
|
||||
)
|
||||
})
|
||||
.collect::<error::Result<Vec<_>>>()
|
||||
.unwrap(),
|
||||
total_row_height_ratio: total_height_ratio,
|
||||
};
|
||||
ret_bottom_layout.get_movement_mappings();
|
||||
// let mut ret_bottom_layout = BottomLayout {
|
||||
// rows: rows
|
||||
// .iter()
|
||||
// .map(|row| {
|
||||
// row.convert_row_to_bottom_row(
|
||||
// &mut iter_id,
|
||||
// &mut total_height_ratio,
|
||||
// &mut default_widget_id,
|
||||
// &default_widget_type,
|
||||
// &mut default_widget_count,
|
||||
// left_legend,
|
||||
// )
|
||||
// })
|
||||
// .collect::<error::Result<Vec<_>>>()
|
||||
// .unwrap(),
|
||||
// total_row_height_ratio: total_height_ratio,
|
||||
// };
|
||||
// ret_bottom_layout.get_movement_mappings();
|
||||
|
||||
ret_bottom_layout
|
||||
}
|
||||
// ret_bottom_layout
|
||||
// }
|
||||
|
||||
#[test]
|
||||
/// Tests the default setup.
|
||||
fn test_default_movement() {
|
||||
let rows = from_str::<Config>(DEFAULT_LAYOUT).unwrap().row.unwrap();
|
||||
let ret_bottom_layout = test_create_layout(&rows, DEFAULT_WIDGET_ID, None, 1, false);
|
||||
// #[test]
|
||||
// /// Tests the default setup.
|
||||
// fn test_default_movement() {
|
||||
// let rows = from_str::<Config>(DEFAULT_LAYOUT).unwrap().row.unwrap();
|
||||
// let ret_bottom_layout = test_create_layout(&rows, DEFAULT_WIDGET_ID, None, 1, false);
|
||||
|
||||
// Simple tests for the top CPU widget
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[0].down_neighbour,
|
||||
Some(3)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[0].right_neighbour,
|
||||
Some(2)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[0].left_neighbour,
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[0].up_neighbour,
|
||||
None
|
||||
);
|
||||
// // Simple tests for the top CPU widget
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[0].down_neighbour,
|
||||
// Some(3)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[0].right_neighbour,
|
||||
// Some(2)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[0].left_neighbour,
|
||||
// None
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[0].up_neighbour,
|
||||
// None
|
||||
// );
|
||||
|
||||
// Test CPU legend
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[1].down_neighbour,
|
||||
Some(4)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[1].right_neighbour,
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[1].left_neighbour,
|
||||
Some(1)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[1].up_neighbour,
|
||||
None
|
||||
);
|
||||
// // Test CPU legend
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[1].down_neighbour,
|
||||
// Some(4)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[1].right_neighbour,
|
||||
// None
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[1].left_neighbour,
|
||||
// Some(1)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[1].up_neighbour,
|
||||
// None
|
||||
// );
|
||||
|
||||
// Test memory->temp, temp->disk, disk->memory mappings
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[1].children[0].children[0].children[0].right_neighbour,
|
||||
Some(4)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[1].children[1].children[0].children[0].down_neighbour,
|
||||
Some(5)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[1].children[1].children[1].children[0].left_neighbour,
|
||||
Some(3)
|
||||
);
|
||||
// // Test memory->temp, temp->disk, disk->memory mappings
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[1].children[0].children[0].children[0].right_neighbour,
|
||||
// Some(4)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[1].children[1].children[0].children[0].down_neighbour,
|
||||
// Some(5)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[1].children[1].children[1].children[0].left_neighbour,
|
||||
// Some(3)
|
||||
// );
|
||||
|
||||
// Test disk -> processes, processes -> process sort, process sort -> network
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[1].children[1].children[1].children[0].down_neighbour,
|
||||
Some(7)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[2].children[1].children[0].children[1].left_neighbour,
|
||||
Some(9)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[2].children[1].children[0].children[0].left_neighbour,
|
||||
Some(6)
|
||||
);
|
||||
}
|
||||
// // Test disk -> processes, processes -> process sort, process sort -> network
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[1].children[1].children[1].children[0].down_neighbour,
|
||||
// Some(7)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[2].children[1].children[0].children[1].left_neighbour,
|
||||
// Some(9)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[2].children[1].children[0].children[0].left_neighbour,
|
||||
// Some(6)
|
||||
// );
|
||||
// }
|
||||
|
||||
#[cfg(feature = "battery")]
|
||||
#[test]
|
||||
/// Tests battery movement in the default setup.
|
||||
fn test_default_battery_movement() {
|
||||
let rows = from_str::<Config>(DEFAULT_BATTERY_LAYOUT)
|
||||
.unwrap()
|
||||
.row
|
||||
.unwrap();
|
||||
let ret_bottom_layout = test_create_layout(&rows, DEFAULT_WIDGET_ID, None, 1, false);
|
||||
// #[cfg(feature = "battery")]
|
||||
// #[test]
|
||||
// /// Tests battery movement in the default setup.
|
||||
// fn test_default_battery_movement() {
|
||||
// let rows = from_str::<Config>(DEFAULT_BATTERY_LAYOUT)
|
||||
// .unwrap()
|
||||
// .row
|
||||
// .unwrap();
|
||||
// let ret_bottom_layout = test_create_layout(&rows, DEFAULT_WIDGET_ID, None, 1, false);
|
||||
|
||||
// Simple tests for the top CPU widget
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[0].down_neighbour,
|
||||
Some(4)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[0].right_neighbour,
|
||||
Some(2)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[0].left_neighbour,
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[0].up_neighbour,
|
||||
None
|
||||
);
|
||||
// // Simple tests for the top CPU widget
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[0].down_neighbour,
|
||||
// Some(4)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[0].right_neighbour,
|
||||
// Some(2)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[0].left_neighbour,
|
||||
// None
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[0].up_neighbour,
|
||||
// None
|
||||
// );
|
||||
|
||||
// Test CPU legend
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[1].down_neighbour,
|
||||
Some(5)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[1].right_neighbour,
|
||||
Some(3)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[1].left_neighbour,
|
||||
Some(1)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[1].up_neighbour,
|
||||
None
|
||||
);
|
||||
}
|
||||
// // Test CPU legend
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[1].down_neighbour,
|
||||
// Some(5)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[1].right_neighbour,
|
||||
// Some(3)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[1].left_neighbour,
|
||||
// Some(1)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[1].up_neighbour,
|
||||
// None
|
||||
// );
|
||||
// }
|
||||
|
||||
#[test]
|
||||
/// Tests using left_legend.
|
||||
fn test_left_legend() {
|
||||
let rows = from_str::<Config>(DEFAULT_LAYOUT).unwrap().row.unwrap();
|
||||
let ret_bottom_layout = test_create_layout(&rows, DEFAULT_WIDGET_ID, None, 1, true);
|
||||
// #[test]
|
||||
// /// Tests using left_legend.
|
||||
// fn test_left_legend() {
|
||||
// let rows = from_str::<Config>(DEFAULT_LAYOUT).unwrap().row.unwrap();
|
||||
// let ret_bottom_layout = test_create_layout(&rows, DEFAULT_WIDGET_ID, None, 1, true);
|
||||
|
||||
// Legend
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[0].down_neighbour,
|
||||
Some(3)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[0].right_neighbour,
|
||||
Some(1)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[0].left_neighbour,
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[0].up_neighbour,
|
||||
None
|
||||
);
|
||||
// // Legend
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[0].down_neighbour,
|
||||
// Some(3)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[0].right_neighbour,
|
||||
// Some(1)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[0].left_neighbour,
|
||||
// None
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[0].up_neighbour,
|
||||
// None
|
||||
// );
|
||||
|
||||
// Widget
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[1].down_neighbour,
|
||||
Some(3)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[1].right_neighbour,
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[1].left_neighbour,
|
||||
Some(2)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[1].up_neighbour,
|
||||
None
|
||||
);
|
||||
}
|
||||
// // Widget
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[1].down_neighbour,
|
||||
// Some(3)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[1].right_neighbour,
|
||||
// None
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[1].left_neighbour,
|
||||
// Some(2)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[1].up_neighbour,
|
||||
// None
|
||||
// );
|
||||
// }
|
||||
|
||||
#[test]
|
||||
/// Tests explicit default widget.
|
||||
fn test_default_widget_in_layout() {
|
||||
let proc_layout = r##"
|
||||
[[row]]
|
||||
[[row.child]]
|
||||
type="proc"
|
||||
[[row]]
|
||||
[[row.child]]
|
||||
type="proc"
|
||||
[[row.child]]
|
||||
type="proc"
|
||||
[[row]]
|
||||
[[row.child]]
|
||||
type="proc"
|
||||
default=true
|
||||
[[row.child]]
|
||||
type="proc"
|
||||
"##;
|
||||
let rows = from_str::<Config>(proc_layout).unwrap().row.unwrap();
|
||||
let mut iter_id = 0; // A lazy way of forcing unique IDs *shrugs*
|
||||
let mut total_height_ratio = 0;
|
||||
let mut default_widget_count = 1;
|
||||
let mut default_widget_id = DEFAULT_WIDGET_ID;
|
||||
let default_widget_type = None;
|
||||
let left_legend = false;
|
||||
// #[test]
|
||||
// /// Tests explicit default widget.
|
||||
// fn test_default_widget_in_layout() {
|
||||
// let proc_layout = r##"
|
||||
// [[row]]
|
||||
// [[row.child]]
|
||||
// type="proc"
|
||||
// [[row]]
|
||||
// [[row.child]]
|
||||
// type="proc"
|
||||
// [[row.child]]
|
||||
// type="proc"
|
||||
// [[row]]
|
||||
// [[row.child]]
|
||||
// type="proc"
|
||||
// default=true
|
||||
// [[row.child]]
|
||||
// type="proc"
|
||||
// "##;
|
||||
// let rows = from_str::<Config>(proc_layout).unwrap().row.unwrap();
|
||||
// let mut iter_id = 0; // A lazy way of forcing unique IDs *shrugs*
|
||||
// let mut total_height_ratio = 0;
|
||||
// let mut default_widget_count = 1;
|
||||
// let mut default_widget_id = DEFAULT_WIDGET_ID;
|
||||
// let default_widget_type = None;
|
||||
// let left_legend = false;
|
||||
|
||||
let mut ret_bottom_layout = BottomLayout {
|
||||
rows: rows
|
||||
.iter()
|
||||
.map(|row| {
|
||||
row.convert_row_to_bottom_row(
|
||||
&mut iter_id,
|
||||
&mut total_height_ratio,
|
||||
&mut default_widget_id,
|
||||
&default_widget_type,
|
||||
&mut default_widget_count,
|
||||
left_legend,
|
||||
)
|
||||
})
|
||||
.collect::<error::Result<Vec<_>>>()
|
||||
.unwrap(),
|
||||
total_row_height_ratio: total_height_ratio,
|
||||
};
|
||||
ret_bottom_layout.get_movement_mappings();
|
||||
// let mut ret_bottom_layout = BottomLayout {
|
||||
// rows: rows
|
||||
// .iter()
|
||||
// .map(|row| {
|
||||
// row.convert_row_to_bottom_row(
|
||||
// &mut iter_id,
|
||||
// &mut total_height_ratio,
|
||||
// &mut default_widget_id,
|
||||
// &default_widget_type,
|
||||
// &mut default_widget_count,
|
||||
// left_legend,
|
||||
// )
|
||||
// })
|
||||
// .collect::<error::Result<Vec<_>>>()
|
||||
// .unwrap(),
|
||||
// total_row_height_ratio: total_height_ratio,
|
||||
// };
|
||||
// ret_bottom_layout.get_movement_mappings();
|
||||
|
||||
assert_eq!(default_widget_id, 10);
|
||||
}
|
||||
// assert_eq!(default_widget_id, 10);
|
||||
// }
|
||||
|
||||
#[test]
|
||||
/// Tests default widget by setting type and count.
|
||||
fn test_default_widget_by_option() {
|
||||
let rows = from_str::<Config>(PROC_LAYOUT).unwrap().row.unwrap();
|
||||
let mut iter_id = 0; // A lazy way of forcing unique IDs *shrugs*
|
||||
let mut total_height_ratio = 0;
|
||||
let mut default_widget_count = 3;
|
||||
let mut default_widget_id = DEFAULT_WIDGET_ID;
|
||||
let default_widget_type = Some(BottomWidgetType::Proc);
|
||||
let left_legend = false;
|
||||
// #[test]
|
||||
// /// Tests default widget by setting type and count.
|
||||
// fn test_default_widget_by_option() {
|
||||
// let rows = from_str::<Config>(PROC_LAYOUT).unwrap().row.unwrap();
|
||||
// let mut iter_id = 0; // A lazy way of forcing unique IDs *shrugs*
|
||||
// let mut total_height_ratio = 0;
|
||||
// let mut default_widget_count = 3;
|
||||
// let mut default_widget_id = DEFAULT_WIDGET_ID;
|
||||
// let default_widget_type = Some(BottomWidgetType::Proc);
|
||||
// let left_legend = false;
|
||||
|
||||
let mut ret_bottom_layout = BottomLayout {
|
||||
rows: rows
|
||||
.iter()
|
||||
.map(|row| {
|
||||
row.convert_row_to_bottom_row(
|
||||
&mut iter_id,
|
||||
&mut total_height_ratio,
|
||||
&mut default_widget_id,
|
||||
&default_widget_type,
|
||||
&mut default_widget_count,
|
||||
left_legend,
|
||||
)
|
||||
})
|
||||
.collect::<error::Result<Vec<_>>>()
|
||||
.unwrap(),
|
||||
total_row_height_ratio: total_height_ratio,
|
||||
};
|
||||
ret_bottom_layout.get_movement_mappings();
|
||||
// let mut ret_bottom_layout = BottomLayout {
|
||||
// rows: rows
|
||||
// .iter()
|
||||
// .map(|row| {
|
||||
// row.convert_row_to_bottom_row(
|
||||
// &mut iter_id,
|
||||
// &mut total_height_ratio,
|
||||
// &mut default_widget_id,
|
||||
// &default_widget_type,
|
||||
// &mut default_widget_count,
|
||||
// left_legend,
|
||||
// )
|
||||
// })
|
||||
// .collect::<error::Result<Vec<_>>>()
|
||||
// .unwrap(),
|
||||
// total_row_height_ratio: total_height_ratio,
|
||||
// };
|
||||
// ret_bottom_layout.get_movement_mappings();
|
||||
|
||||
assert_eq!(default_widget_id, 7);
|
||||
}
|
||||
// assert_eq!(default_widget_id, 7);
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn test_proc_custom_layout() {
|
||||
let rows = from_str::<Config>(PROC_LAYOUT).unwrap().row.unwrap();
|
||||
let ret_bottom_layout = test_create_layout(&rows, DEFAULT_WIDGET_ID, None, 1, false);
|
||||
// #[test]
|
||||
// fn test_proc_custom_layout() {
|
||||
// let rows = from_str::<Config>(PROC_LAYOUT).unwrap().row.unwrap();
|
||||
// let ret_bottom_layout = test_create_layout(&rows, DEFAULT_WIDGET_ID, None, 1, false);
|
||||
|
||||
// First proc widget
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[1].down_neighbour,
|
||||
Some(2)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[1].left_neighbour,
|
||||
Some(3)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[1].right_neighbour,
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[1].up_neighbour,
|
||||
None
|
||||
);
|
||||
// // First proc widget
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[1].down_neighbour,
|
||||
// Some(2)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[1].left_neighbour,
|
||||
// Some(3)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[1].right_neighbour,
|
||||
// None
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[1].up_neighbour,
|
||||
// None
|
||||
// );
|
||||
|
||||
// Its search
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[1].children[0].down_neighbour,
|
||||
Some(4)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[1].children[0].left_neighbour,
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[1].children[0].right_neighbour,
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[1].children[0].up_neighbour,
|
||||
Some(1)
|
||||
);
|
||||
// // Its search
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[1].children[0].down_neighbour,
|
||||
// Some(4)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[1].children[0].left_neighbour,
|
||||
// None
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[1].children[0].right_neighbour,
|
||||
// None
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[1].children[0].up_neighbour,
|
||||
// Some(1)
|
||||
// );
|
||||
|
||||
// Its sort
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[0].down_neighbour,
|
||||
Some(2)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[0].left_neighbour,
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[0].right_neighbour,
|
||||
Some(1)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[0].children[0].children[0].children[0].up_neighbour,
|
||||
None
|
||||
);
|
||||
// // Its sort
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[0].down_neighbour,
|
||||
// Some(2)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[0].left_neighbour,
|
||||
// None
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[0].right_neighbour,
|
||||
// Some(1)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[0].children[0].children[0].children[0].up_neighbour,
|
||||
// None
|
||||
// );
|
||||
|
||||
// Let us now test the second row's first widget...
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[1].children[0].children[0].children[1].down_neighbour,
|
||||
Some(5)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[1].children[0].children[0].children[1].left_neighbour,
|
||||
Some(6)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[1].children[0].children[0].children[1].right_neighbour,
|
||||
Some(9)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[1].children[0].children[0].children[1].up_neighbour,
|
||||
Some(2)
|
||||
);
|
||||
// // Let us now test the second row's first widget...
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[1].children[0].children[0].children[1].down_neighbour,
|
||||
// Some(5)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[1].children[0].children[0].children[1].left_neighbour,
|
||||
// Some(6)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[1].children[0].children[0].children[1].right_neighbour,
|
||||
// Some(9)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[1].children[0].children[0].children[1].up_neighbour,
|
||||
// Some(2)
|
||||
// );
|
||||
|
||||
// Sort
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[1].children[0].children[0].children[0].down_neighbour,
|
||||
Some(5)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[1].children[0].children[0].children[0].left_neighbour,
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[1].children[0].children[0].children[0].right_neighbour,
|
||||
Some(4)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[1].children[0].children[0].children[0].up_neighbour,
|
||||
Some(2)
|
||||
);
|
||||
// // Sort
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[1].children[0].children[0].children[0].down_neighbour,
|
||||
// Some(5)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[1].children[0].children[0].children[0].left_neighbour,
|
||||
// None
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[1].children[0].children[0].children[0].right_neighbour,
|
||||
// Some(4)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[1].children[0].children[0].children[0].up_neighbour,
|
||||
// Some(2)
|
||||
// );
|
||||
|
||||
// Search
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[1].children[0].children[1].children[0].down_neighbour,
|
||||
Some(10)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[1].children[0].children[1].children[0].left_neighbour,
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[1].children[0].children[1].children[0].right_neighbour,
|
||||
Some(8)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[1].children[0].children[1].children[0].up_neighbour,
|
||||
Some(4)
|
||||
);
|
||||
// // Search
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[1].children[0].children[1].children[0].down_neighbour,
|
||||
// Some(10)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[1].children[0].children[1].children[0].left_neighbour,
|
||||
// None
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[1].children[0].children[1].children[0].right_neighbour,
|
||||
// Some(8)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[1].children[0].children[1].children[0].up_neighbour,
|
||||
// Some(4)
|
||||
// );
|
||||
|
||||
// Third row, second
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[2].children[1].children[0].children[1].down_neighbour,
|
||||
Some(14)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[2].children[1].children[0].children[1].left_neighbour,
|
||||
Some(15)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[2].children[1].children[0].children[1].right_neighbour,
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[2].children[1].children[0].children[1].up_neighbour,
|
||||
Some(8)
|
||||
);
|
||||
// // Third row, second
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[2].children[1].children[0].children[1].down_neighbour,
|
||||
// Some(14)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[2].children[1].children[0].children[1].left_neighbour,
|
||||
// Some(15)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[2].children[1].children[0].children[1].right_neighbour,
|
||||
// None
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[2].children[1].children[0].children[1].up_neighbour,
|
||||
// Some(8)
|
||||
// );
|
||||
|
||||
// Sort
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[2].children[1].children[0].children[0].down_neighbour,
|
||||
Some(14)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[2].children[1].children[0].children[0].left_neighbour,
|
||||
Some(10)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[2].children[1].children[0].children[0].right_neighbour,
|
||||
Some(13)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[2].children[1].children[0].children[0].up_neighbour,
|
||||
Some(8)
|
||||
);
|
||||
// // Sort
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[2].children[1].children[0].children[0].down_neighbour,
|
||||
// Some(14)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[2].children[1].children[0].children[0].left_neighbour,
|
||||
// Some(10)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[2].children[1].children[0].children[0].right_neighbour,
|
||||
// Some(13)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[2].children[1].children[0].children[0].up_neighbour,
|
||||
// Some(8)
|
||||
// );
|
||||
|
||||
// Search
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[2].children[1].children[1].children[0].down_neighbour,
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[2].children[1].children[1].children[0].left_neighbour,
|
||||
Some(11)
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[2].children[1].children[1].children[0].right_neighbour,
|
||||
None
|
||||
);
|
||||
assert_eq!(
|
||||
ret_bottom_layout.rows[2].children[1].children[1].children[0].up_neighbour,
|
||||
Some(13)
|
||||
);
|
||||
}
|
||||
// // Search
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[2].children[1].children[1].children[0].down_neighbour,
|
||||
// None
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[2].children[1].children[1].children[0].left_neighbour,
|
||||
// Some(11)
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[2].children[1].children[1].children[0].right_neighbour,
|
||||
// None
|
||||
// );
|
||||
// assert_eq!(
|
||||
// ret_bottom_layout.rows[2].children[1].children[1].children[0].up_neighbour,
|
||||
// Some(13)
|
||||
// );
|
||||
// }
|
||||
|
Loading…
x
Reference in New Issue
Block a user