diff options
author | ClementTsang <cjhtsang@uwaterloo.ca> | 2021-08-31 17:19:05 -0400 |
---|---|---|
committer | ClementTsang <cjhtsang@uwaterloo.ca> | 2021-09-05 19:09:11 -0400 |
commit | eddc9a16c7ac1be90144e8a247b13d6fd96238cf (patch) | |
tree | 8d197acfebf39a02cd8cc4abd0770f4508cbae6f /src/app/widgets/bottom_widgets/basic_mem.rs | |
parent | 204b4dc3510b70618741f82a1e2df6c17c6dadda (diff) |
refactor: move basic mode over
Because writing your own layout system and management is just *so much
fun*. Totally.
-------------------------------------------------------------------
Moves the basic mode system over to the new drawing/widget system. In
the process, it has forced me to completely redo how we do layouts...
again. This is because basic mode has widgets that control their own
height - this means the height of the columns and rows that wrap it
are also affected by the widget's height.
The previous system, using a constraint tree and splitting draw Rects
via tui-rs' built-in constraint solver, did not support this concept
very well. It was not simple to propagate up the widths/heights
towards parents while also using tui-rs' built-in constraint solver.
In the end, it was easier to just rewrite it using another algorithm.
We now follow a process very similar to Flutter's layout system.
Relevant links to the Flutter docs are found in the code or below:
- https://flutter.dev/docs/development/ui/layout/constraints
- https://flutter.dev/docs/resources/inside-flutter#sublinear-layouts
The gist of it, however, is that we now instead a few new options for
any element in the layout tree. A node can either:
- Grow to fill remaining space
- Take up as much room as its children
- Be a specific length
Technically right now, it's not perfect, in that leaf nodes can be as
large as their children (which makes no sense), though in that case it
just treats it as an expand.
Diffstat (limited to 'src/app/widgets/bottom_widgets/basic_mem.rs')
-rw-r--r-- | src/app/widgets/bottom_widgets/basic_mem.rs | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/src/app/widgets/bottom_widgets/basic_mem.rs b/src/app/widgets/bottom_widgets/basic_mem.rs new file mode 100644 index 00000000..7fbd1fd0 --- /dev/null +++ b/src/app/widgets/bottom_widgets/basic_mem.rs @@ -0,0 +1,164 @@ +use crossterm::event::{KeyCode, KeyEvent}; +use tui::{ + backend::Backend, + layout::{Constraint, Layout, Rect}, + widgets::Block, + Frame, +}; + +use crate::{ + app::{ + event::WidgetEventResult, widgets::tui_widgets::PipeGauge, Component, DataCollection, + Widget, + }, + canvas::Painter, + constants::SIDE_BORDERS, + data_conversion::{convert_mem_data_points, convert_mem_labels, convert_swap_data_points}, + options::layout_options::LayoutRule, +}; + +#[derive(Debug)] +pub struct BasicMem { + bounds: Rect, + width: LayoutRule, + mem_data: (f64, String, String), + swap_data: Option<(f64, String, String)>, + use_percent: bool, +} + +impl Default for BasicMem { + fn default() -> Self { + Self { + bounds: Default::default(), + width: Default::default(), + mem_data: (0.0, "0.0B/0.0B".to_string(), "0%".to_string()), + swap_data: None, + use_percent: false, + } + } +} + +impl BasicMem { + /// Sets the width. + pub fn width(mut self, width: LayoutRule) -> Self { + self.width = width; + self + } +} + +impl Component for BasicMem { + fn bounds(&self) -> Rect { + self.bounds + } + + fn set_bounds(&mut self, new_bounds: Rect) { + self.bounds = new_bounds; + } + + fn handle_key_event(&mut self, event: KeyEvent) -> WidgetEventResult { + match event.code { + KeyCode::Char('%') if event.modifiers.is_empty() => { + self.use_percent = !self.use_percent; + WidgetEventResult::Redraw + } + _ => WidgetEventResult::NoRedraw, + } + } +} + +impl Widget for BasicMem { + fn get_pretty_name(&self) -> &'static str { + "Memory" + } + + fn draw<B: Backend>( + &mut self, painter: &Painter, f: &mut Frame<'_, B>, area: Rect, selected: bool, + ) { + let block = Block::default() + .borders(*SIDE_BORDERS) + .border_style(painter.colours.highlighted_border_style); + let inner_area = block.inner(area); + const CONSTRAINTS: [Constraint; 2] = [Constraint::Ratio(1, 2); 2]; + let split_area = Layout::default() + .direction(tui::layout::Direction::Vertical) + .constraints(CONSTRAINTS) + .split(inner_area); + + if selected { + f.render_widget(block, area); + } + + let mut use_percentage = + self.use_percent || (split_area[0].width as usize) < self.mem_data.1.len() + 7; + + if let Some(swap_data) = &self.swap_data { + use_percentage = + use_percentage || (split_area[1].width as usize) < swap_data.1.len() + 7; + + f.render_widget( + PipeGauge::default() + .ratio(swap_data.0) + .style(painter.colours.swap_style) + .gauge_style(painter.colours.swap_style) + .start_label("SWP") + .end_label(if use_percentage { + swap_data.2.clone() + } else { + swap_data.1.clone() + }), + split_area[1], + ); + } + f.render_widget( + PipeGauge::default() + .ratio(self.mem_data.0) + .style(painter.colours.ram_style) + .gauge_style(painter.colours.ram_style) + .start_label("RAM") + .end_label(if use_percentage { + self.mem_data.2.clone() + } else { + self.mem_data.1.clone() + }), + split_area[0], + ); + } + + fn update_data(&mut self, data_collection: &DataCollection) { + let (memory_labels, swap_labels) = convert_mem_labels(data_collection); + + // TODO: [Data update optimization] Probably should just make another function altogether for basic mode. + self.mem_data = if let (Some(data), Some((_, fraction))) = ( + convert_mem_data_points(data_collection, false).last(), + memory_labels, + ) { + ( + data.1 / 100.0, + fraction.trim().to_string(), + format!("{:3.0}%", data.1.round()), + ) + } else { + (0.0, "0.0B/0.0B".to_string(), "0%".to_string()) + }; + self.swap_data = if let (Some(data), Some((_, fraction))) = ( + convert_swap_data_points(data_collection, false).last(), + swap_labels, + ) { + Some(( + data.1 / 100.0, + fraction.trim().to_string(), + format!("{:3.0}%", data.1.round()), + )) + } else { + None + }; + } + + fn width(&self) -> LayoutRule { + self.width + } + + fn height(&self) -> LayoutRule { + LayoutRule::Length { length: 2 } + } +} |