From d788329373e916eda012619422c18de182f2c8b3 Mon Sep 17 00:00:00 2001 From: Gavin Tran Date: Tue, 28 Mar 2023 23:17:23 -0400 Subject: [PATCH] Fix text wrapping and highlighting (#32) --- src/gui.rs | 103 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/input.rs | 2 + src/main.rs | 102 ++++--------------------------------------------- src/naming.rs | 1 + 4 files changed, 109 insertions(+), 99 deletions(-) diff --git a/src/gui.rs b/src/gui.rs index 6fcc663..c879946 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -2,14 +2,15 @@ //! //! The `gui` module provides functions for drawing various UI elements. -use crate::molecule::Cell; -use crate::spatial::{GridState, Invert}; -use crate::Mode; +use crate::molecule::BondOrder::{Double, Triple}; +use crate::molecule::{Bond, BondOrientation, Cell, Element}; +use crate::spatial::{EnumAll, GridState, Invert}; use crate::Mode::{Insert, Normal}; +use crate::{AppState, Mode}; use ruscii::drawing::{Pencil, RectCharset}; use ruscii::spatial::Vec2; use ruscii::terminal::Color; -use ruscii::terminal::Color::{Cyan, DarkGrey}; +use ruscii::terminal::Color::{Cyan, DarkGrey, White}; use Color::Red; pub(crate) fn draw_grid_box(pencil: &mut Pencil, graph_size: Vec2, pos: Vec2) { @@ -118,3 +119,97 @@ pub fn draw_start_message(pencil: &mut Pencil, pos: Vec2) { .draw_center_text("Press any key to start.", Vec2::xy(20, 9)) .move_origin(-pos); } + +pub(crate) fn draw_statistics(graph: &GridState, state: &mut AppState, pencil: &mut Pencil) { + let mut mass = 0.0; + + let mut missed = 0; + let mut final_index = 0; + for (index, element) in Element::all().into_iter().enumerate() { + let count = graph.count(|it| it.is_atom() && it.unwrap_atom().element == element); + + if count == 0 { + missed += 1; + continue; + } + + mass += element.mass() * count as f32; + + pencil + .set_foreground(element.color()) + .draw_text(element.symbol(), Vec2::y(2 + index - missed)) + .set_foreground(White) + .draw_text(&format!("| {}", count), Vec2::xy(6, 2 + index - missed)); + + final_index = 2 + index - missed; + } + + let mut missed = 0; + for (index, order) in [Double, Triple].into_iter().enumerate() { + let count = graph.count(|it| it.is_bond() && it.unwrap_bond().order == order); + + if count == 0 { + missed += 1; + continue; + } + + pencil + .draw_text( + Bond::new(Vec2::zero(), order, BondOrientation::Horiz).symbol(), + Vec2::y(2 + final_index + index - missed), + ) + .draw_text( + &format!("| {}", count), + Vec2::xy(6, 2 + final_index + index - missed), + ); + } + + if state.err { + return; + } + + let carbon = graph.count(|it| it.is_atom() && it.unwrap_atom().element == Element::C); + let nitrogen = graph.count(|it| it.is_atom() && it.unwrap_atom().element == Element::N); + let hydrogen = graph.count(|it| it.is_atom() && it.unwrap_atom().element == Element::H); + let halogens = graph.count(|it| { + it.is_atom() + && matches!( + it.unwrap_atom().element, + Element::Br | Element::Cl | Element::F | Element::I + ) + }); + + let ihd = (2 * carbon + 2 + nitrogen - hydrogen - halogens) / 2; + + pencil + .draw_text(&format!("atomic weight | {:.3} amu", mass), Vec2::xy(15, 2)) + .draw_text(&format!("IHD | {}", ihd), Vec2::xy(15, 3)) + .draw_text( + &format!("name length | {}", state.name.len()), + Vec2::xy(15, 5), + ); +} + +pub(crate) fn draw_wrapped_name( + graph: &mut GridState, + state: &mut AppState, + window_size: Vec2, + pencil: &mut Pencil, +) { + let wrap_length = window_size.x - 14 - graph.size.x * 3; + let lines = state + .name + .chars() + .collect::>() + .chunks(wrap_length as usize) + .map(|chunk| chunk.iter().collect()) + .collect::>(); + pencil.set_foreground(if state.err { Red } else { White }); + + for line in lines { + pencil + .draw_text(&line, Vec2::zero()) + .move_origin(Vec2::y(1)); + } + pencil.move_origin(Vec2::y(-1)).set_foreground(White); +} diff --git a/src/input.rs b/src/input.rs index 1c9c754..d5badda 100644 --- a/src/input.rs +++ b/src/input.rs @@ -102,6 +102,8 @@ pub(crate) fn update(state: &mut AppState, graph: &mut GridState, comp: Componen if let Some(it) = chain { state.parent_chain = Some(get_chain_path(graph, it)) + } else { + state.parent_chain = None } } diff --git a/src/main.rs b/src/main.rs index bc66eaa..3ecee28 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,14 +8,14 @@ use crate::gui::draw_grid_box; use crate::input::{input_insert_mode, input_view_mode, start_mode}; use crate::molecule::BondOrder::{Double, Single, Triple}; -use crate::molecule::{Bond, BondOrientation, Cell, ComponentType, Element}; -use crate::spatial::{EnumAll, GridState}; +use crate::molecule::{Cell, ComponentType}; +use crate::spatial::GridState; use crate::Mode::Insert; use ruscii::app::{App, State}; use ruscii::drawing::Pencil; use ruscii::spatial::Vec2; use ruscii::terminal::Color::{Red, White}; -use ruscii::terminal::{Color, Style, Window}; +use ruscii::terminal::{Color, Window}; use Color::Yellow; use Mode::Normal; @@ -162,100 +162,12 @@ fn main() { return; } - let wrap_length = window_size.x - 14 - graph.size.x * 3; - if state.name.len() > wrap_length as usize { - let first_line = &state.name[0..wrap_length as usize]; - let second_line = &state.name[wrap_length as usize..]; - pencil - .move_origin(Vec2::xy(graph.size.x * 3 + 5, 1)) - .set_style(Style::Bold) - .set_foreground(if state.err { Red } else { White }) - .draw_text(first_line, Vec2::zero()) - .move_origin(Vec2::y(1)) - .draw_text(second_line, Vec2::zero()) - .set_foreground(White) - .set_style(Style::Plain); - } else { - pencil - .move_origin(Vec2::xy(graph.size.x * 3 + 5, 1)) - .set_style(Style::Bold) - .set_foreground(if state.err { Red } else { White }) - .draw_text(&state.name.to_string(), Vec2::zero()) - .set_foreground(White) - .set_style(Style::Plain); - } - - if !matches!(state.mode, Normal) { - return; - } - - let mut mass = 0.0; - - let mut missed = 0; - let mut final_index = 0; - for (index, element) in Element::all().into_iter().enumerate() { - let count = graph.count(|it| it.is_atom() && it.unwrap_atom().element == element); - - if count == 0 { - missed += 1; - continue; - } - - mass += element.mass() * count as f32; - - pencil - .set_foreground(element.color()) - .draw_text(element.symbol(), Vec2::y(2 + index - missed)) - .set_foreground(White) - .draw_text(&format!("| {}", count), Vec2::xy(6, 2 + index - missed)); - - final_index = 2 + index - missed; - } - - let mut missed = 0; - for (index, order) in [Double, Triple].into_iter().enumerate() { - let count = graph.count(|it| it.is_bond() && it.unwrap_bond().order == order); - - if count == 0 { - missed += 1; - continue; - } - - pencil - .draw_text( - Bond::new(Vec2::zero(), order, BondOrientation::Horiz).symbol(), - Vec2::y(2 + final_index + index - missed), - ) - .draw_text( - &format!("| {}", count), - Vec2::xy(6, 2 + final_index + index - missed), - ); - } + pencil.move_origin(Vec2::xy(graph.size.x * 3 + 5, 1)); + gui::draw_wrapped_name(&mut graph, &mut state, window_size, &mut pencil); - if state.err { - return; + if matches!(state.mode, Normal) { + gui::draw_statistics(&graph, &mut state, &mut pencil); } - - let carbon = graph.count(|it| it.is_atom() && it.unwrap_atom().element == Element::C); - let nitrogen = graph.count(|it| it.is_atom() && it.unwrap_atom().element == Element::N); - let hydrogen = graph.count(|it| it.is_atom() && it.unwrap_atom().element == Element::H); - let halogens = graph.count(|it| { - it.is_atom() - && matches!( - it.unwrap_atom().element, - Element::Br | Element::Cl | Element::F | Element::I - ) - }); - - let ihd = (2 * carbon + 2 + nitrogen - hydrogen - halogens) / 2; - - pencil - .draw_text(&format!("atomic weight | {:.3} amu", mass), Vec2::xy(15, 2)) - .draw_text(&format!("IHD | {}", ihd), Vec2::xy(15, 3)) - .draw_text( - &format!("name length | {}", state.name.len()), - Vec2::xy(15, 5), - ); }); } diff --git a/src/naming.rs b/src/naming.rs index fcee314..79b46c6 100644 --- a/src/naming.rs +++ b/src/naming.rs @@ -26,6 +26,7 @@ pub fn name_molecule( graph: &GridState, parent_chain_out: &mut Option>, ) -> Fallible { + *parent_chain_out = None; let cells = graph .find_all(|cell| cell.is_atom()) .iter()