diff --git a/examples/every_option.rs b/examples/every_option.rs index 83385a4d6aeca2e1d0ef7cd9d130715a18e90ec0..3020213771d60d3e09d76e3f4bd4099ec7fbf58f 100644 --- a/examples/every_option.rs +++ b/examples/every_option.rs @@ -1,10 +1,10 @@ use bevy::{prelude::*, ui::FocusPolicy, window::PrimaryWindow}; use bevy_cosmic_edit::{ - change_active_editor_sprite, change_active_editor_ui, ActiveEditor, CosmicAttrs, - CosmicBackground, CosmicEditPlugin, CosmicEditUiBundle, CosmicMaxChars, CosmicMaxLines, - CosmicMetrics, CosmicText, CosmicTextPosition, + change_active_editor_sprite, change_active_editor_ui, get_x_offset, ActiveEditor, CosmicAttrs, + CosmicBackground, CosmicEditPlugin, CosmicEditUiBundle, CosmicEditor, CosmicMaxChars, + CosmicMaxLines, CosmicMetrics, CosmicText, CosmicTextPosition, }; -use cosmic_text::{Attrs, AttrsOwned}; +use cosmic_text::{Attrs, AttrsOwned, Edit}; #[derive(Resource)] struct TextChangeTimer(pub Timer); @@ -25,7 +25,6 @@ fn setup(mut commands: Commands, windows: Query<&Window, With<PrimaryWindow>>) { image: UiImage::default(), transform: Transform::default(), interaction: Interaction::default(), - cosmic_edit_history: bevy_cosmic_edit::CosmicEditHistory::default(), focus_policy: FocusPolicy::default(), text_position: CosmicTextPosition::default(), background_color: BackgroundColor::default(), @@ -69,6 +68,7 @@ fn text_swapper( time: Res<Time>, mut cosmic_q: Query<&mut CosmicText>, mut count: Local<usize>, + editor_q: Query<&CosmicEditor>, ) { timer.0.tick(time.delta()); if !timer.0.just_finished() { @@ -79,6 +79,9 @@ fn text_swapper( for mut text in cosmic_q.iter_mut() { text.set_if_neq(CosmicText::OneStyle(format!("TIMER {}", *count))); } + + let editor = editor_q.single(); + println!("X OFFSET: {}", get_x_offset(editor.0.buffer())); } fn main() { diff --git a/src/lib.rs b/src/lib.rs index 4ffbc8523b4d4254f3e504f0bf86456301f68cae..ced2651f147c03f37964bf085ce87dc7c3794457 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -187,6 +187,9 @@ fn cosmic_editor_builder( editor_component.set_text(text, attrs.0.clone(), &mut font_system.0); commands.entity(entity).insert(editor_component); + + // Add edit history + commands.entity(entity).insert(CosmicEditHistory::default()); } } @@ -269,8 +272,6 @@ pub struct CosmicEditUiBundle { pub text_position: CosmicTextPosition, /// text metrics pub cosmic_metrics: CosmicMetrics, - /// edit history - pub cosmic_edit_history: CosmicEditHistory, /// text attributes pub cosmic_attrs: CosmicAttrs, /// bg img @@ -284,87 +285,6 @@ pub struct CosmicEditUiBundle { pub set_text: CosmicText, } -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 { @@ -383,7 +303,6 @@ impl Default for CosmicEditUiBundle { z_index: Default::default(), text_position: Default::default(), cosmic_metrics: Default::default(), - cosmic_edit_history: Default::default(), cosmic_attrs: Default::default(), background_image: Default::default(), max_lines: Default::default(), @@ -411,8 +330,6 @@ pub struct CosmicEditSpriteBundle { pub text_position: CosmicTextPosition, /// text metrics pub cosmic_metrics: CosmicMetrics, - /// edit history - pub cosmic_edit_history: CosmicEditHistory, /// text attributes pub cosmic_attrs: CosmicAttrs, /// bg img @@ -436,7 +353,6 @@ impl Default for CosmicEditSpriteBundle { background_color: Default::default(), text_position: Default::default(), cosmic_metrics: Default::default(), - cosmic_edit_history: Default::default(), cosmic_attrs: Default::default(), background_image: Default::default(), max_lines: Default::default(), @@ -447,13 +363,13 @@ impl Default for CosmicEditSpriteBundle { } #[derive(Clone)] -pub struct EditHistoryItem { +struct EditHistoryItem { pub cursor: Cursor, pub lines: Vec<Vec<(String, AttrsOwned)>>, } #[derive(Component, Default)] -pub struct CosmicEditHistory { +struct CosmicEditHistory { pub edits: VecDeque<EditHistoryItem>, pub current_edit: usize, } @@ -523,6 +439,87 @@ struct SwashCacheState { swash_cache: SwashCache, } +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) + } + } +} + fn create_cosmic_font_system(cosmic_font_config: CosmicFontConfig) -> FontSystem { let locale = sys_locale::get_locale().unwrap_or_else(|| String::from("en-US")); let mut db = cosmic_text::fontdb::Database::new(); @@ -688,7 +685,7 @@ pub fn get_x_offset(buffer: &Buffer) -> i32 { #[allow(clippy::too_many_arguments, clippy::type_complexity)] // the meat of the input management -pub fn cosmic_edit_bevy_events( +fn cosmic_edit_bevy_events( windows: Query<&Window, With<PrimaryWindow>>, active_editor: Res<ActiveEditor>, keys: Res<Input<KeyCode>>,