Fix layout bugs

This commit is contained in:
ClementTsang 2021-12-30 22:40:00 -05:00
parent 3411d320c9
commit 93f936f369
24 changed files with 229 additions and 145 deletions

View File

@ -2,7 +2,7 @@ use crate::{
app::SelectableType, app::SelectableType,
data_conversion::ConvertedData, data_conversion::ConvertedData,
error::{BottomError, Result}, error::{BottomError, Result},
options::layout_options::{FinalWidget, LayoutRow, LayoutRowChild, LayoutRule}, options::layout_options::{FinalWidget, LayoutRow, LayoutRowChild, WidgetLayoutRule},
tuine::*, tuine::*,
}; };
use anyhow::anyhow; use anyhow::anyhow;
@ -101,7 +101,7 @@ Supported widget names:
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
pub struct RowLayout { pub struct RowLayout {
last_selected: Option<NodeId>, last_selected: Option<NodeId>,
pub parent_rule: LayoutRule, pub parent_rule: WidgetLayoutRule,
pub bound: Rect, pub bound: Rect,
} }
@ -109,7 +109,7 @@ pub struct RowLayout {
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
pub struct ColLayout { pub struct ColLayout {
last_selected: Option<NodeId>, last_selected: Option<NodeId>,
pub parent_rule: LayoutRule, pub parent_rule: WidgetLayoutRule,
pub bound: Rect, pub bound: Rect,
} }
@ -180,7 +180,7 @@ pub enum WidgetLayoutNode {
Widget { Widget {
widget_type: BottomWidgetType, widget_type: BottomWidgetType,
selected: bool, selected: bool,
rule: LayoutRule, rule: WidgetLayoutRule,
}, },
} }
@ -254,10 +254,10 @@ impl WidgetLayoutNode {
} }
} }
fn wrap_element<Message>(element: Element<Message>, rule: &LayoutRule) -> FlexElement<Message> { fn wrap_element<Message>(element: Element<Message>, rule: &WidgetLayoutRule) -> FlexElement<Message> {
match rule { match rule {
LayoutRule::Expand { ratio } => FlexElement::with_flex(element, *ratio), WidgetLayoutRule::Expand { ratio } => FlexElement::with_flex(element, *ratio),
LayoutRule::Length { width, height } => { WidgetLayoutRule::Length { width, height } => {
if width.is_some() || height.is_some() { if width.is_some() || height.is_some() {
FlexElement::with_no_flex( FlexElement::with_no_flex(
Container::with_child(element).width(*width).height(*height), Container::with_child(element).width(*width).height(*height),

View File

@ -7,7 +7,7 @@ use tui::{backend::Backend, layout::Rect, Frame};
use crate::{ use crate::{
app::event::{ComponentEventResult, SelectionAction}, app::event::{ComponentEventResult, SelectionAction},
canvas::Painter, canvas::Painter,
options::layout_options::LayoutRule, options::layout_options::WidgetLayoutRule,
}; };
mod tui_stuff; mod tui_stuff;
@ -133,10 +133,10 @@ pub trait Widget {
fn update_data(&mut self, data_collection: &DataCollection) {} fn update_data(&mut self, data_collection: &DataCollection) {}
/// Returns the desired width from the [`Widget`]. /// Returns the desired width from the [`Widget`].
fn width(&self) -> LayoutRule; fn width(&self) -> WidgetLayoutRule;
/// Returns the desired height from the [`Widget`]. /// Returns the desired height from the [`Widget`].
fn height(&self) -> LayoutRule; fn height(&self) -> WidgetLayoutRule;
/// Returns whether this [`Widget`] can be selected. The default implementation returns [`SelectableType::Selectable`]. /// Returns whether this [`Widget`] can be selected. The default implementation returns [`SelectableType::Selectable`].
fn selectable_type(&self) -> SelectableType { fn selectable_type(&self) -> SelectableType {

View File

@ -11,7 +11,7 @@ use crate::{
app::{widgets::tui_stuff::PipeGauge, AppConfig, Component, DataCollection, Widget}, app::{widgets::tui_stuff::PipeGauge, AppConfig, Component, DataCollection, Widget},
canvas::Painter, canvas::Painter,
constants::SIDE_BORDERS, constants::SIDE_BORDERS,
options::layout_options::LayoutRule, options::layout_options::WidgetLayoutRule,
}; };
const REQUIRED_COLUMNS: usize = 4; const REQUIRED_COLUMNS: usize = 4;
@ -20,7 +20,7 @@ const REQUIRED_COLUMNS: usize = 4;
pub struct BasicCpu { pub struct BasicCpu {
bounds: Rect, bounds: Rect,
display_data: Vec<(f64, String, String)>, display_data: Vec<(f64, String, String)>,
width: LayoutRule, width: WidgetLayoutRule,
showing_avg: bool, showing_avg: bool,
} }
@ -36,7 +36,7 @@ impl BasicCpu {
} }
/// Sets the width. /// Sets the width.
pub fn width(mut self, width: LayoutRule) -> Self { pub fn width(mut self, width: WidgetLayoutRule) -> Self {
self.width = width; self.width = width;
self self
} }
@ -184,11 +184,11 @@ impl Widget for BasicCpu {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
} }
fn width(&self) -> LayoutRule { fn width(&self) -> WidgetLayoutRule {
self.width self.width
} }
fn height(&self) -> LayoutRule { fn height(&self) -> WidgetLayoutRule {
let display_data_len = self.display_data.len(); let display_data_len = self.display_data.len();
let length = max( let length = max(
1, 1,

View File

@ -14,13 +14,13 @@ use crate::{
canvas::Painter, canvas::Painter,
constants::SIDE_BORDERS, constants::SIDE_BORDERS,
data_conversion::{convert_mem_data_points, convert_mem_labels, convert_swap_data_points}, data_conversion::{convert_mem_data_points, convert_mem_labels, convert_swap_data_points},
options::layout_options::LayoutRule, options::layout_options::WidgetLayoutRule,
}; };
#[derive(Debug)] #[derive(Debug)]
pub struct BasicMem { pub struct BasicMem {
bounds: Rect, bounds: Rect,
width: LayoutRule, width: WidgetLayoutRule,
mem_data: (f64, String, String), mem_data: (f64, String, String),
swap_data: Option<(f64, String, String)>, swap_data: Option<(f64, String, String)>,
use_percent: bool, use_percent: bool,
@ -40,7 +40,7 @@ impl Default for BasicMem {
impl BasicMem { impl BasicMem {
/// Sets the width. /// Sets the width.
pub fn width(mut self, width: LayoutRule) -> Self { pub fn width(mut self, width: WidgetLayoutRule) -> Self {
self.width = width; self.width = width;
self self
} }
@ -155,11 +155,11 @@ impl Widget for BasicMem {
}; };
} }
fn width(&self) -> LayoutRule { fn width(&self) -> WidgetLayoutRule {
self.width self.width
} }
fn height(&self) -> LayoutRule { fn height(&self) -> WidgetLayoutRule {
todo!() todo!()
} }
} }

View File

@ -11,14 +11,14 @@ use crate::{
canvas::Painter, canvas::Painter,
constants::SIDE_BORDERS, constants::SIDE_BORDERS,
data_conversion::convert_network_data_points, data_conversion::convert_network_data_points,
options::layout_options::LayoutRule, options::layout_options::WidgetLayoutRule,
units::data_units::DataUnit, units::data_units::DataUnit,
}; };
#[derive(Debug)] #[derive(Debug)]
pub struct BasicNet { pub struct BasicNet {
bounds: Rect, bounds: Rect,
width: LayoutRule, width: WidgetLayoutRule,
rx_display: String, rx_display: String,
tx_display: String, tx_display: String,
@ -45,7 +45,7 @@ impl BasicNet {
} }
/// Sets the width. /// Sets the width.
pub fn width(mut self, width: LayoutRule) -> Self { pub fn width(mut self, width: WidgetLayoutRule) -> Self {
self.width = width; self.width = width;
self self
} }
@ -124,11 +124,11 @@ impl Widget for BasicNet {
} }
} }
fn width(&self) -> LayoutRule { fn width(&self) -> WidgetLayoutRule {
self.width self.width
} }
fn height(&self) -> LayoutRule { fn height(&self) -> WidgetLayoutRule {
todo!() todo!()
} }
} }

View File

@ -17,7 +17,7 @@ use crate::{
canvas::Painter, canvas::Painter,
constants::TABLE_GAP_HEIGHT_LIMIT, constants::TABLE_GAP_HEIGHT_LIMIT,
data_conversion::{convert_battery_harvest, ConvertedBatteryData}, data_conversion::{convert_battery_harvest, ConvertedBatteryData},
options::layout_options::LayoutRule, options::layout_options::WidgetLayoutRule,
}; };
/// A table displaying battery information on a per-battery basis. /// A table displaying battery information on a per-battery basis.
@ -25,8 +25,8 @@ pub struct BatteryTable {
bounds: Rect, bounds: Rect,
selected_index: usize, selected_index: usize,
battery_data: Vec<ConvertedBatteryData>, battery_data: Vec<ConvertedBatteryData>,
width: LayoutRule, width: WidgetLayoutRule,
height: LayoutRule, height: WidgetLayoutRule,
block_border: Borders, block_border: Borders,
tab_bounds: Vec<Rect>, tab_bounds: Vec<Rect>,
} }
@ -37,8 +37,8 @@ impl Default for BatteryTable {
bounds: Default::default(), bounds: Default::default(),
selected_index: 0, selected_index: 0,
battery_data: Default::default(), battery_data: Default::default(),
width: LayoutRule::default(), width: WidgetLayoutRule::default(),
height: LayoutRule::default(), height: WidgetLayoutRule::default(),
block_border: Borders::ALL, block_border: Borders::ALL,
tab_bounds: Default::default(), tab_bounds: Default::default(),
} }
@ -47,13 +47,13 @@ impl Default for BatteryTable {
impl BatteryTable { impl BatteryTable {
/// Sets the width. /// Sets the width.
pub fn width(mut self, width: LayoutRule) -> Self { pub fn width(mut self, width: WidgetLayoutRule) -> Self {
self.width = width; self.width = width;
self self
} }
/// Sets the height. /// Sets the height.
pub fn height(mut self, height: LayoutRule) -> Self { pub fn height(mut self, height: WidgetLayoutRule) -> Self {
self.height = height; self.height = height;
self self
} }
@ -147,11 +147,11 @@ impl Widget for BatteryTable {
} }
} }
fn width(&self) -> LayoutRule { fn width(&self) -> WidgetLayoutRule {
self.width self.width
} }
fn height(&self) -> LayoutRule { fn height(&self) -> WidgetLayoutRule {
self.height self.height
} }

View File

@ -17,7 +17,7 @@ use crate::{
Component, Widget, Component, Widget,
}, },
canvas::Painter, canvas::Painter,
options::layout_options::LayoutRule, options::layout_options::WidgetLayoutRule,
}; };
/// A container that "holds" multiple [`BottomWidget`]s through their [`NodeId`]s. /// A container that "holds" multiple [`BottomWidget`]s through their [`NodeId`]s.
@ -26,8 +26,8 @@ pub struct Carousel {
index: usize, index: usize,
children: Vec<(NodeId, Cow<'static, str>)>, children: Vec<(NodeId, Cow<'static, str>)>,
bounds: Rect, bounds: Rect,
width: LayoutRule, width: WidgetLayoutRule,
height: LayoutRule, height: WidgetLayoutRule,
left_button_bounds: Rect, left_button_bounds: Rect,
right_button_bounds: Rect, right_button_bounds: Rect,
} }
@ -47,13 +47,13 @@ impl Carousel {
} }
/// Sets the width. /// Sets the width.
pub fn width(mut self, width: LayoutRule) -> Self { pub fn width(mut self, width: WidgetLayoutRule) -> Self {
self.width = width; self.width = width;
self self
} }
/// Sets the height. /// Sets the height.
pub fn height(mut self, height: LayoutRule) -> Self { pub fn height(mut self, height: WidgetLayoutRule) -> Self {
self.height = height; self.height = height;
self self
} }
@ -191,11 +191,11 @@ impl Widget for Carousel {
"Carousel" "Carousel"
} }
fn width(&self) -> LayoutRule { fn width(&self) -> WidgetLayoutRule {
self.width self.width
} }
fn height(&self) -> LayoutRule { fn height(&self) -> WidgetLayoutRule {
self.height self.height
} }

