temp work

This commit is contained in:
Clement Tsang 2024-01-02 01:13:02 -05:00
parent dbadbb996c
commit c730048c7a
No known key found for this signature in database
GPG Key ID: B17834EA2182446B
13 changed files with 252 additions and 41 deletions

1
Cargo.lock generated
View File

@ -174,6 +174,7 @@ dependencies = [
"kstring",
"libc",
"log",
"lru",
"mach2",
"nvml-wrapper",
"predicates",

View File

@ -93,6 +93,7 @@ indexmap = "2.1.0"
itertools = "0.12.0"
kstring = { version = "2.0.0", features = ["arc"] }
log = { version = "0.4.20", optional = true }
lru = "0.12.1"
nvml-wrapper = { version = "0.9.0", optional = true, features = ["legacy-functions"] }
regex = "1.10.2"
serde = { version = "=1.0.193", features = ["derive"] }

View File

@ -697,28 +697,6 @@ impl BottomLayout {
}
}
// pub enum BottomLayoutNode {
// Container(BottomContainer),
// Widget(BottomWidget),
// }
// pub struct BottomContainer {
// children: Vec<BottomLayoutNode>,
// root_ratio: u32,
// growth_type: BottomLayoutNodeSizing,
// }
// pub enum BottomContainerType {
// Row,
// Col,
// }
// pub enum BottomLayoutNodeSizing {
// Ratio(u32),
// CanvasHandles,
// FlexGrow,
// }
/// Represents a single row in the layout.
#[derive(Clone, Debug)]
pub struct BottomRow {

View File

@ -55,11 +55,12 @@ impl FromStr for ColourScheme {
}
}
/// Handles the canvas' state.
/// Handles some state used while painting.
pub struct Painter {
pub colours: CanvasStyling,
height: u16,
width: u16,
prev_height: u16,
prev_width: u16,
styled_help_text: Vec<Line<'static>>,
// TODO: Redo this entire thing.
@ -153,8 +154,8 @@ impl Painter {
let mut painter = Painter {
colours: styling,
height: 0,
width: 0,
prev_height: 0,
prev_width: 0,
styled_help_text: Vec::default(),
row_constraints,
col_constraints,
@ -244,12 +245,12 @@ impl Painter {
let terminal_height = terminal_size.height;
let terminal_width = terminal_size.width;
if (self.height == 0 && self.width == 0)
|| (self.height != terminal_height || self.width != terminal_width)
if (self.prev_height == 0 && self.prev_width == 0)
|| (self.prev_height != terminal_height || self.prev_width != terminal_width)
{
app_state.is_force_redraw = true;
self.height = terminal_height;
self.width = terminal_width;
self.prev_height = terminal_height;
self.prev_width = terminal_width;
}
if app_state.should_get_widget_bounds() {

View File

@ -1 +1 @@
//! How to draw a container that has its children displayed vertically.

View File

@ -1 +1 @@
//! How to draw a container that has its children displayed horizontally.

View File

@ -27,6 +27,7 @@ pub mod constants;
pub mod data_collection;
pub mod data_conversion;
pub mod options;
pub mod tuine;
pub mod widgets;
use std::{

33
src/tuine.rs Normal file
View File

@ -0,0 +1,33 @@
//! tuine helps "tie" together ratatui/tui-rs and some layout/event logic to abstract away a bunch of the logic.
mod constraints;
mod container;
mod element;
mod widget;
pub use container::*;
pub use element::*;
pub use widget::*;
use crate::app::layout_manager::BottomLayout;
/// The overall widget tree.
///
/// TODO: The current implementation is a bit WIP while I transition things over.
pub struct WidgetTree {
root: Element,
}
impl WidgetTree {
/// Create a [`WidgetTree`].
///
/// TODO: The current implementation is a bit WIP while I transition things over.
pub fn new(layout: BottomLayout) -> Self {
Self { root: todo!() }
}
/// Draw the widget tree.
pub fn draw(&mut self) {}
}

154
src/tuine/constraints.rs Normal file
View File

@ -0,0 +1,154 @@
use tui::layout::{Direction, Rect};
use crate::canvas::LayoutConstraint;
pub(super) fn get_constraints(
direction: Direction, constraints: &[LayoutConstraint], area: Rect,
) -> Vec<Rect> {
// Order of operations:
// - Ratios first + canvas-handled (which is just zero)
// - Then any flex-grows to take up remaining space; divide amongst remaining
// hand out any remaining space
#[derive(Debug, Default, Clone, Copy)]
struct Size {
width: u16,
height: u16,
}
impl Size {
fn shrink_width(&mut self, amount: u16) {
self.width -= amount;
}
fn shrink_height(&mut self, amount: u16) {
self.height -= amount;
}
}
let mut bounds = Size {
width: area.width,
height: area.height,
};
let mut sizes = vec![Size::default(); constraints.len()];
let mut grow = vec![];
let mut num_non_ch = 0;
for (itx, (constraint, size)) in constraints.iter().zip(sizes.iter_mut()).enumerate() {
match constraint {
LayoutConstraint::Ratio(a, b) => {
match direction {
Direction::Horizontal => {
let amount = (((area.width as u32) * (*a)) / (*b)) as u16;
bounds.shrink_width(amount);
size.width = amount;
size.height = area.height;
}
Direction::Vertical => {
let amount = (((area.height as u32) * (*a)) / (*b)) as u16;
bounds.shrink_height(amount);
size.width = area.width;
size.height = amount;
}
}
num_non_ch += 1;
}
LayoutConstraint::Grow => {
// Mark it as grow in the vector and handle in second pass.
grow.push(itx);
num_non_ch += 1;
}
LayoutConstraint::CanvasHandled => {
// Do nothing in this case. It's already 0.
}
}
}
if !grow.is_empty() {
match direction {
Direction::Horizontal => {
let width = bounds.width / grow.len() as u16;
bounds.shrink_width(width * grow.len() as u16);
for g in grow {
sizes[g] = Size {
width,
height: area.height,
};
}
}
Direction::Vertical => {
let height = bounds.height / grow.len() as u16;
bounds.shrink_height(height * grow.len() as u16);
for g in grow {
sizes[g] = Size {
width: area.width,
height,
};
}
}
}
}
if num_non_ch > 0 {
match direction {
Direction::Horizontal => {
let per_item = bounds.width / num_non_ch;
let mut remaining_width = bounds.width % num_non_ch;
for (size, constraint) in sizes.iter_mut().zip(constraints) {
match constraint {
LayoutConstraint::CanvasHandled => {}
LayoutConstraint::Grow | LayoutConstraint::Ratio(_, _) => {
if remaining_width > 0 {
size.width += per_item + 1;
remaining_width -= 1;
} else {
size.width += per_item;
}
}
}
}
}
Direction::Vertical => {
let per_item = bounds.height / num_non_ch;
let mut remaining_height = bounds.height % num_non_ch;
for (size, constraint) in sizes.iter_mut().zip(constraints) {
match constraint {
LayoutConstraint::CanvasHandled => {}
LayoutConstraint::Grow | LayoutConstraint::Ratio(_, _) => {
if remaining_height > 0 {
size.height += per_item + 1;
remaining_height -= 1;
} else {
size.height += per_item;
}
}
}
}
}
}
}
let mut curr_x = area.x;
let mut curr_y = area.y;
sizes
.into_iter()
.map(|size| {
let rect = Rect::new(curr_x, curr_y, size.width, size.height);
match direction {
Direction::Horizontal => {
curr_x += size.width;
}
Direction::Vertical => {
curr_y += size.height;
}
}
rect
})
.collect()
}
#[cfg(test)]
mod test {
// TODO: Add some tests.
}

27
src/tuine/container.rs Normal file
View File

@ -0,0 +1,27 @@
use crate::canvas::LayoutConstraint;
use super::Element;
/// A [`ContainerDirection`] determines the direction of the [`Container`].
pub enum ContainerDirection {
Row,
Column,
}
/// A [`Container`] holds either more containers or a [`BottomWidget`].
///
/// Basically, a non-leaf node in the [`Element`] tree.
pub struct Container {
direction: ContainerDirection,
constraint: LayoutConstraint,
pub(super) children: Vec<Element>,
}
impl Container {
pub fn draw(&mut self) {
match self.direction {
ContainerDirection::Row => {}
ContainerDirection::Column => {}
}
}
}

16
src/tuine/element.rs Normal file
View File

@ -0,0 +1,16 @@
use super::Container;
/// A widget within bottom.
///
/// We use an enum to represent them to avoid dynamic dispatch.
pub enum BottomWidget {}
impl BottomWidget {}
/// An [`Element`] represents a node in the overall layout tree.
pub enum Element {
BottomWidget(BottomWidget),
Container(Container),
}
impl Element {}

7
src/tuine/widget.rs Normal file
View File

@ -0,0 +1,7 @@
use tui::{layout::Rect, Frame};
/// A [`Widget`] converts raw data into something that a user can see and interact with.
pub trait Widget<Data> {
/// How to actually draw the widget to the terminal.
fn draw(&self, f: &mut Frame<'_>, draw_location: Rect, widget_id: u64);
}

View File

@ -13,11 +13,3 @@ pub use mem_graph::*;
pub use net_graph::*;
pub use process_table::*;
pub use temperature_table::*;
use tui::{layout::Rect, Frame};
/// A [`Widget`] converts raw data into something that a user can see and interact with.
pub trait Widget<Data> {
/// How to actually draw the widget to the terminal.
fn draw(&self, f: &mut Frame<'_>, draw_location: Rect, widget_id: u64);
}