diff --git a/examples/restricted_input.rs b/examples/restricted_input.rs index 18de1076cb28630c8dcab218529f648c4d999ff4..950705d66e0ec8e19e04ff41184fca01514eccdb 100644 --- a/examples/restricted_input.rs +++ b/examples/restricted_input.rs @@ -1,35 +1,45 @@ use bevy::prelude::*; use bevy_cosmic_edit::{ change_active_editor_sprite, change_active_editor_ui, ActiveEditor, CosmicAttrs, - CosmicEditPlugin, CosmicEditUiBundle, CosmicMaxChars, CosmicMaxLines, CosmicMetrics, + CosmicEditPlugin, CosmicEditUiBundle, CosmicFontSystem, CosmicMaxChars, CosmicMaxLines, + CosmicMetrics, CosmicText, }; use cosmic_text::{Attrs, AttrsOwned}; -fn setup(mut commands: Commands) { +fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) { commands.spawn(Camera2dBundle::default()); let attrs = AttrsOwned::new(Attrs::new().color(cosmic_text::Color::rgb(69, 69, 69))); let editor = commands - .spawn(CosmicEditUiBundle { - style: Style { - // Size and position of text box - width: Val::Percent(20.), - height: Val::Px(50.), - left: Val::Percent(40.), - top: Val::Px(100.), + .spawn( + CosmicEditUiBundle { + style: Style { + // Size and position of text box + width: Val::Percent(20.), + height: Val::Px(50.), + left: Val::Percent(40.), + top: Val::Px(100.), + ..default() + }, + cosmic_attrs: CosmicAttrs(attrs.clone()), + cosmic_metrics: CosmicMetrics { + font_size: 16., + line_height: 16., + ..Default::default() + }, + max_chars: CosmicMaxChars(15), + max_lines: CosmicMaxLines(3), ..default() - }, - cosmic_attrs: CosmicAttrs(attrs.clone()), - cosmic_metrics: CosmicMetrics { - font_size: 16., - line_height: 16., - ..Default::default() - }, - max_chars: CosmicMaxChars(15), - max_lines: CosmicMaxLines(1), - ..default() - }) + } + .set_text( + CosmicText::OneStyle( + "This text\n is longer\n than is\n allowed by\n the limits.\n".into(), + ), + attrs, + &mut font_system.0, + ), + ) .id(); commands.insert_resource(ActiveEditor { diff --git a/src/lib.rs b/src/lib.rs index c1b5dbb2fbac38f87a35782da20ca66a68cba863..902ad21094aff023a9f8ddb3416e4942c7a196e5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -272,11 +272,93 @@ impl CosmicEditUiBundle { attrs: AttrsOwned, font_system: &mut FontSystem, ) -> Self { + let text = trim_text(text, self.max_chars.0, self.max_lines.0); self.editor.set_text(text, attrs, font_system); self } } +fn trim_text(text: CosmicText, max_chars: usize, max_lines: usize) -> CosmicText { + if max_chars == 0 && max_lines == 0 { + // no limits, no work to do + return text; + } + + match text { + CosmicText::OneStyle(mut string) => { + string.truncate(max_chars); + + if max_lines == 0 { + return CosmicText::OneStyle(string); + } + + let mut line_acc = 0; + let mut char_pos = 0; + for c in string.chars() { + char_pos += 1; + if c == 0xA as char { + line_acc += 1; + if line_acc >= max_lines { + // break text to pos + string.truncate(char_pos); + break; + } + } + } + + CosmicText::OneStyle(string) + } + CosmicText::MultiStyle(lines) => { + let mut char_acc = 0; + let mut line_acc = 0; + + let mut trimmed_styles = vec![]; + + for line in lines.iter() { + line_acc += 1; + char_acc += 1; // count newlines for consistent behaviour + + if (line_acc >= max_lines && max_lines > 0) + || (char_acc >= max_chars && max_chars > 0) + { + break; + } + + let mut strs = vec![]; + + for (string, attrs) in line.iter() { + if char_acc >= max_chars && max_chars > 0 { + break; + } + + let mut string = string.clone(); + + if max_chars > 0 { + string.truncate(max_chars - char_acc); + char_acc += string.len(); + } + + if max_lines > 0 { + for c in string.chars() { + if c == 0xA as char { + line_acc += 1; + char_acc += 1; // count newlines for consistent behaviour + if line_acc >= max_lines { + break; + } + } + } + } + + strs.push((string, attrs.clone())); + } + trimmed_styles.push(strs); + } + CosmicText::MultiStyle(trimmed_styles) + } + } +} + impl Default for CosmicEditUiBundle { fn default() -> Self { Self { @@ -344,6 +426,7 @@ impl CosmicEditSpriteBundle { attrs: AttrsOwned, font_system: &mut FontSystem, ) -> Self { + let text = trim_text(text, self.max_chars.0, self.max_lines.0); self.editor.set_text(text, attrs, font_system); self }