View File

@ -17,7 +17,7 @@ use crate::{
}, },
canvas::Painter, canvas::Painter,
data_conversion::{convert_cpu_data_points, ConvertedCpuData}, data_conversion::{convert_cpu_data_points, ConvertedCpuData},
options::layout_options::LayoutRule, options::layout_options::WidgetLayoutRule,
}; };
/// Which part of the [`CpuGraph`] is currently selected. /// Which part of the [`CpuGraph`] is currently selected.
@ -45,8 +45,8 @@ pub struct CpuGraph {
display_data: Vec<ConvertedCpuData>, display_data: Vec<ConvertedCpuData>,
load_avg_data: [f32; 3], load_avg_data: [f32; 3],
width: LayoutRule, width: WidgetLayoutRule,
height: LayoutRule, height: WidgetLayoutRule,
} }
impl CpuGraph { impl CpuGraph {
@ -75,19 +75,19 @@ impl CpuGraph {
selected: CpuGraphSelection::Graph, selected: CpuGraphSelection::Graph,
display_data: Default::default(), display_data: Default::default(),
load_avg_data: [0.0; 3], load_avg_data: [0.0; 3],
width: LayoutRule::default(), width: WidgetLayoutRule::default(),
height: LayoutRule::default(), height: WidgetLayoutRule::default(),
} }
} }
/// Sets the width. /// Sets the width.
pub fn width(mut self, width: LayoutRule) -> Self { pub fn width(mut self, width: WidgetLayoutRule) -> Self {
self.width = width; self.width = width;
self self
} }
/// Sets the height. /// Sets the height.
pub fn height(mut self, height: LayoutRule) -> Self { pub fn height(mut self, height: WidgetLayoutRule) -> Self {
self.height = height; self.height = height;
self self
} }
@ -281,11 +281,11 @@ impl Widget for CpuGraph {
self.load_avg_data = data_collection.load_avg_harvest; self.load_avg_data = data_collection.load_avg_harvest;
} }
fn width(&self) -> LayoutRule { fn width(&self) -> WidgetLayoutRule {
self.width self.width
} }
fn height(&self) -> LayoutRule { fn height(&self) -> WidgetLayoutRule {
self.height self.height
} }

