diff --git a/crates/rnote-engine/src/pens/pensconfig/typewriterconfig.rs b/crates/rnote-engine/src/pens/pensconfig/typewriterconfig.rs index 3155237ceb..aab5c725a2 100644 --- a/crates/rnote-engine/src/pens/pensconfig/typewriterconfig.rs +++ b/crates/rnote-engine/src/pens/pensconfig/typewriterconfig.rs @@ -7,18 +7,27 @@ use serde::{Deserialize, Serialize}; pub struct TypewriterConfig { #[serde(rename = "text_style")] pub text_style: TextStyle, - #[serde(rename = "max_width_enabled")] - pub max_width_enabled: bool, #[serde(rename = "text_width")] - pub text_width: f64, + text_width: f64, } impl Default for TypewriterConfig { fn default() -> Self { Self { text_style: TextStyle::default(), - max_width_enabled: true, - text_width: 600.0, + text_width: Self::TEXT_WIDTH_DEFAULT, } } } + +impl TypewriterConfig { + pub const TEXT_WIDTH_DEFAULT: f64 = 600.; + + pub fn text_width(&self) -> f64 { + self.text_width + } + + pub fn set_text_width(&mut self, text_width: f64) { + self.text_width = text_width.max(0.); + } +} diff --git a/crates/rnote-engine/src/pens/typewriter/mod.rs b/crates/rnote-engine/src/pens/typewriter/mod.rs index 107ac263e8..5a3383dfe4 100644 --- a/crates/rnote-engine/src/pens/typewriter/mod.rs +++ b/crates/rnote-engine/src/pens/typewriter/mod.rs @@ -2,6 +2,7 @@ mod penevents; // Imports +use super::pensconfig::TypewriterConfig; use super::PenBehaviour; use super::PenStyle; use crate::engine::{EngineTask, EngineView, EngineViewMut}; @@ -95,7 +96,7 @@ impl DrawableOnDoc for Typewriter { engine_view.store.get_stroke_ref(*stroke_key) { let text_rect = Self::text_rect_bounds( - engine_view.pens_config.typewriter_config.text_width, + engine_view.pens_config.typewriter_config.text_width(), textstroke, ); let typewriter_bounds = text_rect.extend_by( @@ -163,7 +164,7 @@ impl DrawableOnDoc for Typewriter { if let Some(Stroke::TextStroke(textstroke)) = engine_view.store.get_stroke_ref(*stroke_key) { - let text_width = engine_view.pens_config.typewriter_config.text_width; + let text_width = engine_view.pens_config.typewriter_config.text_width(); let text_bounds = Self::text_rect_bounds(text_width, textstroke); // Draw text outline @@ -303,9 +304,12 @@ impl PenBehaviour for Typewriter { .text_style .ranged_text_attributes .clear(); - if let Some(max_width) = textstroke.text_style.max_width { - engine_view.pens_config.typewriter_config.text_width = max_width; - } + engine_view.pens_config.typewriter_config.set_text_width( + textstroke + .text_style + .max_width() + .unwrap_or(TypewriterConfig::TEXT_WIDTH_DEFAULT), + ); update_cursors_for_textstroke(textstroke, cursor, Some(selection_cursor)); widget_flags.refresh_ui = true; @@ -326,9 +330,12 @@ impl PenBehaviour for Typewriter { .text_style .ranged_text_attributes .clear(); - if let Some(max_width) = textstroke.text_style.max_width { - engine_view.pens_config.typewriter_config.text_width = max_width; - } + engine_view.pens_config.typewriter_config.set_text_width( + textstroke + .text_style + .max_width() + .unwrap_or(TypewriterConfig::TEXT_WIDTH_DEFAULT), + ); update_cursors_for_textstroke(textstroke, cursor, None); widget_flags.refresh_ui = true; @@ -623,17 +630,14 @@ impl Typewriter { engine_view.camera.viewport().mins.coords + Stroke::IMPORT_OFFSET_DEFAULT }); let mut widget_flags = WidgetFlags::default(); - let text_width = engine_view.pens_config.typewriter_config.text_width; + let text_width = engine_view.pens_config.typewriter_config.text_width(); let mut text_style = engine_view.pens_config.typewriter_config.text_style.clone(); - let max_width_enabled = engine_view.pens_config.typewriter_config.max_width_enabled; match &mut self.state { TypewriterState::Idle => { let text_len = text.len(); text_style.ranged_text_attributes.clear(); - if max_width_enabled { - text_style.max_width = Some(text_width); - } + text_style.set_max_width(Some(text_width)); let textstroke = TextStroke::new(text, pos, text_style); let cursor = GraphemeCursor::new(text_len, textstroke.text.len(), true); @@ -660,9 +664,7 @@ impl Typewriter { TypewriterState::Start(pos) => { let text_len = text.len(); text_style.ranged_text_attributes.clear(); - if max_width_enabled { - text_style.max_width = Some(text_width); - } + text_style.set_max_width(Some(text_width)); let textstroke = TextStroke::new(text, *pos, text_style); let cursor = GraphemeCursor::new(text_len, textstroke.text.len(), true); diff --git a/crates/rnote-engine/src/pens/typewriter/penevents.rs b/crates/rnote-engine/src/pens/typewriter/penevents.rs index a3623aaaec..26aaaa8b6e 100644 --- a/crates/rnote-engine/src/pens/typewriter/penevents.rs +++ b/crates/rnote-engine/src/pens/typewriter/penevents.rs @@ -21,7 +21,7 @@ impl Typewriter { ) -> (EventResult, WidgetFlags) { let mut widget_flags = WidgetFlags::default(); let typewriter_bounds = self.bounds_on_doc(&engine_view.as_im()); - let text_width = engine_view.pens_config.typewriter_config.text_width; + let text_width = engine_view.pens_config.typewriter_config.text_width(); let event_result = match &mut self.state { TypewriterState::Idle | TypewriterState::Start { .. } => { @@ -283,12 +283,13 @@ impl Typewriter { if x_offset.abs() > Self::ADJ_TEXT_WIDTH_THRESHOLD / engine_view.camera.total_zoom() { - let abs_x_offset = element.pos[0] - start_pos[0]; - engine_view.pens_config.typewriter_config.text_width = - (*start_text_width + abs_x_offset).max(2.0); - if let Some(max_width) = &mut textstroke.text_style.max_width { - *max_width = *start_text_width + abs_x_offset; - } + let new_text_width = + *start_text_width + (element.pos[0] - start_pos[0]); + engine_view + .pens_config + .typewriter_config + .set_text_width(new_text_width); + textstroke.text_style.set_max_width(Some(new_text_width)); engine_view.store.regenerate_rendering_for_stroke( *stroke_key, engine_view.camera.viewport(), @@ -476,9 +477,8 @@ impl Typewriter { ) -> (EventResult, WidgetFlags) { let mut widget_flags = WidgetFlags::default(); - let text_width = engine_view.pens_config.typewriter_config.text_width; + let text_width = engine_view.pens_config.typewriter_config.text_width(); let mut text_style = engine_view.pens_config.typewriter_config.text_style.clone(); - let max_width_enabled = engine_view.pens_config.typewriter_config.max_width_enabled; let event_result = match &mut self.state { TypewriterState::Idle => EventResult { @@ -492,9 +492,7 @@ impl Typewriter { match keyboard_key { KeyboardKey::Unicode(keychar) => { text_style.ranged_text_attributes.clear(); - if max_width_enabled { - text_style.max_width = Some(text_width); - } + text_style.set_max_width(Some(text_width)); let textstroke = TextStroke::new(String::from(keychar), *pos, text_style); let mut cursor = GraphemeCursor::new(0, textstroke.text.len(), true); @@ -1049,9 +1047,8 @@ impl Typewriter { ) -> (EventResult, WidgetFlags) { let mut widget_flags = WidgetFlags::default(); - let text_width = engine_view.pens_config.typewriter_config.text_width; + let text_width = engine_view.pens_config.typewriter_config.text_width(); let mut text_style = engine_view.pens_config.typewriter_config.text_style.clone(); - let max_width_enabled = engine_view.pens_config.typewriter_config.max_width_enabled; self.reset_blink(); @@ -1065,9 +1062,7 @@ impl Typewriter { super::play_sound(None, engine_view.audioplayer); text_style.ranged_text_attributes.clear(); - if max_width_enabled { - text_style.max_width = Some(text_width); - } + text_style.set_max_width(Some(text_width)); let text_len = text.len(); let textstroke = TextStroke::new(text, *pos, text_style); let cursor = GraphemeCursor::new(text_len, text_len, true); diff --git a/crates/rnote-engine/src/strokes/textstroke.rs b/crates/rnote-engine/src/strokes/textstroke.rs index 37b5d4c6af..ec27b20065 100644 --- a/crates/rnote-engine/src/strokes/textstroke.rs +++ b/crates/rnote-engine/src/strokes/textstroke.rs @@ -178,7 +178,7 @@ pub struct TextStyle { #[serde(rename = "color")] pub color: Color, #[serde(rename = "max_width")] - pub max_width: Option, + max_width: Option, #[serde(rename = "alignment")] pub alignment: TextAlignment, @@ -209,6 +209,14 @@ impl TextStyle { pub const FONT_WEIGHT_DEFAULT: u16 = 500; pub const FONT_COLOR_DEFAULT: Color = Color::BLACK; + pub fn max_width(&self) -> Option { + self.max_width + } + + pub fn set_max_width(&mut self, max_width: Option) { + self.max_width = max_width.map(|w| w.max(0.)); + } + pub fn build_text_layout( &self, piet_text: &mut T,