mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-09-23 09:48:25 +02:00
remove code dedup
This commit is contained in:
parent
6555d2d751
commit
a68a7346c3
@ -1,15 +1,12 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
use tui::layout::Direction;
|
||||||
|
|
||||||
|
use crate::canvas::LayoutConstraint;
|
||||||
use crate::constants::DEFAULT_WIDGET_ID;
|
use crate::constants::DEFAULT_WIDGET_ID;
|
||||||
use crate::error::{BottomError, Result};
|
use crate::error::{BottomError, Result};
|
||||||
|
use crate::options::layout_options::Row;
|
||||||
/// Represents a more usable representation of the layout, derived from the
|
use crate::utils::error;
|
||||||
/// config.
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct BottomLayout {
|
|
||||||
pub rows: Vec<BottomRow>,
|
|
||||||
pub total_row_height_ratio: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents a start and end coordinate in some dimension.
|
/// Represents a start and end coordinate in some dimension.
|
||||||
type LineSegment = (u32, u32);
|
type LineSegment = (u32, u32);
|
||||||
@ -18,8 +15,276 @@ type WidgetMappings = (u32, BTreeMap<LineSegment, u64>);
|
|||||||
type ColumnRowMappings = (u32, BTreeMap<LineSegment, WidgetMappings>);
|
type ColumnRowMappings = (u32, BTreeMap<LineSegment, WidgetMappings>);
|
||||||
type ColumnMappings = (u32, BTreeMap<LineSegment, ColumnRowMappings>);
|
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>,
|
||||||
|
|
||||||
|
/// How the container should be sized.
|
||||||
|
pub(crate) constraint: LayoutConstraint,
|
||||||
|
|
||||||
|
/// The direction.
|
||||||
|
direction: ContainerDirection,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Container {
|
||||||
|
pub(crate) fn row(children: Vec<usize>, sizing: LayoutConstraint) -> Self {
|
||||||
|
Self {
|
||||||
|
children,
|
||||||
|
constraint: sizing,
|
||||||
|
direction: ContainerDirection::Row,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn col(children: Vec<usize>, constraint: LayoutConstraint) -> Self {
|
||||||
|
Self {
|
||||||
|
children,
|
||||||
|
constraint,
|
||||||
|
direction: ContainerDirection::Col,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the direction of the container.
|
||||||
|
pub fn direction(&self) -> ContainerDirection {
|
||||||
|
self.direction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The direction in which children in a [`BottomContainer`] will be laid out.
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub(crate) enum ContainerDirection {
|
||||||
|
/// Lay out all children horizontally.
|
||||||
|
Row,
|
||||||
|
|
||||||
|
/// Lay out all children vertically.
|
||||||
|
Col,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ContainerDirection> for Direction {
|
||||||
|
fn from(value: ContainerDirection) -> Self {
|
||||||
|
match value {
|
||||||
|
ContainerDirection::Row => Direction::Horizontal,
|
||||||
|
ContainerDirection::Col => Direction::Vertical,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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>,
|
||||||
|
}
|
||||||
|
|
||||||
impl BottomLayout {
|
impl BottomLayout {
|
||||||
pub fn get_movement_mappings(&mut self) {
|
/// 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);
|
||||||
|
|
||||||
|
id
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the node with the corresponding ID.
|
||||||
|
pub fn get_node(&self, id: usize) -> Option<&Node> {
|
||||||
|
self.arena.get(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the number of elements in the layout.
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.arena.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;
|
||||||
|
|
||||||
|
// TODO: Create the thing; use num_widgets to count how many widgets were inserted.
|
||||||
|
|
||||||
|
if num_widgets > 0 {
|
||||||
|
todo!()
|
||||||
|
} else {
|
||||||
|
Err(error::BottomError::ConfigError(
|
||||||
|
"please have at least one widget under the '[[row]]' section.".to_string(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new [`BottomLayout`] following the basic layout.
|
||||||
|
pub fn new_basic(use_battery: bool) -> Self {
|
||||||
|
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)
|
||||||
|
.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 = 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_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 temp = BottomWidget::new_handled(BottomWidgetType::Temp, 7)
|
||||||
|
.up_neighbour(Some(100))
|
||||||
|
.left_neighbour(Some(DEFAULT_WIDGET_ID))
|
||||||
|
.right_neighbour(Some(8));
|
||||||
|
|
||||||
|
let battery = BottomWidget::new_handled(BottomWidgetType::Battery, 8)
|
||||||
|
.up_neighbour(Some(100))
|
||||||
|
.left_neighbour(Some(7))
|
||||||
|
.right_neighbour(Some(4));
|
||||||
|
|
||||||
|
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),
|
||||||
|
]
|
||||||
|
} 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)
|
||||||
|
.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 = 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_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 temp = BottomWidget::new_handled(BottomWidgetType::Temp, 7)
|
||||||
|
.up_neighbour(Some(100))
|
||||||
|
.left_neighbour(Some(DEFAULT_WIDGET_ID))
|
||||||
|
.right_neighbour(Some(4));
|
||||||
|
|
||||||
|
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 cpu = 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 net = 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 mut layout = BottomLayout::default();
|
||||||
|
// TODO: Add nodes; should we instead back with a hashmap?
|
||||||
|
|
||||||
|
// 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),
|
||||||
|
// ],
|
||||||
|
// }
|
||||||
|
|
||||||
|
layout
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_movement_mappings(&mut self) {
|
||||||
#[allow(clippy::suspicious_operation_groupings)] // Have to enable this, clippy really doesn't like me doing this with tuples...
|
#[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 {
|
fn is_intersecting(a: LineSegment, b: LineSegment) -> bool {
|
||||||
a.0 >= b.0 && a.1 <= b.1
|
a.0 >= b.0 && a.1 <= b.1
|
||||||
@ -39,7 +304,7 @@ impl BottomLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now we need to create the correct mapping for moving from a specific
|
// Now we need to create the correct mapping for moving from a specific
|
||||||
// widget to another
|
// widget to another.
|
||||||
let mut layout_mapping: BTreeMap<LineSegment, ColumnMappings> = BTreeMap::new();
|
let mut layout_mapping: BTreeMap<LineSegment, ColumnMappings> = BTreeMap::new();
|
||||||
let mut total_height = 0;
|
let mut total_height = 0;
|
||||||
for row in &self.rows {
|
for row in &self.rows {
|
||||||
@ -529,201 +794,6 @@ impl BottomLayout {
|
|||||||
height_cursor += row.row_height_ratio;
|
height_cursor += row.row_height_ratio;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_basic_default(use_battery: bool) -> Self {
|
|
||||||
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)
|
|
||||||
.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 = 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_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 temp = BottomWidget::new_handled(BottomWidgetType::Temp, 7)
|
|
||||||
.up_neighbour(Some(100))
|
|
||||||
.left_neighbour(Some(DEFAULT_WIDGET_ID))
|
|
||||||
.right_neighbour(Some(8));
|
|
||||||
|
|
||||||
let battery = BottomWidget::new_handled(BottomWidgetType::Battery, 8)
|
|
||||||
.up_neighbour(Some(100))
|
|
||||||
.left_neighbour(Some(7))
|
|
||||||
.right_neighbour(Some(4));
|
|
||||||
|
|
||||||
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),
|
|
||||||
]
|
|
||||||
} 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)
|
|
||||||
.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 = 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_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 temp = BottomWidget::new_handled(BottomWidgetType::Temp, 7)
|
|
||||||
.up_neighbour(Some(100))
|
|
||||||
.left_neighbour(Some(DEFAULT_WIDGET_ID))
|
|
||||||
.right_neighbour(Some(4));
|
|
||||||
|
|
||||||
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 cpu = 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 net = 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));
|
|
||||||
|
|
||||||
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),
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub(crate) enum BottomLayoutNode {
|
|
||||||
/// A container type, containing more [`BottomLayoutNode`] children.
|
|
||||||
Container(BottomContainer),
|
|
||||||
|
|
||||||
/// A leaf node, containing a [`BottomWidget`].
|
|
||||||
Widget(BottomWidget),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A "container" that contains more [`BottomLayoutNode`]s.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub(crate) struct BottomContainer {
|
|
||||||
/// The children elements.
|
|
||||||
pub(crate) children: Vec<BottomLayoutNode>,
|
|
||||||
|
|
||||||
/// How the container should be sized.
|
|
||||||
pub(crate) sizing: ElementSizing,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The direction in which children in a [`BottomContainer`] will be laid out.
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub(crate) enum BottomContainerType {
|
|
||||||
/// Lay out all children horizontally.
|
|
||||||
Row,
|
|
||||||
|
|
||||||
/// Lay out all children vertically.
|
|
||||||
Col,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// How the element sizing should be determined.
|
|
||||||
///
|
|
||||||
/// FIXME: This should honestly be matched tighter to the canvas system; we currently have two very similar ways of doing things!
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub(crate) enum ElementSizing {
|
|
||||||
/// Denotes that the canvas should follow the given ratio of `lhs:rhs` to determine spacing for the element.
|
|
||||||
Ratio { lhs: u32, rhs: u32 },
|
|
||||||
|
|
||||||
/// Denotes that the canvas should let this element grow to take up whatever remaining space is left after
|
|
||||||
/// sizing the other sibling elements.
|
|
||||||
FlexGrow,
|
|
||||||
|
|
||||||
/// Denotes that the canvas can do whatever it likes to determine spacing for the element.
|
|
||||||
CanvasHandled,
|
|
||||||
|
|
||||||
/// Denotes that the element should take up 100% of the space.
|
|
||||||
Fill,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a single row in the layout.
|
/// Represents a single row in the layout.
|
||||||
@ -884,7 +954,7 @@ pub struct BottomWidget {
|
|||||||
pub widget_id: u64,
|
pub widget_id: u64,
|
||||||
|
|
||||||
/// How the widget should be sized by the canvas.
|
/// How the widget should be sized by the canvas.
|
||||||
pub sizing: ElementSizing,
|
pub constraint: LayoutConstraint,
|
||||||
|
|
||||||
/// The widget ID to go to when moving to the left.
|
/// The widget ID to go to when moving to the left.
|
||||||
pub left_neighbour: Option<u64>,
|
pub left_neighbour: Option<u64>,
|
||||||
@ -910,12 +980,12 @@ pub struct BottomWidget {
|
|||||||
|
|
||||||
impl BottomWidget {
|
impl BottomWidget {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
widget_type: BottomWidgetType, widget_id: u64, sizing: ElementSizing,
|
widget_type: BottomWidgetType, widget_id: u64, constraint: LayoutConstraint,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
widget_type,
|
widget_type,
|
||||||
widget_id,
|
widget_id,
|
||||||
sizing,
|
constraint,
|
||||||
left_neighbour: None,
|
left_neighbour: None,
|
||||||
right_neighbour: None,
|
right_neighbour: None,
|
||||||
up_neighbour: None,
|
up_neighbour: None,
|
||||||
@ -927,11 +997,15 @@ impl BottomWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new_fill(widget_type: BottomWidgetType, widget_id: u64) -> Self {
|
pub(crate) fn new_fill(widget_type: BottomWidgetType, widget_id: u64) -> Self {
|
||||||
Self::new(widget_type, widget_id, ElementSizing::Fill)
|
Self::new(
|
||||||
|
widget_type,
|
||||||
|
widget_id,
|
||||||
|
LayoutConstraint::Ratio { lhs: 1, rhs: 1 },
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new_handled(widget_type: BottomWidgetType, widget_id: u64) -> Self {
|
pub(crate) fn new_handled(widget_type: BottomWidgetType, widget_id: u64) -> Self {
|
||||||
Self::new(widget_type, widget_id, ElementSizing::CanvasHandled)
|
Self::new(widget_type, widget_id, LayoutConstraint::CanvasHandled)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn left_neighbour(mut self, left_neighbour: Option<u64>) -> Self {
|
pub(crate) fn left_neighbour(mut self, left_neighbour: Option<u64>) -> Self {
|
||||||
|
247
src/canvas.rs
247
src/canvas.rs
@ -1,7 +1,7 @@
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use canvas_styling::*;
|
use canvas_styling::*;
|
||||||
use itertools::izip;
|
use hashbrown::HashMap;
|
||||||
use tui::{
|
use tui::{
|
||||||
backend::Backend,
|
backend::Backend,
|
||||||
layout::{Constraint, Direction, Layout, Rect},
|
layout::{Constraint, Direction, Layout, Rect},
|
||||||
@ -13,7 +13,7 @@ use tui::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
app::{
|
app::{
|
||||||
self,
|
self,
|
||||||
layout_manager::{BottomColRow, BottomLayout, BottomWidgetType, ElementSizing},
|
layout_manager::{BottomColRow, BottomLayout, BottomWidget, BottomWidgetType, Node},
|
||||||
App,
|
App,
|
||||||
},
|
},
|
||||||
constants::*,
|
constants::*,
|
||||||
@ -63,22 +63,23 @@ pub struct Painter {
|
|||||||
height: u16,
|
height: u16,
|
||||||
width: u16,
|
width: u16,
|
||||||
styled_help_text: Vec<Line<'static>>,
|
styled_help_text: Vec<Line<'static>>,
|
||||||
is_mac_os: bool, // TODO: This feels out of place...
|
|
||||||
|
|
||||||
// TODO: Redo this entire thing.
|
derived_widget_draw_locs: HashMap<usize, Rect>,
|
||||||
row_constraints: Vec<LayoutConstraint>,
|
|
||||||
col_constraints: Vec<Vec<LayoutConstraint>>,
|
|
||||||
col_row_constraints: Vec<Vec<Vec<LayoutConstraint>>>,
|
|
||||||
layout_constraints: Vec<Vec<Vec<Vec<LayoutConstraint>>>>,
|
|
||||||
derived_widget_draw_locs: Vec<Vec<Vec<Vec<Rect>>>>,
|
|
||||||
widget_layout: BottomLayout,
|
widget_layout: BottomLayout,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Part of a temporary fix for https://github.com/ClementTsang/bottom/issues/896
|
// Part of a temporary fix for https://github.com/ClementTsang/bottom/issues/896
|
||||||
enum LayoutConstraint {
|
#[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 },
|
||||||
|
|
||||||
|
/// Denotes that the canvas should let this element grow to take up whatever remaining space is left after
|
||||||
|
/// sizing the other sibling elements.
|
||||||
|
FlexGrow,
|
||||||
|
|
||||||
|
/// Denotes that the canvas can do whatever it likes to determine spacing for the element.
|
||||||
CanvasHandled,
|
CanvasHandled,
|
||||||
Grow,
|
|
||||||
Ratio(u32, u32),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Painter {
|
impl Painter {
|
||||||
@ -87,77 +88,11 @@ impl Painter {
|
|||||||
// We want to do this ONCE and reuse; after this we can just construct
|
// We want to do this ONCE and reuse; after this we can just construct
|
||||||
// based on the console size.
|
// based on the console size.
|
||||||
|
|
||||||
let mut row_constraints = Vec::new();
|
|
||||||
let mut col_constraints = Vec::new();
|
|
||||||
let mut col_row_constraints = Vec::new();
|
|
||||||
let mut layout_constraints = Vec::new();
|
|
||||||
|
|
||||||
widget_layout.rows.iter().for_each(|row| {
|
|
||||||
if row.canvas_handle_height {
|
|
||||||
row_constraints.push(LayoutConstraint::CanvasHandled);
|
|
||||||
} else {
|
|
||||||
row_constraints.push(LayoutConstraint::Ratio(
|
|
||||||
row.row_height_ratio,
|
|
||||||
widget_layout.total_row_height_ratio,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut new_col_constraints = Vec::new();
|
|
||||||
let mut new_widget_constraints = Vec::new();
|
|
||||||
let mut new_col_row_constraints = Vec::new();
|
|
||||||
row.children.iter().for_each(|col| {
|
|
||||||
if col.canvas_handle_width {
|
|
||||||
new_col_constraints.push(LayoutConstraint::CanvasHandled);
|
|
||||||
} else {
|
|
||||||
new_col_constraints.push(LayoutConstraint::Ratio(
|
|
||||||
col.col_width_ratio,
|
|
||||||
row.total_col_ratio,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut new_new_col_row_constraints = Vec::new();
|
|
||||||
let mut new_new_widget_constraints = Vec::new();
|
|
||||||
col.children.iter().for_each(|col_row| {
|
|
||||||
if col_row.canvas_handle_height {
|
|
||||||
new_new_col_row_constraints.push(LayoutConstraint::CanvasHandled);
|
|
||||||
} else if col_row.flex_grow {
|
|
||||||
new_new_col_row_constraints.push(LayoutConstraint::Grow);
|
|
||||||
} else {
|
|
||||||
new_new_col_row_constraints.push(LayoutConstraint::Ratio(
|
|
||||||
col_row.col_row_height_ratio,
|
|
||||||
col.total_col_row_ratio,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut new_new_new_widget_constraints = Vec::new();
|
|
||||||
col_row.children.iter().for_each(|widget| {
|
|
||||||
new_new_new_widget_constraints.push(match widget.sizing {
|
|
||||||
ElementSizing::Ratio { lhs, rhs } => LayoutConstraint::Ratio(lhs, rhs),
|
|
||||||
ElementSizing::FlexGrow => LayoutConstraint::Grow,
|
|
||||||
ElementSizing::CanvasHandled => LayoutConstraint::CanvasHandled,
|
|
||||||
ElementSizing::Fill => LayoutConstraint::Ratio(1, 1),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
new_new_widget_constraints.push(new_new_new_widget_constraints);
|
|
||||||
});
|
|
||||||
new_col_row_constraints.push(new_new_col_row_constraints);
|
|
||||||
new_widget_constraints.push(new_new_widget_constraints);
|
|
||||||
});
|
|
||||||
col_row_constraints.push(new_col_row_constraints);
|
|
||||||
layout_constraints.push(new_widget_constraints);
|
|
||||||
col_constraints.push(new_col_constraints);
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut painter = Painter {
|
let mut painter = Painter {
|
||||||
colours: styling,
|
colours: styling,
|
||||||
height: 0,
|
height: 0,
|
||||||
width: 0,
|
width: 0,
|
||||||
styled_help_text: Vec::default(),
|
styled_help_text: Vec::default(),
|
||||||
is_mac_os: cfg!(target_os = "macos"),
|
|
||||||
row_constraints,
|
|
||||||
col_constraints,
|
|
||||||
col_row_constraints,
|
|
||||||
layout_constraints,
|
|
||||||
widget_layout,
|
widget_layout,
|
||||||
derived_widget_draw_locs: Vec::default(),
|
derived_widget_draw_locs: Vec::default(),
|
||||||
};
|
};
|
||||||
@ -525,8 +460,8 @@ impl Painter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.derived_widget_draw_locs.is_empty() || app_state.is_force_redraw {
|
if self.derived_widget_draw_locs.is_empty() || app_state.is_force_redraw {
|
||||||
fn get_constraints(
|
fn get_rects<I: ExactSizeIterator<Item = LayoutConstraint>>(
|
||||||
direction: Direction, constraints: &[LayoutConstraint], area: Rect,
|
direction: Direction, constraints: I, area: Rect,
|
||||||
) -> Vec<Rect> {
|
) -> Vec<Rect> {
|
||||||
// Order of operations:
|
// Order of operations:
|
||||||
// - Ratios first + canvas-handled (which is just zero)
|
// - Ratios first + canvas-handled (which is just zero)
|
||||||
@ -558,21 +493,20 @@ impl Painter {
|
|||||||
let mut num_non_ch = 0;
|
let mut num_non_ch = 0;
|
||||||
|
|
||||||
for (itx, (constraint, size)) in
|
for (itx, (constraint, size)) in
|
||||||
constraints.iter().zip(sizes.iter_mut()).enumerate()
|
constraints.zip(sizes.iter_mut()).enumerate()
|
||||||
{
|
{
|
||||||
match constraint {
|
match constraint {
|
||||||
LayoutConstraint::Ratio(a, b) => {
|
LayoutConstraint::Ratio { lhs, rhs } => {
|
||||||
match direction {
|
match direction {
|
||||||
Direction::Horizontal => {
|
Direction::Horizontal => {
|
||||||
let amount =
|
let amount = (((area.width as u32) * lhs) / rhs) as u16;
|
||||||
(((area.width as u32) * (*a)) / (*b)) as u16;
|
|
||||||
bounds.shrink_width(amount);
|
bounds.shrink_width(amount);
|
||||||
size.width = amount;
|
size.width = amount;
|
||||||
size.height = area.height;
|
size.height = area.height;
|
||||||
}
|
}
|
||||||
Direction::Vertical => {
|
Direction::Vertical => {
|
||||||
let amount =
|
let amount =
|
||||||
(((area.height as u32) * (*a)) / (*b)) as u16;
|
(((area.height as u32) * lhs) / rhs) as u16;
|
||||||
bounds.shrink_height(amount);
|
bounds.shrink_height(amount);
|
||||||
size.width = area.width;
|
size.width = area.width;
|
||||||
size.height = amount;
|
size.height = amount;
|
||||||
@ -580,7 +514,7 @@ impl Painter {
|
|||||||
}
|
}
|
||||||
num_non_ch += 1;
|
num_non_ch += 1;
|
||||||
}
|
}
|
||||||
LayoutConstraint::Grow => {
|
LayoutConstraint::FlexGrow => {
|
||||||
// Mark it as grow in the vector and handle in second pass.
|
// Mark it as grow in the vector and handle in second pass.
|
||||||
grow.push(itx);
|
grow.push(itx);
|
||||||
num_non_ch += 1;
|
num_non_ch += 1;
|
||||||
@ -624,8 +558,8 @@ impl Painter {
|
|||||||
for (size, constraint) in sizes.iter_mut().zip(constraints) {
|
for (size, constraint) in sizes.iter_mut().zip(constraints) {
|
||||||
match constraint {
|
match constraint {
|
||||||
LayoutConstraint::CanvasHandled => {}
|
LayoutConstraint::CanvasHandled => {}
|
||||||
LayoutConstraint::Grow
|
LayoutConstraint::FlexGrow
|
||||||
| LayoutConstraint::Ratio(_, _) => {
|
| LayoutConstraint::Ratio { .. } => {
|
||||||
if remaining_width > 0 {
|
if remaining_width > 0 {
|
||||||
size.width += per_item + 1;
|
size.width += per_item + 1;
|
||||||
remaining_width -= 1;
|
remaining_width -= 1;
|
||||||
@ -642,8 +576,8 @@ impl Painter {
|
|||||||
for (size, constraint) in sizes.iter_mut().zip(constraints) {
|
for (size, constraint) in sizes.iter_mut().zip(constraints) {
|
||||||
match constraint {
|
match constraint {
|
||||||
LayoutConstraint::CanvasHandled => {}
|
LayoutConstraint::CanvasHandled => {}
|
||||||
LayoutConstraint::Grow
|
LayoutConstraint::FlexGrow
|
||||||
| LayoutConstraint::Ratio(_, _) => {
|
| LayoutConstraint::Ratio { .. } => {
|
||||||
if remaining_height > 0 {
|
if remaining_height > 0 {
|
||||||
size.height += per_item + 1;
|
size.height += per_item + 1;
|
||||||
remaining_height -= 1;
|
remaining_height -= 1;
|
||||||
@ -677,79 +611,53 @@ impl Painter {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
let draw_locs =
|
// Do a preorder traversal through the tree in, and calculate the draw [`Rect`]s for each widget.
|
||||||
get_constraints(Direction::Vertical, &self.row_constraints, terminal_size);
|
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
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
self.derived_widget_draw_locs = izip!(
|
let rects =
|
||||||
draw_locs,
|
get_rects(container.direction().into(), constraints, rect);
|
||||||
&self.col_constraints,
|
|
||||||
&self.col_row_constraints,
|
|
||||||
&self.layout_constraints,
|
|
||||||
&self.widget_layout.rows
|
|
||||||
)
|
|
||||||
.map(
|
|
||||||
|(
|
|
||||||
draw_loc,
|
|
||||||
col_constraint,
|
|
||||||
col_row_constraint,
|
|
||||||
row_constraint_vec,
|
|
||||||
cols,
|
|
||||||
)| {
|
|
||||||
izip!(
|
|
||||||
get_constraints(Direction::Horizontal, col_constraint, draw_loc),
|
|
||||||
col_row_constraint,
|
|
||||||
row_constraint_vec,
|
|
||||||
&cols.children
|
|
||||||
)
|
|
||||||
.map(|(split_loc, constraint, col_constraint_vec, col_rows)| {
|
|
||||||
izip!(
|
|
||||||
get_constraints(
|
|
||||||
Direction::Vertical,
|
|
||||||
constraint.as_slice(),
|
|
||||||
split_loc
|
|
||||||
),
|
|
||||||
col_constraint_vec,
|
|
||||||
&col_rows.children
|
|
||||||
)
|
|
||||||
.map(|(draw_loc, col_row_constraint_vec, widgets)| {
|
|
||||||
// Note that col_row_constraint_vec CONTAINS the widget constraints
|
|
||||||
let widget_draw_locs = get_constraints(
|
|
||||||
Direction::Horizontal,
|
|
||||||
col_row_constraint_vec.as_slice(),
|
|
||||||
draw_loc,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Side effect, draw here.
|
// If it's a container, push in reverse order to the stack.
|
||||||
self.draw_widgets_with_constraints(
|
for child in container
|
||||||
f,
|
.children
|
||||||
app_state,
|
.iter()
|
||||||
widgets,
|
.cloned()
|
||||||
&widget_draw_locs,
|
.zip(rects.into_iter())
|
||||||
);
|
.rev()
|
||||||
|
{
|
||||||
widget_draw_locs
|
queue.push(child);
|
||||||
})
|
}
|
||||||
.collect()
|
}
|
||||||
})
|
Node::Widget(widget) => {
|
||||||
.collect()
|
// 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);
|
||||||
)
|
}
|
||||||
.collect();
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.widget_layout
|
for (id, rect) in &self.derived_widget_draw_locs {
|
||||||
.rows
|
match &self.widget_layout.get_node(*id) {
|
||||||
.iter()
|
Some(Node::Widget(widget)) => {
|
||||||
.flat_map(|row| &row.children)
|
self.draw_widget(f, app_state, widget, *rect);
|
||||||
.flat_map(|col| &col.children)
|
}
|
||||||
.zip(self.derived_widget_draw_locs.iter().flatten().flatten())
|
_ => {
|
||||||
.for_each(|(widgets, widget_draw_locs)| {
|
// This should never happen, but if it does, do nothing.
|
||||||
self.draw_widgets_with_constraints(
|
}
|
||||||
f,
|
}
|
||||||
app_state,
|
}
|
||||||
widgets,
|
|
||||||
widget_draw_locs,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
@ -800,4 +708,23 @@ impl Painter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn draw_widget<B: Backend>(
|
||||||
|
&self, f: &mut Frame<'_, B>, app_state: &mut App, widget: &BottomWidget, rect: Rect,
|
||||||
|
) {
|
||||||
|
use BottomWidgetType::*;
|
||||||
|
if rect.width >= 2 && rect.height >= 2 {
|
||||||
|
match &widget.widget_type {
|
||||||
|
Empty => {}
|
||||||
|
Cpu => self.draw_cpu(f, app_state, rect, widget.widget_id),
|
||||||
|
Mem => self.draw_memory_graph(f, app_state, rect, widget.widget_id),
|
||||||
|
Net => self.draw_network(f, app_state, rect, widget.widget_id),
|
||||||
|
Temp => self.draw_temp_table(f, app_state, rect, widget.widget_id),
|
||||||
|
Disk => self.draw_disk_table(f, app_state, rect, widget.widget_id),
|
||||||
|
Proc => self.draw_process_widget(f, app_state, rect, true, widget.widget_id),
|
||||||
|
Battery => self.draw_battery_display(f, app_state, rect, true, widget.widget_id),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,10 +220,14 @@ impl Painter {
|
|||||||
|
|
||||||
// TODO: [MOUSE] Mouse support for these in search
|
// TODO: [MOUSE] Mouse support for these in search
|
||||||
// TODO: [MOVEMENT] Movement support for these in search
|
// TODO: [MOVEMENT] Movement support for these in search
|
||||||
let (case, whole, regex) = if self.is_mac_os {
|
let (case, whole, regex) = {
|
||||||
("Case(F1)", "Whole(F2)", "Regex(F3)")
|
cfg_if::cfg_if! {
|
||||||
} else {
|
if #[cfg(target_os = "macos")] {
|
||||||
("Case(Alt+C)", "Whole(Alt+W)", "Regex(Alt+R)")
|
("Case(F1)", "Whole(F2)", "Regex(F3)")
|
||||||
|
} else {
|
||||||
|
("Case(Alt+C)", "Whole(Alt+W)", "Regex(Alt+R)")
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let option_text = Line::from(vec![
|
let option_text = Line::from(vec![
|
||||||
Span::styled(case, case_style),
|
Span::styled(case, case_style),
|
||||||
|
@ -471,7 +471,7 @@ pub fn get_widget_layout(
|
|||||||
let bottom_layout = if is_flag_enabled!(basic, matches, config) {
|
let bottom_layout = if is_flag_enabled!(basic, matches, config) {
|
||||||
default_widget_id = DEFAULT_WIDGET_ID;
|
default_widget_id = DEFAULT_WIDGET_ID;
|
||||||
|
|
||||||
BottomLayout::init_basic_default(get_use_battery(matches, config))
|
BottomLayout::new_basic(get_use_battery(matches, config))
|
||||||
} else {
|
} else {
|
||||||
let ref_row: Vec<Row>; // Required to handle reference
|
let ref_row: Vec<Row>; // Required to handle reference
|
||||||
let rows = match &config.row {
|
let rows = match &config.row {
|
||||||
@ -492,34 +492,24 @@ pub fn get_widget_layout(
|
|||||||
let mut iter_id = 0; // A lazy way of forcing unique IDs *shrugs*
|
let mut iter_id = 0; // A lazy way of forcing unique IDs *shrugs*
|
||||||
let mut total_height_ratio = 0;
|
let mut total_height_ratio = 0;
|
||||||
|
|
||||||
let mut ret_bottom_layout = BottomLayout {
|
// let mut ret_bottom_layout = BottomLayout {
|
||||||
rows: rows
|
// arena: todo!(),
|
||||||
.iter()
|
// arena: rows
|
||||||
.map(|row| {
|
// .iter()
|
||||||
row.convert_row_to_bottom_row(
|
// .map(|row| {
|
||||||
&mut iter_id,
|
// row.convert_row_to_bottom_row(
|
||||||
&mut total_height_ratio,
|
// &mut iter_id,
|
||||||
&mut default_widget_id,
|
// &mut total_height_ratio,
|
||||||
&default_widget_type,
|
// &mut default_widget_id,
|
||||||
&mut default_widget_count,
|
// &default_widget_type,
|
||||||
left_legend,
|
// &mut default_widget_count,
|
||||||
)
|
// left_legend,
|
||||||
})
|
// )
|
||||||
.collect::<error::Result<Vec<_>>>()?,
|
// })
|
||||||
total_row_height_ratio: total_height_ratio,
|
// .collect::<error::Result<Vec<_>>>()?,
|
||||||
};
|
// };
|
||||||
|
|
||||||
// Confirm that we have at least ONE widget left - if not, error out!
|
BottomLayout::from_rows(rows)?
|
||||||
if iter_id > 0 {
|
|
||||||
ret_bottom_layout.get_movement_mappings();
|
|
||||||
// debug!("Bottom layout: {:#?}", ret_bottom_layout);
|
|
||||||
|
|
||||||
ret_bottom_layout
|
|
||||||
} else {
|
|
||||||
return Err(error::BottomError::ConfigError(
|
|
||||||
"please have at least one widget under the '[[row]]' section.".to_string(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((bottom_layout, default_widget_id, default_widget_type))
|
Ok((bottom_layout, default_widget_id, default_widget_type))
|
||||||
|
@ -8,7 +8,7 @@ use bottom::options::{layout_options::Row, Config};
|
|||||||
use bottom::utils::error;
|
use bottom::utils::error;
|
||||||
use toml_edit::de::from_str;
|
use toml_edit::de::from_str;
|
||||||
|
|
||||||
// TODO: Could move these into the library files rather than external tbh.
|
// FIXME: Move these into the library!
|
||||||
|
|
||||||
const PROC_LAYOUT: &str = r##"
|
const PROC_LAYOUT: &str = r##"
|
||||||
[[row]]
|
[[row]]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user