summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClementTsang <34804052+ClementTsang@users.noreply.github.com>2023-08-05 17:41:14 -0400
committerClementTsang <34804052+ClementTsang@users.noreply.github.com>2023-08-05 17:41:14 -0400
commita0c2efe09d6348eb4280fdc6ca60dc5df317f0b2 (patch)
tree480909e0e89c944b54ec818ac8fa2a7bcc493066
parent000ea7cce462334f4f5a535d946bbc6fdb83f0fe (diff)
-rw-r--r--src/app/layout_manager.rs88
-rw-r--r--src/canvas.rs65
-rw-r--r--src/options.rs6
3 files changed, 102 insertions, 57 deletions
diff --git a/src/app/layout_manager.rs b/src/app/layout_manager.rs
index da55b9ac..9f601885 100644
--- a/src/app/layout_manager.rs
+++ b/src/app/layout_manager.rs
@@ -15,14 +15,14 @@ type WidgetMappings = (u32, BTreeMap<LineSegment, u64>);
type ColumnRowMappings = (u32, BTreeMap<LineSegment, WidgetMappings>);
type ColumnMappings = (u32, BTreeMap<LineSegment, ColumnRowMappings>);
-/// A "container" that contains more [`Node`]s.
+/// A "container" that contains more child elements, stored as [`NodeId`]s.
#[derive(Debug, Clone)]
pub(crate) struct Container {
/// The children elements.
- pub(crate) children: Vec<NodeId>,
+ children: Vec<NodeId>,
/// How the container should be sized.
- pub(crate) constraint: LayoutConstraint,
+ constraint: LayoutConstraint,
/// The direction.
direction: ContainerDirection,
@@ -45,7 +45,20 @@ impl Container {
}
}
+ /// Returns the constraint of the container.
+ #[inline]
+ pub fn constraint(&self) -> LayoutConstraint {
+ self.constraint
+ }
+
+ /// Returns a reference to the children.
+ #[inline]
+ pub fn children(&self) -> &[NodeId] {
+ &self.children
+ }
+
/// Returns the direction of the container.
+ #[inline]
pub fn direction(&self) -> ContainerDirection {
self.direction
}
@@ -188,16 +201,24 @@ impl BottomLayout {
NodeId::Widget(id)
}
- /// Get the node with the corresponding ID.
+ /// Get a reference to the [`Container`] with the corresponding ID if
+ /// it exists.
pub fn get_container(&self, id: usize) -> Option<&Container> {
self.containers.get(id)
}
- /// Get the node with the corresponding ID.
+ /// Get a reference to the [`BottomWidget`] with the corresponding ID if
+ /// it exists.
pub fn get_widget(&self, id: usize) -> Option<&BottomWidget> {
self.widgets.get(id)
}
+ /// Get a mutable reference to the [`BottomWidget`] with the corresponding
+ /// ID if it exists.
+ pub fn get_widget_mut(&mut self, id: usize) -> Option<&mut BottomWidget> {
+ self.widgets.get_mut(id)
+ }
+
/// Returns an iterator of all widgets.
pub fn widgets_iter(&self) -> impl Iterator<Item = &BottomWidget> {
self.widgets.iter()
@@ -534,7 +555,64 @@ impl BottomLayout {
layout
}
+ /// Creates mappings to move from one widget to another.
fn get_movement_mappings(&mut self) {
+ type LineSegment = (u32, u32);
+
+ // Have to enable this, clippy really doesn't like me doing this with tuples...
+ #[allow(clippy::suspicious_operation_groupings)]
+ fn is_intersecting(a: LineSegment, b: LineSegment) -> bool {
+ a.0 >= b.0 && a.1 <= b.1
+ || a.1 >= b.1 && a.0 <= b.0
+ || a.0 <= b.0 && a.1 >= b.0
+ || a.0 >= b.0 && a.0 < b.1 && a.1 >= b.1
+ }
+
+ fn distance(target: LineSegment, candidate: LineSegment) -> u32 {
+ if candidate.0 < target.0 {
+ candidate.1 - target.0
+ } else if candidate.1 < target.1 {
+ candidate.1 - candidate.0
+ } else {
+ target.1 - candidate.0
+ }
+ }
+
+ if let Some(root_id) = self.root_id() {
+ let mut queue = vec![root_id];
+
+ // Build a k-d tree to have a simple virtual mapping of where each
+ // widget is relative to each other.
+ while let Some(current) = queue.pop() {
+ match current {
+ NodeId::Container(id) => if let Some(children) = self.get_container(id) {},
+ NodeId::Widget(id) => if let Some(widget) = self.get_widget(id) {},
+ }
+ }
+
+ // Now traverse the layout tree a second time, assigning any missing
+ // widget mappings where it makes sense.
+ queue.push(root_id);
+ while let Some(current) = queue.pop() {
+ match current {
+ NodeId::Container(id) => if let Some(children) = self.get_container(id) {},
+ NodeId::Widget(id) => {
+ if let Some(widget) = self.get_widget_mut(id) {
+ if widget.left_neighbour.is_none() {}
+
+ if widget.right_neighbour.is_none() {}
+
+ if widget.up_neighbour.is_none() {}
+
+ if widget.down_neighbour.is_none() {}
+ }
+ }
+ }
+ }
+ }
+ }
+
+ fn old_get_movement_mappings(&mut self) {
#[allow(clippy::suspicious_operation_groupings)] // Have to enable this, clippy really doesn't like me doing this with tuples...
fn is_intersecting(a: LineSegment, b: LineSegment) -> bool {
a.0 >= b.0 && a.1 <= b.1
diff --git a/src/canvas.rs b/src/canvas.rs
index 19a5a3d5..6d268a90 100644
--- a/src/canvas.rs
+++ b/src/canvas.rs
@@ -13,7 +13,7 @@ use tui::{
use crate::{
app::{
self,
- layout_manager::{BottomColRow, BottomLayout, BottomWidget, BottomWidgetType, NodeId},
+ layout_manager::{BottomLayout, BottomWidget, BottomWidgetType, NodeId},
App,
},
constants::*,
@@ -620,19 +620,20 @@ impl Painter {
if let Some(container) =
self.widget_layout.get_container(current_id)
{
- 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 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(),
@@ -642,7 +643,7 @@ impl Painter {
// If it's a container, push in reverse order to the stack.
for child in container
- .children
+ .children()
.iter()
.cloned()
.zip(rects.into_iter())
@@ -690,40 +691,6 @@ impl Painter {
Ok(())
}
- fn draw_widgets_with_constraints<B: Backend>(
- &self, f: &mut Frame<'_, B>, app_state: &mut App, widgets: &BottomColRow,
- widget_draw_locs: &[Rect],
- ) {
- use BottomWidgetType::*;
- for (widget, widget_draw_loc) in widgets.children.iter().zip(widget_draw_locs) {
- if widget_draw_loc.width >= 2 && widget_draw_loc.height >= 2 {
- match &widget.widget_type {
- Empty => {}
- Cpu => self.draw_cpu(f, app_state, *widget_draw_loc, widget.widget_id),
- Mem => self.draw_memory_graph(f, app_state, *widget_draw_loc, widget.widget_id),
- Net => self.draw_network(f, app_state, *widget_draw_loc, widget.widget_id),
- Temp => self.draw_temp_table(f, app_state, *widget_draw_loc, widget.widget_id),
- Disk => self.draw_disk_table(f, app_state, *widget_draw_loc, widget.widget_id),
- Proc => self.draw_process_widget(
- f,
- app_state,
- *widget_draw_loc,
- true,
- widget.widget_id,
- ),
- Battery => self.draw_battery_display(
- f,
- app_state,
- *widget_draw_loc,
- true,
- widget.widget_id,
- ),
- _ => {}
- }
- }
- }
- }
-
fn draw_widget<B: Backend>(
&self, f: &mut Frame<'_, B>, app_state: &mut App, widget: &BottomWidget, rect: Rect,
) {
diff --git a/src/options.rs b/src/options.rs
index 2d9c0e66..e9cc807d 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -468,18 +468,18 @@ pub fn get_widget_layout(
default_widget_type,
))
} else {
- let ref_row: Vec<Row>; // Required to handle reference
+ let ref_row: Vec<Row>; // Required to handle reference.
let rows = match &config.row {
Some(r) => r,
None => {
- // This cannot (like it really shouldn't) fail!
ref_row = toml_edit::de::from_str::<Config>(if get_use_battery(matches, config) {
DEFAULT_BATTERY_LAYOUT
} else {
DEFAULT_LAYOUT
})?
.row
- .unwrap();
+ .expect("parsing the default layouts should never fail!");
+
&ref_row
}
};