View File

@ -9,7 +9,7 @@ use crate::{
}, },
canvas::Painter, canvas::Painter,
data_conversion::convert_disk_row, data_conversion::convert_disk_row,
options::layout_options::LayoutRule, options::layout_options::WidgetLayoutRule,
}; };
/// A table displaying disk data. /// A table displaying disk data.
@ -19,8 +19,8 @@ pub struct DiskTable {
display_data: TextTableData, display_data: TextTableData,
width: LayoutRule, width: WidgetLayoutRule,
height: LayoutRule, height: WidgetLayoutRule,
block_border: Borders, block_border: Borders,
show_scroll_index: bool, show_scroll_index: bool,
} }
@ -43,21 +43,21 @@ impl DiskTable {
table, table,
bounds: Rect::default(), bounds: Rect::default(),
display_data: Default::default(), display_data: Default::default(),
width: LayoutRule::default(), width: WidgetLayoutRule::default(),
height: LayoutRule::default(), height: WidgetLayoutRule::default(),
block_border: Borders::ALL, block_border: Borders::ALL,
show_scroll_index: false, show_scroll_index: false,
} }
} }
/// Sets the width. /// Sets the width.
pub fn width(mut self, width: LayoutRule) -> Self { pub fn width(mut self, width: WidgetLayoutRule) -> Self {
self.width = width; self.width = width;
self self
} }
/// Sets the height. /// Sets the height.
pub fn height(mut self, height: LayoutRule) -> Self { pub fn height(mut self, height: WidgetLayoutRule) -> Self {
self.height = height; self.height = height;
self self
} }
@ -126,11 +126,11 @@ impl Widget for DiskTable {
self.display_data = convert_disk_row(data_collection); self.display_data = convert_disk_row(data_collection);
} }
fn width(&self) -> LayoutRule { fn width(&self) -> WidgetLayoutRule {
self.width self.width
} }
fn height(&self) -> LayoutRule { fn height(&self) -> WidgetLayoutRule {
self.height self.height
} }
} }

