Add frozen

This commit is contained in:
ClementTsang 2021-12-28 04:09:07 -05:00
parent a78edc88c0
commit 95318bb3e4
7 changed files with 55 additions and 142 deletions

View File

@ -151,11 +151,6 @@ pub struct AppState {
pub app_config_fields: AppConfigFields,
// --- NEW STUFF ---
pub selected_widget: NodeId,
pub widget_lookup_map: FxHashMap<NodeId, BottomWidget>,
pub layout_tree: Arena<LayoutNode>,
pub layout_tree_root: NodeId,
frozen_state: FrozenState,
current_screen: CurrentScreen,
painter: Painter,
@ -180,10 +175,6 @@ impl AppState {
app_config_fields,
filters,
used_widgets,
selected_widget,
widget_lookup_map,
layout_tree,
layout_tree_root,
painter,
// Use defaults.
@ -226,8 +217,14 @@ impl Application for AppState {
self.set_current_screen(CurrentScreen::Help);
true
}
AppMessages::ConfirmKillProcess { to_kill } => true,
AppMessages::KillProcess { to_kill, signal } => true,
AppMessages::ConfirmKillProcess { to_kill } => {
// FIXME: Handle confirmation
true
}
AppMessages::KillProcess { to_kill, signal } => {
// FIXME: Handle process termination
true
}
AppMessages::ToggleFreeze => {
self.frozen_state.toggle(&self.data_collection);
true
@ -302,27 +299,26 @@ impl Application for AppState {
}
fn global_event_handler(
&mut self, event: crate::tuine::Event, messages: &mut Vec<Self::Message>,
&mut self, event: crate::tuine::Event, messages: &mut Vec<AppMessages>,
) -> Status {
use crate::tuine::Event;
use crossterm::event::{KeyCode, KeyModifiers};
fn on_quit(messages: &mut Vec<AppMessages>) -> Status {
messages.push(AppMessages::Quit);
Status::Captured
}
match event {
Event::Keyboard(event) => {
if event.modifiers.is_empty() {
match event.code {
KeyCode::Char('q') | KeyCode::Char('Q') => {
messages.push(AppMessages::Quit);
Status::Captured
}
KeyCode::Char('q') | KeyCode::Char('Q') => on_quit(messages),
_ => Status::Ignored,
}
} else if let KeyModifiers::CONTROL = event.modifiers {
match event.code {
KeyCode::Char('c') | KeyCode::Char('C') => {
messages.push(AppMessages::Quit);
Status::Captured
}
KeyCode::Char('c') | KeyCode::Char('C') => on_quit(messages),
KeyCode::Char('r') | KeyCode::Char('R') => {
messages.push(AppMessages::Reset);
Status::Captured

View File

@ -175,7 +175,7 @@ impl Default for DataCollection {
}
}
// TODO: Just rip this out, store only stringified data...?
// TODO: Just rip this out, store only stringified data...? Hm.
impl DataCollection {
pub fn reset(&mut self) {
self.timed_data_vec = Default::default();

View File

@ -118,124 +118,4 @@ impl Painter {
Ok(())
}
fn draw_frozen_indicator<B: Backend>(&self, f: &mut Frame<'_, B>, draw_loc: Rect) {
f.render_widget(
Paragraph::new(Span::styled(
"Frozen, press 'f' to unfreeze",
self.colours.currently_selected_text_style,
)),
Layout::default()
.horizontal_margin(1)
.constraints([Constraint::Length(1)])
.split(draw_loc)[0],
)
}
pub fn draw_data<B: Backend>(
&mut self, terminal: &mut Terminal<B>, app_state: &mut app::AppState,
) -> error::Result<()> {
terminal.draw(|mut f| {
let (draw_area, frozen_draw_loc) = if false {
let split_loc = Layout::default()
.constraints([Constraint::Min(0), Constraint::Length(1)])
.split(f.size());
(split_loc[0], Some(split_loc[1]))
} else {
(f.size(), None)
};
let terminal_height = draw_area.height;
let terminal_width = draw_area.width;
if false {
if let Some(frozen_draw_loc) = frozen_draw_loc {
self.draw_frozen_indicator(&mut f, frozen_draw_loc);
}
if let Some(current_widget) = app_state
.widget_lookup_map
.get_mut(&app_state.selected_widget)
{
current_widget.set_bounds(draw_area);
current_widget.draw(self, f, draw_area, true, true);
}
} else {
/// A simple traversal through the `arena`, drawing all leaf elements.
fn traverse_and_draw_tree<B: Backend>(
node: NodeId, arena: &Arena<LayoutNode>, f: &mut Frame<'_, B>,
lookup_map: &mut FxHashMap<NodeId, BottomWidget>, painter: &Painter,
selected_id: NodeId, offset_x: u16, offset_y: u16,
) {
if let Some(layout_node) = arena.get(node).map(|n| n.get()) {
match layout_node {
LayoutNode::Row(RowLayout { bound, .. })
| LayoutNode::Col(ColLayout { bound, .. }) => {
for child in node.children(arena) {
traverse_and_draw_tree(
child,
arena,
f,
lookup_map,
painter,
selected_id,
offset_x + bound.x,
offset_y + bound.y,
);
}
}
LayoutNode::Widget(widget_layout) => {
let bound = widget_layout.bound;
let area = Rect::new(
bound.x + offset_x,
bound.y + offset_y,
bound.width,
bound.height,
);
if let Some(widget) = lookup_map.get_mut(&node) {
if let BottomWidget::Carousel(carousel) = widget {
let remaining_area: Rect =
carousel.draw_carousel(painter, f, area);
if let Some(to_draw_node) =
carousel.get_currently_selected()
{
if let Some(child_widget) =
lookup_map.get_mut(&to_draw_node)
{
child_widget.set_bounds(remaining_area);
child_widget.draw(
painter,
f,
remaining_area,
selected_id == node,
false,
);
}
}
} else {
widget.set_bounds(area);
widget.draw(painter, f, area, selected_id == node, false);
}
}
}
}
}
}
if let Some(frozen_draw_loc) = frozen_draw_loc {
self.draw_frozen_indicator(&mut f, frozen_draw_loc);
}
let root = &app_state.layout_tree_root;
let arena = &mut app_state.layout_tree;
let selected_id = app_state.selected_widget;
generate_layout(*root, arena, draw_area, &app_state.widget_lookup_map);
let lookup_map = &mut app_state.widget_lookup_map;
traverse_and_draw_tree(*root, arena, f, lookup_map, self, selected_id, 0, 0);
}
})?;
Ok(())
}
}

View File

@ -0,0 +1,32 @@
use tui::{
layout::{Constraint, Layout},
style::Style,
text::Span,
widgets::Paragraph,
};
use crate::tuine::TmpComponent;
/// A small banner to display that the app is "frozen" from data updates.
pub struct FrozenBanner {
style: Style,
}
impl<Message> TmpComponent<Message> for FrozenBanner {
fn draw<Backend>(
&mut self, _state_ctx: &mut crate::tuine::StateContext<'_>,
draw_ctx: &crate::tuine::DrawContext<'_>, frame: &mut tui::Frame<'_, Backend>,
) where
Backend: tui::backend::Backend,
{
let rect = draw_ctx.global_rect();
frame.render_widget(
Paragraph::new(Span::styled("Frozen, press 'f' to unfreeze", self.style)),
Layout::default()
.horizontal_margin(1)
.constraints([Constraint::Length(1)])
.split(rect)[0],
)
}
}

View File

@ -0,0 +1,2 @@
pub mod frozen_banner;
pub use frozen_banner::*;

View File

@ -7,6 +7,9 @@ pub use widget::*;
pub mod stateful;
pub use stateful::*;
pub mod banner;
pub use banner::*;
// pub mod stateless;
// pub use stateless::*;

View File

@ -1,4 +1,4 @@
use crate::tuine::{State, StateContext, ViewContext};
use crate::tuine::{State, ViewContext};
use super::TmpComponent;