Files
bottom/src/options/layout_options.rs
T
Clement Tsang 99fc5fc2c8 refactor: run cargo +nightly fmt with group_imports (#885)
* refactor: add some disabled unstable fmt options

* run cargo +nightly fmt with group_imports

* separate out the cfg-specific imports for clarity
2022-11-10 01:22:19 -05:00

356 lines
19 KiB
Rust

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
/// of children.
#[derive(Clone, Deserialize, Debug, Serialize)]
#[serde(rename = "row")]
pub struct Row {
pub ratio: Option<u32>,
pub child: Option<Vec<RowChildren>>,
}
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 => {
let cpu_id = *iter_id;
*iter_id += 1;
BottomCol::builder()
.col_width_ratio(width_ratio)
.children(if left_legend {
vec![BottomColRow::builder()
.total_widget_ratio(20)
.children(vec![
BottomWidget::builder()
.width_ratio(3)
.widget_type(BottomWidgetType::CpuLegend)
.widget_id(*iter_id)
.canvas_handle_width(true)
.parent_reflector(Some((
WidgetDirection::Right,
1,
)))
.build(),
BottomWidget::builder()
.width_ratio(17)
.widget_type(BottomWidgetType::Cpu)
.widget_id(cpu_id)
.flex_grow(true)
.build(),
])
.build()]
} else {
vec![BottomColRow::builder()
.total_widget_ratio(20)
.children(vec![
BottomWidget::builder()
.width_ratio(17)
.widget_type(BottomWidgetType::Cpu)
.widget_id(cpu_id)
.flex_grow(true)
.build(),
BottomWidget::builder()
.width_ratio(3)
.widget_type(BottomWidgetType::CpuLegend)
.widget_id(*iter_id)
.canvas_handle_width(true)
.parent_reflector(Some((
WidgetDirection::Left,
1,
)))
.build(),
])
.build()]
})
.build()
}
BottomWidgetType::Proc => {
let proc_id = *iter_id;
let proc_search_id = *iter_id + 1;
*iter_id += 2;
BottomCol::builder()
.total_col_row_ratio(2)
.col_width_ratio(width_ratio)
.children(vec![
BottomColRow::builder()
.children(vec![
BottomWidget::builder()
.widget_type(BottomWidgetType::ProcSort)
.widget_id(*iter_id)
.canvas_handle_width(true)
.parent_reflector(Some((
WidgetDirection::Right,
2,
)))
.width_ratio(1)
.build(),
BottomWidget::builder()
.widget_type(BottomWidgetType::Proc)
.widget_id(proc_id)
.width_ratio(2)
.build(),
])
.total_widget_ratio(3)
.flex_grow(true)
.build(),
BottomColRow::builder()
.children(vec![BottomWidget::builder()
.widget_type(BottomWidgetType::ProcSearch)
.widget_id(proc_search_id)
.parent_reflector(Some((WidgetDirection::Up, 1)))
.build()])
.canvas_handle_height(true)
.build(),
])
.build()
}
_ => BottomCol::builder()
.col_width_ratio(width_ratio)
.children(vec![BottomColRow::builder()
.children(vec![BottomWidget::builder()
.widget_type(widget_type)
.widget_id(*iter_id)
.build()])
.build()])
.build(),
});
}
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 => {
let cpu_id = *iter_id;
*iter_id += 1;
if left_legend {
col_row_children.push(
BottomColRow::builder()
.col_row_height_ratio(col_row_height_ratio)
.total_widget_ratio(20)
.children(vec![
BottomWidget::builder()
.width_ratio(3)
.widget_type(BottomWidgetType::CpuLegend)
.widget_id(*iter_id)
.canvas_handle_width(true)
.parent_reflector(Some((
WidgetDirection::Right,
1,
)))
.build(),
BottomWidget::builder()
.width_ratio(17)
.widget_type(BottomWidgetType::Cpu)
.widget_id(cpu_id)
.flex_grow(true)
.build(),
])
.build(),
);
} else {
col_row_children.push(
BottomColRow::builder()
.col_row_height_ratio(col_row_height_ratio)
.total_widget_ratio(20)
.children(vec![
BottomWidget::builder()
.width_ratio(17)
.widget_type(BottomWidgetType::Cpu)
.widget_id(cpu_id)
.flex_grow(true)
.build(),
BottomWidget::builder()
.width_ratio(3)
.widget_type(BottomWidgetType::CpuLegend)
.widget_id(*iter_id)
.canvas_handle_width(true)
.parent_reflector(Some((
WidgetDirection::Left,
1,
)))
.build(),
])
.build(),
);
}
}
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::builder()
.children(vec![
BottomWidget::builder()
.widget_type(BottomWidgetType::ProcSort)
.widget_id(*iter_id)
.canvas_handle_width(true)
.parent_reflector(Some((
WidgetDirection::Right,
2,
)))
.width_ratio(1)
.build(),
BottomWidget::builder()
.widget_type(BottomWidgetType::Proc)
.widget_id(proc_id)
.width_ratio(2)
.build(),
])
.col_row_height_ratio(col_row_height_ratio)
.total_widget_ratio(3)
.build(),
);
col_row_children.push(
BottomColRow::builder()
.col_row_height_ratio(col_row_height_ratio)
.children(vec![BottomWidget::builder()
.widget_type(BottomWidgetType::ProcSearch)
.widget_id(proc_search_id)
.parent_reflector(Some((WidgetDirection::Up, 1)))
.build()])
.canvas_handle_height(true)
.build(),
);
}
_ => col_row_children.push(
BottomColRow::builder()
.col_row_height_ratio(col_row_height_ratio)
.children(vec![BottomWidget::builder()
.widget_type(widget_type)
.widget_id(*iter_id)
.build()])
.build(),
),
}
}
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::builder()
.total_col_row_ratio(total_col_row_ratio)
.col_width_ratio(col_width_ratio)
.children(col_row_children)
.build(),
);
}
}
}
}
Ok(BottomRow::builder()
.total_col_ratio(total_col_ratio)
.row_height_ratio(row_ratio)
.children(children)
.build())
}
}
/// 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
/// to have FinalWidgets as children, lest we get some amount of mutual
/// recursion between Row and Col.
#[derive(Clone, Deserialize, Debug, Serialize)]
#[serde(untagged)]
pub enum RowChildren {
Widget(FinalWidget),
Col {
ratio: Option<u32>,
child: Vec<FinalWidget>,
},
}
/// Represents a widget.
#[derive(Clone, Deserialize, Debug, Serialize)]
pub struct FinalWidget {
pub ratio: Option<u32>,
#[serde(rename = "type")]
pub widget_type: String,
pub default: Option<bool>,
}