View File

@ -2,32 +2,32 @@ use tui::layout::Rect;
use crate::{ use crate::{
app::{Component, SelectableType, Widget}, app::{Component, SelectableType, Widget},
options::layout_options::LayoutRule, options::layout_options::WidgetLayoutRule,
}; };
pub struct Empty { pub struct Empty {
width: LayoutRule, width: WidgetLayoutRule,
height: LayoutRule, height: WidgetLayoutRule,
} }
impl Default for Empty { impl Default for Empty {
fn default() -> Self { fn default() -> Self {
Self { Self {
width: LayoutRule::default(), width: WidgetLayoutRule::default(),
height: LayoutRule::default(), height: WidgetLayoutRule::default(),
} }
} }
} }
impl Empty { impl Empty {
/// Sets the width. /// Sets the width.
pub fn width(mut self, width: LayoutRule) -> Self { pub fn width(mut self, width: WidgetLayoutRule) -> Self {
self.width = width; self.width = width;
self self
} }
/// Sets the height. /// Sets the height.
pub fn height(mut self, height: LayoutRule) -> Self { pub fn height(mut self, height: WidgetLayoutRule) -> Self {
self.height = height; self.height = height;
self self
} }
@ -46,11 +46,11 @@ impl Widget for Empty {
"" ""
} }
fn width(&self) -> LayoutRule { fn width(&self) -> WidgetLayoutRule {
self.width self.width
} }
fn height(&self) -> LayoutRule { fn height(&self) -> WidgetLayoutRule {
self.height self.height
} }

View File

@ -7,7 +7,7 @@ use crate::{
app::{event::ComponentEventResult, time_graph::TimeGraphData, DataCollection}, app::{event::ComponentEventResult, time_graph::TimeGraphData, DataCollection},
app::{Component, TimeGraph, Widget}, app::{Component, TimeGraph, Widget},
data_conversion::{convert_mem_data_points, convert_mem_labels, convert_swap_data_points}, data_conversion::{convert_mem_data_points, convert_mem_labels, convert_swap_data_points},
options::layout_options::LayoutRule, options::layout_options::WidgetLayoutRule,
}; };
/// A widget that deals with displaying memory usage on a [`TimeGraph`]. Basically just a wrapper /// A widget that deals with displaying memory usage on a [`TimeGraph`]. Basically just a wrapper
@ -19,8 +19,8 @@ pub struct MemGraph {
mem_data: Vec<(f64, f64)>, mem_data: Vec<(f64, f64)>,
swap_data: Vec<(f64, f64)>, swap_data: Vec<(f64, f64)>,
bounds: Rect, bounds: Rect,
width: LayoutRule, width: WidgetLayoutRule,
height: LayoutRule, height: WidgetLayoutRule,
} }
impl MemGraph { impl MemGraph {
@ -33,19 +33,19 @@ impl MemGraph {
mem_data: Default::default(), mem_data: Default::default(),
swap_data: Default::default(), swap_data: Default::default(),
bounds: Rect::default(), bounds: Rect::default(),
width: LayoutRule::default(), width: WidgetLayoutRule::default(),
height: LayoutRule::default(), height: WidgetLayoutRule::default(),
} }
} }
/// Sets the width. /// Sets the width.
pub fn width(mut self, width: LayoutRule) -> Self { pub fn width(mut self, width: WidgetLayoutRule) -> Self {
self.width = width; self.width = width;
self self
} }
/// Sets the height. /// Sets the height.
pub fn height(mut self, height: LayoutRule) -> Self { pub fn height(mut self, height: WidgetLayoutRule) -> Self {
self.height = height; self.height = height;
self self
} }
@ -126,11 +126,11 @@ impl Widget for MemGraph {
self.swap_labels = swap_labels; self.swap_labels = swap_labels;
} }
fn width(&self) -> LayoutRule { fn width(&self) -> WidgetLayoutRule {
self.width self.width
} }
fn height(&self) -> LayoutRule { fn height(&self) -> WidgetLayoutRule {
self.height self.height
} }
} }

View File

