mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-04-08 17:05:59 +02:00
temp work
This commit is contained in:
parent
dbadbb996c
commit
c730048c7a
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -174,6 +174,7 @@ dependencies = [
|
||||
"kstring",
|
||||
"libc",
|
||||
"log",
|
||||
"lru",
|
||||
"mach2",
|
||||
"nvml-wrapper",
|
||||
"predicates",
|
||||
|
@ -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"] }
|
||||
|
@ -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 {
|
||||
|
@ -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() {
|
||||
|
@ -1 +1 @@
|
||||
|
||||
//! How to draw a container that has its children displayed vertically.
|
||||
|
@ -1 +1 @@
|
||||
|
||||
//! How to draw a container that has its children displayed horizontally.
|
||||
|
@ -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
33
src/tuine.rs
Normal 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
154
src/tuine/constraints.rs
Normal 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
27
src/tuine/container.rs
Normal 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
16
src/tuine/element.rs
Normal 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
7
src/tuine/widget.rs
Normal 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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user