diff --git a/Cargo.toml b/Cargo.toml index eb0f399f..9d56e94e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ path = "src/bin/main.rs" doc = false [lib] -test = false +test = true doctest = false doc = false diff --git a/src/canvas.rs b/src/canvas.rs index 4648a417..447d9421 100644 --- a/src/canvas.rs +++ b/src/canvas.rs @@ -282,9 +282,6 @@ impl Painter { self.styled_help_text = styled_help_spans.into_iter().map(Spans::from).collect(); } - // FIXME: [CONFIG] write this, should call painter init and any changed colour functions... - pub fn update_painter_colours(&mut self) {} - fn draw_frozen_indicator(&self, f: &mut Frame<'_, B>, draw_loc: Rect) { f.render_widget( Paragraph::new(Span::styled( @@ -559,44 +556,62 @@ impl Painter { .direction(Direction::Horizontal) .constraints([Constraint::Percentage(50), Constraint::Percentage(50)]) .split(vertical_chunks[1]); - self.draw_basic_cpu(f, app_state, vertical_chunks[0], 1); - self.draw_basic_memory(f, app_state, middle_chunks[0], 2); - self.draw_basic_network(f, app_state, middle_chunks[1], 3); + + if vertical_chunks[0].width >= 2 { + self.draw_basic_cpu(f, app_state, vertical_chunks[0], 1); + } + if middle_chunks[0].width >= 2 { + self.draw_basic_memory(f, app_state, middle_chunks[0], 2); + } + if middle_chunks[1].width >= 2 { + self.draw_basic_network(f, app_state, middle_chunks[1], 3); + } let mut later_widget_id: Option = None; if let Some(basic_table_widget_state) = &app_state.basic_table_widget_state { let widget_id = basic_table_widget_state.currently_displayed_widget_id; later_widget_id = Some(widget_id); - match basic_table_widget_state.currently_displayed_widget_type { - Disk => { - self.draw_disk_table(f, app_state, vertical_chunks[3], false, widget_id) - } - Proc | ProcSort => { - let wid = widget_id - - match basic_table_widget_state.currently_displayed_widget_type { - ProcSearch => 1, - ProcSort => 2, - _ => 0, - }; - self.draw_process_features( + if vertical_chunks[3].width >= 2 { + match basic_table_widget_state.currently_displayed_widget_type { + Disk => self.draw_disk_table( f, app_state, vertical_chunks[3], false, - wid, - ); + widget_id, + ), + Proc | ProcSort => { + let wid = widget_id + - match basic_table_widget_state.currently_displayed_widget_type + { + ProcSearch => 1, + ProcSort => 2, + _ => 0, + }; + self.draw_process_features( + f, + app_state, + vertical_chunks[3], + false, + wid, + ); + } + Temp => self.draw_temp_table( + f, + app_state, + vertical_chunks[3], + false, + widget_id, + ), + Battery => self.draw_battery_display( + f, + app_state, + vertical_chunks[3], + false, + widget_id, + ), + _ => {} } - Temp => { - self.draw_temp_table(f, app_state, vertical_chunks[3], false, widget_id) - } - Battery => self.draw_battery_display( - f, - app_state, - vertical_chunks[3], - false, - widget_id, - ), - _ => {} } } @@ -712,32 +727,34 @@ impl Painter { ) { use BottomWidgetType::*; for (widget, widget_draw_loc) in widgets.children.iter().zip(widget_draw_locs) { - match &widget.widget_type { - Empty => {} - Cpu => self.draw_cpu(f, app_state, *widget_draw_loc, widget.widget_id), - Mem => self.draw_memory_graph(f, app_state, *widget_draw_loc, widget.widget_id), - Net => self.draw_network(f, app_state, *widget_draw_loc, widget.widget_id), - Temp => { - self.draw_temp_table(f, app_state, *widget_draw_loc, true, widget.widget_id) + if widget_draw_loc.width >= 2 && widget_draw_loc.height >= 2 { + match &widget.widget_type { + Empty => {} + Cpu => self.draw_cpu(f, app_state, *widget_draw_loc, widget.widget_id), + Mem => self.draw_memory_graph(f, app_state, *widget_draw_loc, widget.widget_id), + Net => self.draw_network(f, app_state, *widget_draw_loc, widget.widget_id), + Temp => { + self.draw_temp_table(f, app_state, *widget_draw_loc, true, widget.widget_id) + } + Disk => { + self.draw_disk_table(f, app_state, *widget_draw_loc, true, widget.widget_id) + } + Proc => self.draw_process_features( + f, + app_state, + *widget_draw_loc, + true, + widget.widget_id, + ), + Battery => self.draw_battery_display( + f, + app_state, + *widget_draw_loc, + true, + widget.widget_id, + ), + _ => {} } - Disk => { - self.draw_disk_table(f, app_state, *widget_draw_loc, true, widget.widget_id) - } - Proc => self.draw_process_features( - f, - app_state, - *widget_draw_loc, - true, - widget.widget_id, - ), - Battery => self.draw_battery_display( - f, - app_state, - *widget_draw_loc, - true, - widget.widget_id, - ), - _ => {} } } } diff --git a/src/canvas/drawing_utils.rs b/src/canvas/drawing_utils.rs index ee81127a..129a80a9 100644 --- a/src/canvas/drawing_utils.rs +++ b/src/canvas/drawing_utils.rs @@ -35,94 +35,83 @@ pub fn get_column_widths( "soft width max length != soft width desired length!" ); - let initial_width = total_width - 2; - let mut total_width_left = initial_width; - let mut column_widths: Vec = vec![0; hard_widths.len()]; - let range: Vec = if left_to_right { - (0..hard_widths.len()).collect() - } else { - (0..hard_widths.len()).rev().collect() - }; + if total_width > 2 { + let initial_width = total_width - 2; + let mut total_width_left = initial_width; + let mut column_widths: Vec = vec![0; hard_widths.len()]; + let range: Vec = if left_to_right { + (0..hard_widths.len()).collect() + } else { + (0..hard_widths.len()).rev().collect() + }; - for itx in &range { - if let Some(Some(hard_width)) = hard_widths.get(*itx) { - // Hard width... - let space_taken = min(*hard_width, total_width_left); - - // TODO [COLUMN MOVEMENT]: Remove this - if *hard_width > space_taken { - break; - } - - column_widths[*itx] = space_taken; - total_width_left -= space_taken; - total_width_left = total_width_left.saturating_sub(1); - } else if let ( - Some(Some(soft_width_max)), - Some(Some(soft_width_min)), - Some(Some(soft_width_desired)), - ) = ( - soft_widths_max.get(*itx), - soft_widths_min.get(*itx), - soft_widths_desired.get(*itx), - ) { - // Soft width... - let soft_limit = max( - if soft_width_max.is_sign_negative() { - *soft_width_desired - } else { - (*soft_width_max * initial_width as f64).ceil() as u16 - }, - *soft_width_min, - ); - let space_taken = min(min(soft_limit, *soft_width_desired), total_width_left); - - // TODO [COLUMN MOVEMENT]: Remove this - if *soft_width_min > space_taken { - break; - } - - column_widths[*itx] = space_taken; - total_width_left -= space_taken; - total_width_left = total_width_left.saturating_sub(1); - } - } - - // Redistribute remaining. - while total_width_left > 0 { for itx in &range { - if column_widths[*itx] > 0 { - column_widths[*itx] += 1; - total_width_left -= 1; - if total_width_left == 0 { + if let Some(Some(hard_width)) = hard_widths.get(*itx) { + // Hard width... + let space_taken = min(*hard_width, total_width_left); + + // TODO [COLUMN MOVEMENT]: Remove this + if *hard_width > space_taken { break; } + + column_widths[*itx] = space_taken; + total_width_left -= space_taken; + total_width_left = total_width_left.saturating_sub(1); + } else if let ( + Some(Some(soft_width_max)), + Some(Some(soft_width_min)), + Some(Some(soft_width_desired)), + ) = ( + soft_widths_max.get(*itx), + soft_widths_min.get(*itx), + soft_widths_desired.get(*itx), + ) { + // Soft width... + let soft_limit = max( + if soft_width_max.is_sign_negative() { + *soft_width_desired + } else { + (*soft_width_max * initial_width as f64).ceil() as u16 + }, + *soft_width_min, + ); + let space_taken = min(min(soft_limit, *soft_width_desired), total_width_left); + + // TODO [COLUMN MOVEMENT]: Remove this + if *soft_width_min > space_taken { + break; + } + + column_widths[*itx] = space_taken; + total_width_left -= space_taken; + total_width_left = total_width_left.saturating_sub(1); + } + } + + while let Some(0) = column_widths.last() { + column_widths.pop(); + } + + if !column_widths.is_empty() { + // Redistribute remaining. + let amount_per_slot = total_width_left / column_widths.len() as u16; + total_width_left %= column_widths.len() as u16; + for (index, width) in column_widths.iter_mut().enumerate() { + if (index as u16) < total_width_left { + *width += amount_per_slot + 1; + } else { + *width += amount_per_slot; + } } } + + column_widths + } else { + vec![] } - - let mut filtered_column_widths: Vec = vec![]; - let mut still_seeing_zeros = true; - column_widths.iter().rev().for_each(|width| { - if still_seeing_zeros { - if *width != 0 { - still_seeing_zeros = false; - filtered_column_widths.push(*width); - } - } else { - filtered_column_widths.push(*width); - } - }); - filtered_column_widths.reverse(); - filtered_column_widths } -/// FIXME: [command move] This is a greedy method of determining column widths. This is reserved for columns where we are okay with -/// shoving information as far right as required. -// pub fn greedy_get_column_widths() -> Vec { -// vec![] -// } - pub fn get_search_start_position( num_columns: usize, cursor_direction: &app::CursorDirection, cursor_bar: &mut usize, current_cursor_position: usize, is_force_redraw: bool, @@ -216,3 +205,56 @@ pub fn interpolate_points(point_one: &(f64, f64), point_two: &(f64, f64), time: (point_one.1 + (time - point_one.0) * slope).max(0.0) } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_zero_width() { + assert_eq!( + get_column_widths( + 0, + &[Some(1), None, None], + &[None, Some(1), Some(2)], + &[None, Some(0.125), Some(0.5)], + &[None, Some(10), Some(10)], + true + ), + vec![], + "vector should be empty" + ); + } + + #[test] + fn test_two_width() { + assert_eq!( + get_column_widths( + 2, + &[Some(1), None, None], + &[None, Some(1), Some(2)], + &[None, Some(0.125), Some(0.5)], + &[None, Some(10), Some(10)], + true + ), + vec![], + "vector should be empty" + ); + } + + #[test] + fn test_non_zero_width() { + assert_eq!( + get_column_widths( + 16, + &[Some(1), None, None], + &[None, Some(1), Some(2)], + &[None, Some(0.125), Some(0.5)], + &[None, Some(10), Some(10)], + true + ), + vec![2, 2, 7], + "vector should not be empty" + ); + } +}