@ -15,7 +15,7 @@ use crate::{
}, },
canvas::Painter, canvas::Painter,
data_conversion::convert_network_data_points, data_conversion::convert_network_data_points,
options::layout_options::LayoutRule, options::layout_options::WidgetLayoutRule,
units::data_units::DataUnit, units::data_units::DataUnit,
utils::gen_util::*, utils::gen_util::*,
}; };
@ -381,8 +381,8 @@ pub struct NetGraph {
hide_legend: bool, hide_legend: bool,
bounds: Rect, bounds: Rect,
width: LayoutRule, width: WidgetLayoutRule,
height: LayoutRule, height: WidgetLayoutRule,
} }
impl NetGraph { impl NetGraph {
@ -404,8 +404,8 @@ impl NetGraph {
use_binary_prefix: app_config_fields.network_use_binary_prefix, use_binary_prefix: app_config_fields.network_use_binary_prefix,
hide_legend: false, hide_legend: false,
bounds: Rect::default(), bounds: Rect::default(),
width: LayoutRule::default(), width: WidgetLayoutRule::default(),
height: LayoutRule::default(), height: WidgetLayoutRule::default(),
} }
} }
@ -416,13 +416,13 @@ impl NetGraph {
} }
/// Sets the width. /// Sets the width.
pub fn width(mut self, width: LayoutRule) -> Self { pub fn width(mut self, width: WidgetLayoutRule) -> Self {
self.width = width; self.width = width;
self self
} }
/// Sets the height. /// Sets the height.
pub fn height(mut self, height: LayoutRule) -> Self { pub fn height(mut self, height: WidgetLayoutRule) -> Self {
self.height = height; self.height = height;
self self
} }
@ -569,11 +569,11 @@ impl Widget for NetGraph {
} }
} }
fn width(&self) -> LayoutRule { fn width(&self) -> WidgetLayoutRule {
self.width self.width
} }
fn height(&self) -> LayoutRule { fn height(&self) -> WidgetLayoutRule {
self.height self.height
} }
} }
@ -584,8 +584,8 @@ pub struct OldNetGraph {
net_graph: NetGraph, net_graph: NetGraph,
table: TextTable, table: TextTable,
bounds: Rect, bounds: Rect,
width: LayoutRule, width: WidgetLayoutRule,
height: LayoutRule, height: WidgetLayoutRule,
} }
impl OldNetGraph { impl OldNetGraph {
@ -602,19 +602,19 @@ impl OldNetGraph {
.try_show_gap(config.table_gap) .try_show_gap(config.table_gap)
.unselectable(), .unselectable(),
bounds: Rect::default(), bounds: Rect::default(),
width: LayoutRule::default(), width: WidgetLayoutRule::default(),
height: LayoutRule::default(), height: WidgetLayoutRule::default(),
} }
} }
/// Sets the width. /// Sets the width.
pub fn width(mut self, width: LayoutRule) -> Self { pub fn width(mut self, width: WidgetLayoutRule) -> Self {
self.width = width; self.width = width;
self self
} }
/// Sets the height. /// Sets the height.
pub fn height(mut self, height: LayoutRule) -> Self { pub fn height(mut self, height: WidgetLayoutRule) -> Self {
self.height = height; self.height = height;
self self
} }
@ -709,11 +709,11 @@ impl Widget for OldNetGraph {
} }
} }
fn width(&self) -> LayoutRule { fn width(&self) -> WidgetLayoutRule {
self.width self.width
} }
fn height(&self) -> LayoutRule { fn height(&self) -> WidgetLayoutRule {
self.height self.height
} }
} }

View File

@ -26,7 +26,7 @@ use crate::{
}, },
canvas::Painter, canvas::Painter,
data_conversion::{get_string_with_bytes, get_string_with_bytes_per_second}, data_conversion::{get_string_with_bytes, get_string_with_bytes_per_second},
options::{layout_options::LayoutRule, ProcessDefaults}, options::{layout_options::WidgetLayoutRule, ProcessDefaults},
utils::error::BottomError, utils::error::BottomError,
Pid, Pid,
}; };
@ -271,8 +271,8 @@ pub struct ProcessManager {
display_data: TextTableData, display_data: TextTableData,
process_filter: Option<Result<Query, BottomError>>, process_filter: Option<Result<Query, BottomError>>,
block_border: Borders, block_border: Borders,
width: LayoutRule, width: WidgetLayoutRule,
height: LayoutRule, height: WidgetLayoutRule,
show_scroll_index: bool, show_scroll_index: bool,
} }
@ -311,8 +311,8 @@ impl ProcessManager {
display_data: Default::default(), display_data: Default::default(),
process_filter: None, process_filter: None,
block_border: Borders::ALL, block_border: Borders::ALL,
width: LayoutRule::default(), width: WidgetLayoutRule::default(),
height: LayoutRule::default(), height: WidgetLayoutRule::default(),
show_scroll_index: false, show_scroll_index: false,
}; };
@ -330,13 +330,13 @@ impl ProcessManager {
} }
/// Sets the width. /// Sets the width.
pub fn width(mut self, width: LayoutRule) -> Self { pub fn width(mut self, width: WidgetLayoutRule) -> Self {
self.width = width; self.width = width;
self self
} }
/// Sets the height. /// Sets the height.
pub fn height(mut self, height: LayoutRule) -> Self { pub fn height(mut self, height: WidgetLayoutRule) -> Self {
self.height = height; self.height = height;
self self
} }
@ -1362,11 +1362,11 @@ impl Widget for ProcessManager {
}; };
} }
fn width(&self) -> LayoutRule { fn width(&self) -> WidgetLayoutRule {
self.width self.width
} }
fn height(&self) -> LayoutRule { fn height(&self) -> WidgetLayoutRule {
self.height self.height
} }

