Skip to content

Commit

Permalink
refactor: Create a prototype time graph element
Browse files Browse the repository at this point in the history
Move some state content over

refactor: rename folder

refactor: More renaming and pruning of old unused code.

Create a prototype time graph element

scrollable table

Temporarily add dead code allows

Minor refactorings
  • Loading branch information
ClementTsang committed Jun 12, 2021
1 parent 0413045 commit a0feabc
Show file tree
Hide file tree
Showing 27 changed files with 1,402 additions and 88 deletions.
16 changes: 8 additions & 8 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ pub struct AppConfigFields {
#[derive(TypedBuilder)]
pub struct AppState {
#[builder(default = false, setter(skip))]
awaiting_second_char: bool,
awaiting_second_char: bool, // TODO: Move out to input

#[builder(default, setter(skip))]
second_char: Option<char>,
second_char: Option<char>, // TODO: Move out to input

#[builder(default, setter(skip))]
pub dd_err: Option<String>,
Expand All @@ -83,7 +83,7 @@ pub struct AppState {
pub is_frozen: bool,

#[builder(default = Instant::now(), setter(skip))]
last_key_press: Instant,
last_key_press: Instant, // TODO: Move out to input

#[builder(default, setter(skip))]
pub canvas_data: canvas::DisplayableData,
Expand Down Expand Up @@ -129,11 +129,11 @@ pub struct AppState {
}

#[cfg(target_os = "windows")]
const MAX_SIGNAL: usize = 1;
const MAX_KILL_SIGNAL: usize = 1;
#[cfg(target_os = "linux")]
const MAX_SIGNAL: usize = 64;
const MAX_KILL_SIGNAL: usize = 64;
#[cfg(target_os = "macos")]
const MAX_SIGNAL: usize = 31;
const MAX_KILL_SIGNAL: usize = 31;

impl AppState {
pub fn reset(&mut self) {
Expand Down Expand Up @@ -966,7 +966,7 @@ impl AppState {
if self.delete_dialog_state.is_showing_dd {
let mut new_signal = match self.delete_dialog_state.selected_signal {
KillSignal::Cancel => 8,
KillSignal::Kill(signal) => min(signal + 8, MAX_SIGNAL),
KillSignal::Kill(signal) => min(signal + 8, MAX_KILL_SIGNAL),
};
if new_signal > 31 && new_signal < 42 {
new_signal += 2;
Expand Down Expand Up @@ -2132,7 +2132,7 @@ impl AppState {
.max_scroll_index
.saturating_sub(1);
} else if self.delete_dialog_state.is_showing_dd {
self.delete_dialog_state.selected_signal = KillSignal::Kill(MAX_SIGNAL);
self.delete_dialog_state.selected_signal = KillSignal::Kill(MAX_KILL_SIGNAL);
}
}

Expand Down
20 changes: 1 addition & 19 deletions src/app/layout_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -947,25 +947,7 @@ impl std::str::FromStr for BottomWidgetType {
"empty" => Ok(BottomWidgetType::Empty),
"battery" | "batt" => Ok(BottomWidgetType::Battery),
_ => Err(BottomError::ConfigError(format!(
"\"{}\" is an invalid widget name.
Supported widget names:
+--------------------------+
| cpu |
+--------------------------+
| mem, memory |
+--------------------------+
| net, network |
+--------------------------+
| proc, process, processes |
+--------------------------+
| temp, temperature |
+--------------------------+
| disk |
+--------------------------+
| batt, battery |
+--------------------------+
",
"\"{}\" is an invalid widget name.",
s
))),
}
Expand Down
1 change: 0 additions & 1 deletion src/app/widget_states/graph_state.rs

This file was deleted.

4 changes: 2 additions & 2 deletions src/app/widget_states/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub enum CursorDirection {
}

/// AppScrollWidgetState deals with fields for a scrollable app's current state.
#[derive(Default)]
#[derive(Debug, Default)]
pub struct AppScrollWidgetState {
pub current_scroll_position: usize,
pub previous_scroll_position: usize,
Expand Down Expand Up @@ -99,7 +99,7 @@ impl Default for AppHelpDialogState {
}

/// Meant for canvas operations involving table column widths.
#[derive(Default)]
#[derive(Debug, Default)]
pub struct CanvasTableWidthState {
pub desired_column_widths: Vec<u16>,
pub calculated_column_widths: Vec<u16>,
Expand Down
1 change: 0 additions & 1 deletion src/app/widget_states/table_state.rs

This file was deleted.

78 changes: 47 additions & 31 deletions src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#[macro_use]
extern crate log;

use bottom::{canvas, constants::*, data_conversion::*, options::*, *};
use bottom::{canvas, data_conversion::*, options::*, *};

use std::{
boxed::Box,
Expand Down Expand Up @@ -61,6 +61,30 @@ fn main() -> Result<()> {
get_color_scheme(&matches, &config)?,
)?;

// Set up up tui and crossterm
let mut stdout_val = stdout();
execute!(stdout_val, EnterAlternateScreen, EnableMouseCapture)?;
enable_raw_mode()?;

let mut terminal = Terminal::new(CrosstermBackend::new(stdout_val))?;
terminal.clear()?;
terminal.hide_cursor()?;

// Set panic hook
panic::set_hook(Box::new(|info| panic_hook(info)));

// Set termination hook
let is_terminated = Arc::new(AtomicBool::new(false));
{
let is_terminated = is_terminated.clone();
ctrlc::set_handler(move || {
is_terminated.store(true, Ordering::SeqCst);
})?;
}
let mut first_pass = true;

// ===== Start of actual thread creation and loop =====

// Create termination mutex and cvar
#[allow(clippy::mutex_atomic)]
let thread_termination_lock = Arc::new(Mutex::new(false));
Expand Down Expand Up @@ -107,46 +131,34 @@ fn main() -> Result<()> {
app.used_widgets.clone(),
);

// Set up up tui and crossterm
let mut stdout_val = stdout();
execute!(stdout_val, EnterAlternateScreen, EnableMouseCapture)?;
enable_raw_mode()?;

let mut terminal = Terminal::new(CrosstermBackend::new(stdout_val))?;
terminal.clear()?;
terminal.hide_cursor()?;

// Set panic hook
panic::set_hook(Box::new(|info| panic_hook(info)));

// Set termination hook
let is_terminated = Arc::new(AtomicBool::new(false));
let ist_clone = is_terminated.clone();
ctrlc::set_handler(move || {
ist_clone.store(true, Ordering::SeqCst);
})?;
let mut first_run = true;

while !is_terminated.load(Ordering::SeqCst) {
if let Ok(recv) = receiver.recv_timeout(Duration::from_millis(TICK_RATE_IN_MILLISECONDS)) {
if let Ok(recv) = receiver.recv() {
match recv {
BottomEvent::KeyInput(event) => {
if handle_key_event_or_break(event, &mut app, &collection_thread_ctrl_sender) {
break;
}
handle_force_redraws(&mut app);

if try_drawing(&mut terminal, &mut app, &mut painter).is_err() {
break;
}
}
BottomEvent::MouseInput(event) => {
handle_mouse_event(event, &mut app);
handle_force_redraws(&mut app);

if try_drawing(&mut terminal, &mut app, &mut painter).is_err() {
break;
}
}
BottomEvent::Update(data) => {
app.data_collection.eat_data(data);

// This thing is required as otherwise, some widgets can't draw correctly w/o
// some data (or they need to be re-drawn).
if first_run {
first_run = false;
if first_pass {
first_pass = false;
app.is_force_redraw = true;
}

Expand Down Expand Up @@ -221,25 +233,29 @@ fn main() -> Result<()> {
convert_battery_harvest(&app.data_collection);
}
}

if try_drawing(&mut terminal, &mut app, &mut painter).is_err() {
break;
}
}
BottomEvent::Clean => {
app.data_collection
.clean_data(constants::STALE_MAX_MILLISECONDS);
}
BottomEvent::RequestRedraw => {
if try_drawing(&mut terminal, &mut app, &mut painter).is_err() {
break;
}
}
}
}

// TODO: [OPT] Should not draw if no change (ie: scroll max)
try_drawing(&mut terminal, &mut app, &mut painter)?;
}

// I think doing it in this order is safe...

*thread_termination_lock.lock().unwrap() = true;

thread_termination_cvar.notify_all();

cleanup_terminal(&mut terminal)?;

// ===== End of actual thread creation and loop =====

Ok(())
}
6 changes: 4 additions & 2 deletions src/canvas/dialogs/dd_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ pub trait KillDialog {
);

fn draw_dd_dialog<B: Backend>(
&self, f: &mut Frame<'_, B>, dd_text: Option<Text<'_>>, app_state: &mut AppState, draw_loc: Rect,
&self, f: &mut Frame<'_, B>, dd_text: Option<Text<'_>>, app_state: &mut AppState,
draw_loc: Rect,
) -> bool;
}

Expand Down Expand Up @@ -318,7 +319,8 @@ impl KillDialog for Painter {
}

fn draw_dd_dialog<B: Backend>(
&self, f: &mut Frame<'_, B>, dd_text: Option<Text<'_>>, app_state: &mut AppState, draw_loc: Rect,
&self, f: &mut Frame<'_, B>, dd_text: Option<Text<'_>>, app_state: &mut AppState,
draw_loc: Rect,
) -> bool {
if let Some(dd_text) = dd_text {
let dd_title = if app_state.dd_err.is_some() {
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ static DISK_HEADERS_LENS: Lazy<Vec<u16>> = Lazy::new(|| {

pub trait DiskTableWidget {
fn draw_disk_table<B: Backend>(
&self, f: &mut Frame<'_, B>, app_state: &mut app::AppState, draw_loc: Rect, draw_border: bool,
widget_id: u64,
&self, f: &mut Frame<'_, B>, app_state: &mut app::AppState, draw_loc: Rect,
draw_border: bool, widget_id: u64,
);
}

impl DiskTableWidget for Painter {
fn draw_disk_table<B: Backend>(
&self, f: &mut Frame<'_, B>, app_state: &mut app::AppState, draw_loc: Rect, draw_border: bool,
widget_id: u64,
&self, f: &mut Frame<'_, B>, app_state: &mut app::AppState, draw_loc: Rect,
draw_border: bool, widget_id: u64,
) {
let recalculate_column_widths = app_state.should_get_widget_bounds();
if let Some(disk_widget_state) = app_state.disk_state.widget_states.get_mut(&widget_id) {
Expand Down
48 changes: 48 additions & 0 deletions src/canvas/elements/element.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#![allow(dead_code)]

use tui::{backend::Backend, layout::Rect, Frame};

use crate::{app::AppState, canvas::canvas_colours::CanvasColours};

/// A single point.
#[derive(Copy, Clone)]
pub struct Point {
pub x: u16,
pub y: u16,
}

/// The top-left and bottom-right corners of a [`Element`].
#[derive(Copy, Clone)]
pub enum ElementBounds {
Unset,
Points {
top_left_corner: Point,
bottom_right_corner: Point,
},
}

/// A basic [`Element`] trait, all drawn components must implement this.
pub trait Element {
/// The type of data that is expected for the [`Element`].

/// The main drawing function.
fn draw<B: Backend>(
&mut self, f: &mut Frame<'_, B>, app_state: &AppState, draw_loc: Rect,
style: &CanvasColours,
) -> anyhow::Result<()>;

/// Recalculates the click bounds.
fn recalculate_click_bounds(&mut self);

/// A function to determine the main widget click bounds.
fn click_bounds(&self) -> ElementBounds;

/// Returns whether am [`Element`] is selected.
fn is_selected(&self) -> bool;

/// Marks an [`Element`] as selected.
fn select(&mut self);

/// Marks an [`Element`] as unselected.
fn unselect(&mut self);
}
File renamed without changes.
File renamed without changes.
12 changes: 12 additions & 0 deletions src/canvas/widgets.rs → src/canvas/elements/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,15 @@ pub use network_basic::NetworkBasicWidget;
pub use network_graph::NetworkGraphWidget;
pub use process_table::ProcessTableWidget;
pub use temp_table::TempTableWidget;

pub mod element;
pub use element::Element;

pub mod scrollable_table;
pub use scrollable_table::ScrollableTable;

pub mod scroll_sort_table;
pub use scroll_sort_table::ScrollSortTable;

pub mod time_graph;
pub use time_graph::TimeGraph;
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit a0feabc

Please sign in to comment.