1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
extern crate tui; use tui::{Frame, Terminal}; use tui::backend::Backend; use tui::layout::{Layout, Constraint, Direction, Rect}; use crate::log; use crate::userinterface::widgets::{brushselector, grid, shortcuts, gauge::{self, Rgb}}; use crate::userinterface::views::{MIN_BRUSH_AREA_WIDTH, MIN_SHORTCUTS_AREA_WIDTH, ratio}; const NB_BRUSH_SHORTCUTS: usize = 3; const NB_GRID_SHORTCUTS: usize = 4; const NB_WORKSPACE_SHORTCUTS: usize = 3; const NB_GENERAL_SHORTCUTS: usize = 4; const SHORTCUTS_AREAS: usize = 4; pub fn render<B: Backend>(terminal: &mut Terminal<B>, log: &mut log::Log, (nb_todo_tasks, nb_max_tasks): (usize, usize)) { terminal.draw(|frame| { let frame_area = frame.size(); let left = frame_area.left(); let top = frame_area.top(); let width = frame_area.right() - left; let height = frame_area.bottom() - top; let shortcuts_height = height - 2 * gauge::GAUGE_HEIGHT; let shortcuts_chunks = Layout::default() .direction(Direction::Vertical) .constraints([ Constraint::Percentage(25), Constraint::Percentage(25), Constraint::Percentage(25), Constraint::Percentage(25), ].as_ref()) .split(Rect::new(left, top, width, shortcuts_height)); let brush_area = Rect::new(0, 0, MIN_BRUSH_AREA_WIDTH, height); let workspace_area = Rect::new(brush_area.right(), 0, width - MIN_BRUSH_AREA_WIDTH - MIN_SHORTCUTS_AREA_WIDTH, height); let mut shortcuts_areas = Vec::<Rect>::with_capacity(SHORTCUTS_AREAS); for i in 0..SHORTCUTS_AREAS { shortcuts_areas.push(Rect::new(workspace_area.right(), top, MIN_SHORTCUTS_AREA_WIDTH, shortcuts_height) .intersection(shortcuts_chunks[i])); } let gauge_tasks_area = Rect::new(workspace_area.right(), shortcuts_areas.last().unwrap().bottom(), MIN_SHORTCUTS_AREA_WIDTH, gauge::GAUGE_HEIGHT); let gauge_map_area = Rect::new(workspace_area.right(), gauge_tasks_area.bottom(), MIN_SHORTCUTS_AREA_WIDTH, gauge::GAUGE_HEIGHT); frame.render_widget( brushselector::BrushSelectorWidget::new(log), brush_area); frame.render_widget(grid::GridWidget::new(log), workspace_area); render_shortcuts(frame, shortcuts_areas); render_tasks_gauge( frame, gauge_tasks_area, (nb_todo_tasks, nb_max_tasks)); render_map_gauge(frame, log, gauge_map_area); }).unwrap(); } fn render_shortcuts<B: Backend>(frame: &mut Frame<B>, areas: Vec<Rect>) { let mut brush_shortcuts = shortcuts::ShortcutsWidget::new( NB_BRUSH_SHORTCUTS, String::from(" Brush Shortcuts ")); brush_shortcuts.push_action("Brush | Eraser"); brush_shortcuts.push_action("Next Brush | Previous Brush"); brush_shortcuts.push_action("Set Brush Color"); brush_shortcuts.push_instruction("< L-Click | R-Click >"); brush_shortcuts.push_instruction("< q | a >"); brush_shortcuts.push_instruction("< c >"); frame.render_widget(brush_shortcuts, areas[0]); let mut grid_shortcuts = shortcuts::ShortcutsWidget::new( NB_GRID_SHORTCUTS, String::from(" Grid Shortcuts ")); grid_shortcuts.push_action("(+|-) Width | (+|-) Height"); grid_shortcuts.push_action("Scroll Grid"); grid_shortcuts.push_action("Clear Grid"); grid_shortcuts.push_action("Rename Grid"); grid_shortcuts.push_instruction("< w | W > | < h | H >"); grid_shortcuts.push_instruction("< ← | ↑ | ↓ | → >"); grid_shortcuts.push_instruction("< C >"); grid_shortcuts.push_instruction("< r >"); frame.render_widget(grid_shortcuts, areas[1]); let mut workspace_shortcuts = shortcuts::ShortcutsWidget::new( NB_WORKSPACE_SHORTCUTS, String::from(" Workspace Shortcuts ")); workspace_shortcuts.push_action("Add | Delete Grid"); workspace_shortcuts.push_action("Next Grid | Previous Grid"); workspace_shortcuts.push_action("Switch Grid Order"); workspace_shortcuts.push_instruction("< + | - >"); workspace_shortcuts.push_instruction("< n | N >"); workspace_shortcuts.push_instruction("< S >"); frame.render_widget(workspace_shortcuts, areas[2]); let mut general_shortcuts = shortcuts::ShortcutsWidget::new( NB_GENERAL_SHORTCUTS, String::from(" General Shortcuts ")); general_shortcuts.push_action("Undo | Redo"); general_shortcuts.push_action("Generate Texture"); general_shortcuts.push_action("Switch View"); general_shortcuts.push_action("Exit"); general_shortcuts.push_instruction("< u | U >"); general_shortcuts.push_instruction("< g >"); general_shortcuts.push_instruction("< s >"); general_shortcuts.push_instruction("< Esc >"); frame.render_widget(general_shortcuts, areas[3]); } fn render_tasks_gauge<B: Backend>(frame: &mut Frame<B>, area: Rect, (nb_todo_tasks, nb_max_tasks): (usize, usize)) { let gauge_tasks_ratio = ratio(nb_todo_tasks, nb_max_tasks); let gauge_tasks_label = format!("Tasks: {}/{}", nb_todo_tasks, nb_max_tasks); let gauge_tasks; if gauge_tasks_ratio < 0.5 { gauge_tasks = gauge::GaugeWidget::new(gauge_tasks_ratio, &gauge_tasks_label, (Rgb::GREEN, Rgb::YELLOW, gauge_tasks_ratio * 2.)); } else { gauge_tasks = gauge::GaugeWidget::new(gauge_tasks_ratio, &gauge_tasks_label, (Rgb::YELLOW, Rgb::RED, (gauge_tasks_ratio - 0.5) * 2.)); } frame.render_widget(gauge_tasks, area); } fn render_map_gauge<B: Backend>(frame: &mut Frame<B>, log: &log::Log, area: Rect) { let (map_length, map_capacity) = log.grids_getlengthcapacity(); let gauge_map_ratio = ratio(map_length, map_capacity); let gauge_map_label = format!("Memory: {}/{}", map_length, map_capacity); let gauge_map; if gauge_map_ratio < 0.5 { gauge_map = gauge::GaugeWidget::new(gauge_map_ratio, &gauge_map_label, (Rgb::GREEN, Rgb::YELLOW, gauge_map_ratio * 2.)); } else { gauge_map = gauge::GaugeWidget::new(gauge_map_ratio, &gauge_map_label, (Rgb::YELLOW, Rgb::RED, (gauge_map_ratio - 0.5) * 2.)); } frame.render_widget(gauge_map, area); }