View File

@ -9,7 +9,7 @@ use crate::{
}, },
canvas::Painter, canvas::Painter,
data_conversion::convert_temp_row, data_conversion::convert_temp_row,
options::layout_options::LayoutRule, options::layout_options::WidgetLayoutRule,
}; };
/// A table displaying temperature data. /// A table displaying temperature data.
@ -18,8 +18,8 @@ pub struct TempTable {
bounds: Rect, bounds: Rect,
display_data: TextTableData, display_data: TextTableData,
temp_type: TemperatureType, temp_type: TemperatureType,
width: LayoutRule, width: WidgetLayoutRule,
height: LayoutRule, height: WidgetLayoutRule,
block_border: Borders, block_border: Borders,
show_scroll_index: bool, show_scroll_index: bool,
} }
@ -39,8 +39,8 @@ impl TempTable {
bounds: Rect::default(), bounds: Rect::default(),
display_data: Default::default(), display_data: Default::default(),
temp_type: TemperatureType::default(), temp_type: TemperatureType::default(),
width: LayoutRule::default(), width: WidgetLayoutRule::default(),
height: LayoutRule::default(), height: WidgetLayoutRule::default(),
block_border: Borders::ALL, block_border: Borders::ALL,
show_scroll_index: false, show_scroll_index: false,
} }
@ -53,13 +53,13 @@ impl TempTable {
} }
/// Sets the width. /// Sets the width.
pub fn width(mut self, width: LayoutRule) -> Self { pub fn width(mut self, width: WidgetLayoutRule) -> Self {
self.width = width; self.width = width;
self self
} }
/// Sets the height. /// Sets the height.
pub fn height(mut self, height: LayoutRule) -> Self { pub fn height(mut self, height: WidgetLayoutRule) -> Self {
self.height = height; self.height = height;
self self
} }
@ -128,11 +128,11 @@ impl Widget for TempTable {
self.display_data = convert_temp_row(data_collection, &self.temp_type); self.display_data = convert_temp_row(data_collection, &self.temp_type);
} }
fn width(&self) -> LayoutRule { fn width(&self) -> WidgetLayoutRule {
self.width self.width
} }
fn height(&self) -> LayoutRule { fn height(&self) -> WidgetLayoutRule {
self.height self.height
} }
} }

View File

@ -462,19 +462,23 @@ pub const DEFAULT_BATTERY_LAYOUT: &str = r##"
pub const DEFAULT_BASIC_LAYOUT: &str = r##" pub const DEFAULT_BASIC_LAYOUT: &str = r##"
[[row]] [[row]]
ratio = 0
[[row.child]] [[row.child]]
type = "bcpu" type = "bcpu"
[[row]] [[row]]
ratio = 0
[[row.child]] [[row.child]]
type = "bmem" type = "bmem"
[[row.child]] [[row.child]]
type = "bnet" type = "bnet"
[[row]] [[row]]
ratio = 0
[[row.child]] [[row.child]]
[[row.child.child]] [[row.child.child]]
length = 1 length = 1
type = "empty" type = "empty"
[[row]] [[row]]
ratio = 0
[[row.child]] [[row.child]]
default = true default = true
carousel_children = ["proc", "temp", "disk"] carousel_children = ["proc", "temp", "disk"]

View File

@ -33,18 +33,19 @@ pub enum LayoutRowChild {
#[derive(Clone, Deserialize, Debug, Serialize)] #[derive(Clone, Deserialize, Debug, Serialize)]
pub struct FinalWidget { pub struct FinalWidget {
#[serde(flatten)] #[serde(flatten)]
pub rule: Option<LayoutRule>, pub rule: Option<WidgetLayoutRule>,
#[serde(rename = "type")] #[serde(rename = "type")]
pub widget_type: String, pub widget_type: String,
pub default: Option<bool>, pub default: Option<bool>,
} }
/// A "rule" denoting how this component is to be laid out. /// A "rule" denoting how a widget is to be laid out.
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)] #[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
#[serde(untagged)] #[serde(untagged)]
pub enum LayoutRule { pub enum WidgetLayoutRule {
/// Expand to whatever space is left; the `ratio` determines how much /// Expand to whatever space is left. The `ratio` field determines
/// space to take if there is more than one [`LayoutRule::Expand`] component. /// how much space to allocate if there are other [`WidgetLayoutRule::Expand`]
/// items.
Expand { ratio: u16 }, Expand { ratio: u16 },
/// Take up an exact amount of space, if possible. /// Take up an exact amount of space, if possible.
@ -54,8 +55,8 @@ pub enum LayoutRule {
}, },
} }
impl Default for LayoutRule { impl Default for WidgetLayoutRule {
fn default() -> Self { fn default() -> Self {
LayoutRule::Expand { ratio: 1 } WidgetLayoutRule::Expand { ratio: 1 }
} }
} }

View File

