Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IN PROGRESS] refactor: Refactor scrollable table widgets #265

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"cmdline",
"commandline",
"concat",
"coord",
"crossterm",
"curr",
"cvar",
Expand Down
8 changes: 6 additions & 2 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use layout_manager::*;
pub use states::*;

use crate::{
canvas, constants,
canvas,
components::ScrollDirection,
constants,
options::Config,
options::ConfigFlags,
options::WidgetIdEnabled,
Expand Down Expand Up @@ -126,6 +128,7 @@ pub struct App {
pub filters: DataFilters,
pub config: Config,
pub config_path: Option<PathBuf>,
pub config_page_settings: Vec<MainConfigState>,
}

impl App {
Expand Down Expand Up @@ -1236,7 +1239,7 @@ impl App {
}
}
'C' => {
// self.open_config(),
// self.open_config_screen();
}
'c' => {
if let BottomWidgetType::Proc = self.current_widget.widget_type {
Expand Down Expand Up @@ -2593,6 +2596,7 @@ impl App {
}

// Now handle click propagation down to widget.
// self.current_widget.on_click(MouseButton::Left, Coordinate {x, y});
if let Some((_tlc_x, tlc_y)) = &self.current_widget.top_left_corner {
match &self.current_widget.widget_type {
BottomWidgetType::Proc
Expand Down
1 change: 1 addition & 0 deletions src/app/process_killer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub fn kill_process_given_pid(pid: Pid) -> crate::utils::error::Result<()> {
if cfg!(target_family = "unix") {
#[cfg(any(target_family = "unix"))]
{
// FIXME: [KILL] Forbid negative PID killing in unix
let output = unsafe { libc::kill(pid as i32, libc::SIGTERM) };
if output != 0 {
// We had an error...
Expand Down
47 changes: 21 additions & 26 deletions src/app/states.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,12 @@ use tui::widgets::TableState;

use crate::{
app::{layout_manager::BottomWidgetType, query::*},
components::ScrollDirection,
constants,
data_harvester::processes::{self, ProcessSorting},
};
use ProcessSorting::*;

#[derive(Debug)]
pub enum ScrollDirection {
// UP means scrolling up --- this usually DECREMENTS
Up,
// DOWN means scrolling down --- this usually INCREMENTS
Down,
}

impl Default for ScrollDirection {
fn default() -> Self {
ScrollDirection::Down
}
}

#[derive(Debug)]
pub enum CursorDirection {
Left,
Expand All @@ -34,6 +21,8 @@ pub enum CursorDirection {
/// AppScrollWidgetState deals with fields for a scrollable app's current state.
#[derive(Default)]
pub struct AppScrollWidgetState {
pub column_headers: Vec<String>,
pub column_contents: Vec<Vec<String>>,
pub current_scroll_position: usize,
pub previous_scroll_position: usize,
pub scroll_direction: ScrollDirection,
Expand Down Expand Up @@ -802,24 +791,30 @@ impl BatteryState {
}
}

// FIXME: [REFACTOR] Unify scroll state tracking implementations under one struct.
#[derive(Default)]
pub struct ParagraphScrollState {
pub current_scroll_index: u16,
pub max_scroll_index: u16,
}

#[derive(Default)]
pub struct ConfigState {
pub current_category_index: usize,
pub category_list: Vec<ConfigCategory>,
}

#[derive(Default)]
pub struct ConfigCategory {
pub struct MainConfigState {
pub category_name: &'static str,
pub options_list: Vec<ConfigOption>,
}

pub struct ConfigOption {
pub set_function: Box<dyn Fn() -> anyhow::Result<()>>,
pub config_sub_options: Vec<ConfigSubOptions>,
}

pub struct ConfigSubOptions {
/// The option's name.
pub option_name: &'static str,
/// The option's description.
pub description: &'static str,
/// How it handles drawing in an additional Block. If this does is None,
/// then nothing additional will be drawn here.
pub draw_fn: Option<Box<dyn Fn()>>,
/// How it handles inputs. For example, scroll states, mouse inputs, keyboard inputs, etc.
/// must be handled by the option itself.
pub input_fn: Box<dyn Fn()>,
/// How it updates the config. Must be handled by the option itself.
pub update_fn: Box<dyn Fn()>,
}
7 changes: 4 additions & 3 deletions src/canvas/canvas_colours.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub struct CanvasColours {
pub text_style: Style,
pub widget_title_style: Style,
pub graph_style: Style,
// Full, Medium, Low
// Order is full, medium, and low
pub battery_bar_styles: Vec<Style>,
pub invalid_query_style: Style,
pub disabled_text_style: Style,
Expand Down Expand Up @@ -88,8 +88,9 @@ impl CanvasColours {

pub fn set_table_header_colour(&mut self, colour: &str) -> error::Result<()> {
self.table_header_style = get_style_from_config(colour)?;
// Disabled as it seems to be bugged when I go into full command mode...? It becomes huge lol
// self.table_header_style = get_style_from_config(colour)?.modifier(Modifier::BOLD);
// TODO: Make arrows not bolded, rest of text bolded (if enabled)
// self.table_header_style =
// get_style_from_config(colour)?.add_modifier(tui::style::Modifier::BOLD);
Ok(())
}

Expand Down
8 changes: 4 additions & 4 deletions src/canvas/drawing_utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::app;
use crate::{app, components::ScrollDirection};
use std::cmp::{max, min};

/// Return a (hard)-width vector for column widths.
Expand Down Expand Up @@ -145,15 +145,15 @@ pub fn get_search_start_position(
}

pub fn get_start_position(
num_rows: usize, scroll_direction: &app::ScrollDirection, scroll_position_bar: &mut usize,
num_rows: usize, scroll_direction: &ScrollDirection, scroll_position_bar: &mut usize,
currently_selected_position: usize, is_force_redraw: bool,
) -> usize {
if is_force_redraw {
*scroll_position_bar = 0;
}

match scroll_direction {
app::ScrollDirection::Down => {
ScrollDirection::Down => {
if currently_selected_position < *scroll_position_bar + num_rows {
// If, using previous_scrolled_position, we can see the element
// (so within that and + num_rows) just reuse the current previously scrolled position
Expand All @@ -168,7 +168,7 @@ pub fn get_start_position(
0
}
}
app::ScrollDirection::Up => {
ScrollDirection::Up => {
if currently_selected_position <= *scroll_position_bar {
// If it's past the first element, then show from that element downwards
*scroll_position_bar = currently_selected_position;
Expand Down
47 changes: 18 additions & 29 deletions src/canvas/screens/config_screen.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![allow(unused_variables)] //FIXME: Remove this
#![allow(unused_imports)] //FIXME: Remove this
#![allow(unused_variables)]
#![allow(unused_imports)]
use crate::{app::App, canvas::Painter, constants};
use tui::{
backend::Backend,
Expand All @@ -9,7 +9,8 @@ use tui::{
layout::{Alignment, Rect},
terminal::Frame,
text::Span,
widgets::{Block, Borders, Paragraph},
text::Spans,
widgets::{Block, Borders, Paragraph, Tabs},
};

pub trait ConfigScreen {
Expand All @@ -23,36 +24,24 @@ impl ConfigScreen for Painter {
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect,
) {
let config_block = Block::default()
.title(" Config ") // FIXME: [Config] missing title styling
.title(Span::styled(" Config ", self.colours.widget_title_style))
.style(self.colours.border_style)
.borders(Borders::ALL)
.border_style(self.colours.border_style);

f.render_widget(config_block, draw_loc);
let titles: Vec<Spans<'_>> = app_state
.config_page_settings
.iter()
.map(|category| Spans::from(category.category_name))
.collect();

// let margined_draw_locs = Layout::default()
// .margin(2)
// .direction(Direction::Horizontal)
// .constraints(
// [
// Constraint::Percentage(33),
// Constraint::Percentage(34),
// Constraint::Percentage(33),
// ]
// )
// .split(draw_loc)
// .into_iter()
// .map(|loc| {
// // Required to properly margin in *between* the rectangles.
// Layout::default()
// .horizontal_margin(1)
// .constraints([Constraint::Percentage(100)])
// .split(loc)[0]
// })
// .collect::<Vec<Rect>>();

// for dl in margined_draw_locs {
// f.render_widget(Block::default().borders(Borders::ALL), dl);
// }
f.render_widget(
Tabs::new(titles)
.block(config_block)
.divider(tui::symbols::line::VERTICAL)
.style(self.colours.text_style)
.highlight_style(self.colours.currently_selected_text_style),
draw_loc,
)
}
}
4 changes: 2 additions & 2 deletions src/clap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ inspired by htop's.\n\n",
);
let battery = Arg::with_name("battery")
.long("battery")
.help("Shows the battery widget.")
.help("Shows the battery widget in default/basic mode.")
.long_help(
"\
Shows the battery widget in default or basic mode. No effect on
Shows the battery widget in default/basic mode. No effect on
custom layouts.\n\n",
);
let case_sensitive = Arg::with_name("case_sensitive")
Expand Down
51 changes: 51 additions & 0 deletions src/components/base_traits/base_widget.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use crate::app::layout_manager::{BottomWidget, BottomWidgetType};

use super::{Drawable, HandleClick, HandleKeyInputs, HandleScroll};

#[derive(Default, Debug)]
pub struct Coordinate {
pub x: u16,
pub y: u16,
}

#[derive(Default, Debug)]
pub struct WidgetCorners {
pub top_left_corner: Coordinate,
pub bottom_right_corner: Coordinate,
}

pub trait BaseWidget: HandleClick + HandleScroll + HandleKeyInputs + Drawable {
/// Get the widget bounds - returns the top left corner (TLC) and the bottom
/// right corner (BRC).
fn get_widget_bounds(&self) -> Option<WidgetCorners>;

/// Get if a border is being drawn around this widget.
fn is_drawing_borders(&self) -> bool {
self.is_drawing_horizontal_borders() && self.is_drawing_vertical_borders()
}

/// Get if horizontal borders are being drawn around this widget.
fn is_drawing_horizontal_borders(&self) -> bool;

/// Get if vertical borders are being drawn around this widget.
fn is_drawing_vertical_borders(&self) -> bool;

/// Obtain the widget ID.
fn get_widget_id(&self) -> u64 {
self.get_bottom_widget_details().widget_id
}

/// Obtain the widget type.
fn get_widget_type(&self) -> &BottomWidgetType {
&self.get_bottom_widget_details().widget_type
}

/// Obtain the widget layout details.
fn get_bottom_widget_details(&self) -> &BottomWidget;
}

pub trait BaseTableWidget: BaseWidget {
fn get_table_gap(&self) -> u16;
}

pub trait BaseGraphWidget: BaseWidget {}
9 changes: 9 additions & 0 deletions src/components/base_traits/drawable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use tui::{backend::Backend, layout::Rect, Frame};

use crate::app::App;

pub trait Drawable {
fn draw<B: Backend>(
&mut self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect, is_force_redraw: bool,
);
}
25 changes: 25 additions & 0 deletions src/components/base_traits/events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crossterm::event::KeyEvent;

use super::Coordinate;

pub trait HandleKeyInputs {
/// How to handle a key input
fn on_char(&mut self, key_input: KeyEvent);
}

pub trait HandleScroll {
fn on_scroll_up(&mut self);

fn on_scroll_down(&mut self);
}

pub enum MouseButton {
Left,
Middle,
Right,
}

pub trait HandleClick {
/// How to handle a click.
fn on_click(&mut self, button: MouseButton, click_coord: Coordinate);
}
7 changes: 7 additions & 0 deletions src/components/base_traits/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pub mod base_widget;
pub mod drawable;
pub mod events;

pub use base_widget::*;
pub use drawable::*;
pub use events::*;
5 changes: 5 additions & 0 deletions src/components/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pub mod base_traits;
pub mod scrollable_table;

pub use base_traits::*;
pub use scrollable_table::*;
Loading