Skip to content

Commit

Permalink
change: Refactor dd drawing code
Browse files Browse the repository at this point in the history
This also slightly improves how we generate the widths/heights to be
less... terrible.

Note this is not done, unfortunately.  This requires tui-rs' wrapped
paragraph height PR to land and release so I can properly calculate the
height offsets.

See fdehau/tui-rs#349 for details.
  • Loading branch information
ClementTsang committed Aug 12, 2020
1 parent 60f4759 commit 6e38d73
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 83 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"Qudsi",
"Tebibytes",
"Ungrouped",
"WASD",
"Wojnarowski",
"andys",
"crossterm",
Expand Down
77 changes: 52 additions & 25 deletions src/canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,47 +243,74 @@ impl Painter {

self.draw_help_dialog(&mut f, app_state, middle_dialog_chunk[1]);
} else if app_state.delete_dialog_state.is_showing_dd {
let bordering = f.size().height.saturating_sub(7) / 2;
// TODO: This needs the paragraph wrap feature from tui-rs to be pushed to complete... but for now it's pretty close!
// The main problem right now is that I cannot properly calculate the height offset since
// line-wrapping is NOT the same as taking the width of the text and dividing by width.
// So, I need the height AFTER wrapping.
// See: https://github.com/fdehau/tui-rs/pull/349. Land this after this pushes to release.

let dd_text = self.get_dd_spans(app_state);

let (text_width, text_height) = if let Some(dd_text) = &dd_text {
let width = if f.size().width < 100 {
f.size().width * 90 / 100
} else {
let min_possible_width = (f.size().width * 50 / 100) as usize;
let mut width = dd_text.width();

// This should theoretically never allow width to be 0... we can be safe and do an extra check though.
while width > (f.size().width as usize) && width / 2 > min_possible_width {
width /= 2;
}

std::cmp::max(width, min_possible_width) as u16
};

(
width,
(dd_text.height() + 2 + (dd_text.width() / width as usize)) as u16,
)
} else {
// AFAIK this shouldn't happen, unless something went wrong...
(
if f.size().width < 100 {
f.size().width * 90 / 100
} else {
f.size().width * 50 / 100
},
7,
)
};

let vertical_bordering = f.size().height.saturating_sub(text_height) / 2;
let vertical_dialog_chunk = Layout::default()
.direction(Direction::Vertical)
.constraints(
[
Constraint::Length(bordering),
Constraint::Length(7),
Constraint::Length(bordering),
Constraint::Length(vertical_bordering),
Constraint::Length(text_height),
Constraint::Length(vertical_bordering),
]
.as_ref(),
)
.split(f.size());

let horizontal_bordering = f.size().width.saturating_sub(text_width) / 2;
let middle_dialog_chunk = Layout::default()
.direction(Direction::Horizontal)
.constraints(
if f.size().width < 100 {
// TODO: [REFACTOR] The point we start changing size at currently hard-coded in.
[
Constraint::Percentage(5),
Constraint::Percentage(90),
Constraint::Percentage(5),
]
} else {
[
Constraint::Percentage(30),
Constraint::Percentage(40),
Constraint::Percentage(30),
]
}
[
Constraint::Length(horizontal_bordering),
Constraint::Length(text_width),
Constraint::Length(horizontal_bordering),
]
.as_ref(),
)
.split(vertical_dialog_chunk[1]);

if let Some(dd_err) = &app_state.dd_err {
self.draw_dd_error_dialog(&mut f, dd_err, middle_dialog_chunk[1]);
} else {
// This is a bit nasty, but it works well... I guess.
app_state.delete_dialog_state.is_showing_dd =
self.draw_dd_dialog(&mut f, app_state, middle_dialog_chunk[1]);
}
// This is a bit nasty, but it works well... I guess.
app_state.delete_dialog_state.is_showing_dd =
self.draw_dd_dialog(&mut f, dd_text, app_state, middle_dialog_chunk[1]);
} else if app_state.is_expanded {
let rect = Layout::default()
.margin(0)
Expand Down
111 changes: 54 additions & 57 deletions src/canvas/dialogs/dd_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,23 @@ const DD_BASE: &str = " Confirm Kill Process ── Esc to close ";
const DD_ERROR_BASE: &str = " Error ── Esc to close ";

pub trait KillDialog {
fn get_dd_spans(&self, app_state: &App) -> Option<Text<'_>>;

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

fn draw_dd_error_dialog<B: Backend>(&self, f: &mut Frame<'_, B>, dd_err: &str, draw_loc: Rect);
}

impl KillDialog for Painter {
fn draw_dd_dialog<B: Backend>(
&self, f: &mut Frame<'_, B>, app_state: &mut App, draw_loc: Rect,
) -> bool {
if let Some(to_kill_processes) = app_state.get_to_delete_processes() {
fn get_dd_spans(&self, app_state: &App) -> Option<Text<'_>> {
if let Some(dd_err) = &app_state.dd_err {
return Some(Text::from(Spans::from(format!(
"\nFailure to properly kill the process - {}",
dd_err
))));
} else if let Some(to_kill_processes) = app_state.get_to_delete_processes() {
if let Some(first_pid) = to_kill_processes.1.first() {
let dd_text = Text::from(vec![
return Some(Text::from(vec![
Spans::from(vec![]),
Spans::from(vec![
if app_state.is_grouped(app_state.current_widget.widget_id) {
Expand Down Expand Up @@ -62,33 +65,59 @@ impl KillDialog for Painter {
Span::styled("No", self.colours.currently_selected_text_style)
},
]),
]);
Spans::from(vec![]),
]));
}
}

let dd_title = Span::styled(
None
}

fn draw_dd_dialog<B: Backend>(
&self, f: &mut Frame<'_, B>, dd_text: Option<Text<'_>>, app_state: &App, draw_loc: Rect,
) -> bool {
if let Some(dd_text) = dd_text {
let dd_title = if app_state.dd_err.is_some() {
Span::styled(
format!(
" Error ─{}─ Esc to close ",
"─".repeat(
usize::from(draw_loc.width)
.saturating_sub(DD_ERROR_BASE.chars().count() + 2)
)
),
self.colours.border_style,
)
} else {
Span::styled(
format!(
" Confirm Kill Process ─{}─ Esc to close ",
"─".repeat(
usize::from(draw_loc.width).saturating_sub(DD_BASE.chars().count() + 2)
)
),
self.colours.border_style,
);
)
};

f.render_widget(
Paragraph::new(dd_text)
.block(
Block::default()
.title(dd_title)
.style(self.colours.border_style)
.borders(Borders::ALL)
.border_style(self.colours.border_style),
)
.style(self.colours.text_style)
.alignment(Alignment::Center)
.wrap(Wrap { trim: true }),
draw_loc,
);
f.render_widget(
Paragraph::new(dd_text)
.block(
Block::default()
.title(dd_title)
.style(self.colours.border_style)
.borders(Borders::ALL)
.border_style(self.colours.border_style),
)
.style(self.colours.text_style)
.alignment(Alignment::Center)
.wrap(Wrap { trim: true }),
draw_loc,
);

if app_state.dd_err.is_some() {
return app_state.delete_dialog_state.is_showing_dd;
} else {
return true;
}
}
Expand All @@ -98,36 +127,4 @@ impl KillDialog for Painter {
// I don't really like this, and I find it ugly, but it works for now.
false
}

fn draw_dd_error_dialog<B: Backend>(&self, f: &mut Frame<'_, B>, dd_err: &str, draw_loc: Rect) {
let dd_text = Span::from(format!(
"\nFailure to properly kill the process - {}",
dd_err
));

let error_title = Span::styled(
format!(
" Error ─{}─ Esc to close ",
"─".repeat(
usize::from(draw_loc.width).saturating_sub(DD_ERROR_BASE.chars().count() + 2)
)
),
self.colours.border_style,
);

f.render_widget(
Paragraph::new(dd_text)
.block(
Block::default()
.title(error_title)
.style(self.colours.border_style)
.borders(Borders::ALL)
.border_style(self.colours.border_style),
)
.style(self.colours.text_style)
.alignment(Alignment::Center)
.wrap(Wrap { trim: true }),
draw_loc,
);
}
}
2 changes: 1 addition & 1 deletion src/canvas/widgets/process_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ impl ProcessTableWidget for Painter {
let wps = "W/s".to_string();
let total_read = "Read".to_string();
let total_write = "Write".to_string();
let process_state = "State".to_string();
let process_state = "State ".to_string();

let direction_val = if proc_widget_state.process_sorting_reverse {
"▼".to_string()
Expand Down

0 comments on commit 6e38d73

Please sign in to comment.