@ -73,6 +73,28 @@ where
} }
inner inner
} }
fn outer_size(&self, original: Size) -> Size {
let mut outer = original;
if self.borders.intersects(Borders::LEFT) {
outer.width = outer.width.saturating_add(1);
}
if self.borders.intersects(Borders::TOP)
|| self.left_text.is_some()
|| self.right_text.is_some()
{
outer.height = outer.height.saturating_add(1);
}
if self.borders.intersects(Borders::RIGHT) {
outer.width = outer.width.saturating_add(1);
}
if self.borders.intersects(Borders::BOTTOM) {
outer.height = outer.height.saturating_add(1);
}
outer
}
} }
impl<Message, Child> TmpComponent<Message> for Block<Message, Child> impl<Message, Child> TmpComponent<Message> for Block<Message, Child>
@ -136,7 +158,7 @@ where
); );
node.children = vec![child_node]; node.children = vec![child_node];
child_size self.outer_size(child_size)
} else { } else {
Size { Size {
width: 0, width: 0,

View File

@ -62,28 +62,34 @@ impl<Message> FlexElement<Message> {
} }
/// Assumes the flex is NOT 0. Will call layout on its children, but will ignore /// Assumes the flex is NOT 0. Will call layout on its children, but will ignore
/// its sizing. /// its sizing on the given axis.
/// ///
/// **Note it does NOT check for div by zero!** Please check this yourself. /// **Note it does NOT check for div by zero!** Please check this yourself.
pub(crate) fn ratio_layout( pub(crate) fn ratio_layout(
&self, bounds: Bounds, total_flex: u16, node: &mut LayoutNode, parent_alignment: Axis, &self, bounds: Bounds, total_flex: u16, node: &mut LayoutNode, parent_alignment: Axis,
) -> Size { ) -> Size {
let (width, height) = match parent_alignment { let (min_width, min_height, max_width, max_height) = match parent_alignment {
Axis::Horizontal => (bounds.max_width * self.flex / total_flex, bounds.max_height), Axis::Horizontal => {
Axis::Vertical => (bounds.max_width, bounds.max_height * self.flex / total_flex), let w = bounds.max_width * self.flex / total_flex;
(w, 0, w, bounds.max_height)
}
Axis::Vertical => {
let h = bounds.max_height * self.flex / total_flex;
(0, h, bounds.max_width, h)
}
}; };
self.element.layout( let ratio_res = self.element.layout(
Bounds { Bounds {
min_width: width, min_width,
min_height: height, min_height,
max_width: width, max_width,
max_height: height, max_height,
}, },
node, node,
); );
Size { width, height } ratio_res
} }
} }

View File

@ -1,3 +1,5 @@
use std::cmp::max;
use tui::{backend::Backend, layout::Rect, Frame}; use tui::{backend::Backend, layout::Rect, Frame};
pub mod flex_element; pub mod flex_element;
@ -119,11 +121,14 @@ impl<Message> TmpComponent<Message> for Flex<Message> {
} }
fn layout(&self, bounds: Bounds, node: &mut LayoutNode) -> Size { fn layout(&self, bounds: Bounds, node: &mut LayoutNode) -> Size {
let mut remaining_bounds = bounds; let mut remaining_bounds = Bounds {
min_width: 0,
min_height: 0,
max_width: bounds.max_width,
max_height: bounds.max_height,
};
let mut children = vec![LayoutNode::default(); self.children.len()]; let mut children = vec![LayoutNode::default(); self.children.len()];
let mut flexible_children_indexes = vec![]; let mut flexible_children_indexes = vec![];
let mut current_x_offset = 0;
let mut current_y_offset = 0;
let mut sizes = Vec::with_capacity(self.children.len()); let mut sizes = Vec::with_capacity(self.children.len());
let mut current_size = Size::default(); let mut current_size = Size::default();
let mut total_flex = 0; let mut total_flex = 0;
@ -139,7 +144,10 @@ impl<Message> TmpComponent<Message> for Flex<Message> {
let size = if remaining_bounds.has_space() { let size = if remaining_bounds.has_space() {
let size = child.child_layout(remaining_bounds, child_node); let size = child.child_layout(remaining_bounds, child_node);
current_size += size; current_size += size;
remaining_bounds.shrink_size(size); match &self.alignment {
Axis::Horizontal => remaining_bounds.shrink_width_size(size),
Axis::Vertical => remaining_bounds.shrink_height_size(size),
}
size size
} else { } else {
@ -160,13 +168,23 @@ impl<Message> TmpComponent<Message> for Flex<Message> {
// //
// NB: If you **EVER** make changes in this function, ensure these assumptions // NB: If you **EVER** make changes in this function, ensure these assumptions
// still hold! // still hold!
// FIXME: [Remove Unsafe] Can potentially just use zips... and maybe partition to combine above and here
let child = unsafe { self.children.get_unchecked(index) }; let child = unsafe { self.children.get_unchecked(index) };
let child_node = unsafe { children.get_unchecked_mut(index) }; let child_node = unsafe { children.get_unchecked_mut(index) };
let size = unsafe { sizes.get_unchecked_mut(index) }; let size = unsafe { sizes.get_unchecked_mut(index) };
let new_size = let new_size =
child.ratio_layout(remaining_bounds, total_flex, child_node, self.alignment); child.ratio_layout(remaining_bounds, total_flex, child_node, self.alignment);
current_size += new_size; match &self.alignment {
Axis::Horizontal => {
current_size.width += new_size.width;
current_size.height = max(current_size.height, new_size.height);
}
Axis::Vertical => {
current_size.width = max(current_size.width, new_size.width);
current_size.height += new_size.height;
}
}
*size = new_size; *size = new_size;
}); });
@ -184,6 +202,9 @@ impl<Message> TmpComponent<Message> for Flex<Message> {
// Now that we're done determining sizes, convert all children into the appropriate // Now that we're done determining sizes, convert all children into the appropriate
// layout nodes. Remember - parents determine children, and so, we determine // layout nodes. Remember - parents determine children, and so, we determine
// children here! // children here!
let mut current_x_offset = 0;
let mut current_y_offset = 0;
sizes sizes
.iter() .iter()
.zip(children.iter_mut()) .zip(children.iter_mut())
@ -200,7 +221,6 @@ impl<Message> TmpComponent<Message> for Flex<Message> {
} }
}); });
node.children = children; node.children = children;
current_size current_size
} }
} }

View File

@ -1,6 +1,8 @@
use std::cmp::{max, min};
use tui::{text::Text, widgets::Paragraph, Frame}; use tui::{text::Text, widgets::Paragraph, Frame};
use crate::tuine::{DrawContext, StateContext, TmpComponent}; use crate::tuine::{Bounds, DrawContext, LayoutNode, Size, StateContext, TmpComponent};
/// A [`CpuSimple`] is a widget displaying simple CPU stats. /// A [`CpuSimple`] is a widget displaying simple CPU stats.
pub struct CpuSimple {} pub struct CpuSimple {}
@ -27,4 +29,11 @@ impl<Message> TmpComponent<Message> for CpuSimple {
rect, rect,
); );
} }
fn layout(&self, bounds: Bounds, _node: &mut LayoutNode) -> Size {
Size {
width: bounds.max_width,
height: max(bounds.min_height, min(4, bounds.max_height)), // FIXME: Temp value - this is not correct; should be based on data.
}
}
} }

View File

@ -1,6 +1,8 @@
use std::cmp::{max, min};
use tui::{text::Text, widgets::Paragraph, Frame}; use tui::{text::Text, widgets::Paragraph, Frame};
use crate::tuine::{DrawContext, StateContext, TmpComponent}; use crate::tuine::{Bounds, DrawContext, LayoutNode, Size, StateContext, TmpComponent};
/// A [`MemSimple`] is a widget displaying simple CPU stats. /// A [`MemSimple`] is a widget displaying simple CPU stats.
pub struct MemSimple {} pub struct MemSimple {}
@ -27,4 +29,11 @@ impl<Message> TmpComponent<Message> for MemSimple {
rect, rect,
); );
} }
fn layout(&self, bounds: Bounds, _node: &mut LayoutNode) -> Size {
Size {
width: bounds.max_width,
height: max(bounds.min_height, min(2, bounds.max_height)),
}
}
} }

View File

@ -1,6 +1,8 @@
use std::cmp::{max, min};
use tui::{text::Text, widgets::Paragraph, Frame}; use tui::{text::Text, widgets::Paragraph, Frame};
use crate::tuine::{DrawContext, StateContext, TmpComponent}; use crate::tuine::{Bounds, DrawContext, LayoutNode, Size, StateContext, TmpComponent};
/// A [`NetSimple`] is a widget displaying simple CPU stats. /// A [`NetSimple`] is a widget displaying simple CPU stats.
pub struct NetSimple {} pub struct NetSimple {}
@ -27,4 +29,11 @@ impl<Message> TmpComponent<Message> for NetSimple {
rect, rect,
); );
} }
fn layout(&self, bounds: Bounds, _node: &mut LayoutNode) -> Size {
Size {
width: bounds.max_width,
height: max(bounds.min_height, min(2, bounds.max_height)),
}
}
} }

View File

@ -26,17 +26,21 @@ impl Bounds {
self.max_height = self.max_height.saturating_sub(height); self.max_height = self.max_height.saturating_sub(height);
} }
/// Shrinks by a given [`Size`]. /// Shrinks the width by a given [`Size`].
pub fn shrink_size(&mut self, size: Size) { pub fn shrink_width_size(&mut self, size: Size) {
self.max_width = self.max_width.saturating_sub(size.width); self.max_width = self.max_width.saturating_sub(size.width);
}
/// Shrinks the height by a given [`Size`].
pub fn shrink_height_size(&mut self, size: Size) {
self.max_height = self.max_height.saturating_sub(size.height); self.max_height = self.max_height.saturating_sub(size.height);
} }
/// Returns whether there is any space left in this bound for laying out things. /// Returns whether there is any space left in this bound for laying out things.
pub fn has_space(&self) -> bool { pub fn has_space(&self) -> bool {
self.min_width >= self.max_width !(self.min_width > self.max_width
|| self.min_height >= self.max_height || self.min_height > self.max_height
|| self.max_width == 0 || self.max_width == 0
|| self.max_height == 0 || self.max_height == 0)
} }
} }

View File

@ -105,7 +105,7 @@ where
}; };
for msg in messages { for msg in messages {
debug!("Message: {:?}", msg); // FIXME: Remove this debug line! // debug!("Message: {:?}", msg);
let msg_result = application.update(msg); let msg_result = application.update(msg);
should_redraw = should_redraw || msg_result; should_redraw = should_redraw || msg_result;
} }