diff --git a/examples/basic_sprite.rs b/examples/basic_sprite.rs index ef0b9e3ca5113029f525bd62995bf7bc12c05e5d..59fa63823422e8617b465cca3bbf6a13e7545f56 100644 --- a/examples/basic_sprite.rs +++ b/examples/basic_sprite.rs @@ -1,15 +1,10 @@ use bevy::{core_pipeline::clear_color::ClearColorConfig, prelude::*, window::PrimaryWindow}; use bevy_cosmic_edit::{ - ActiveEditor, CosmicAttrs, CosmicEditPlugin, CosmicEditSpriteBundle, CosmicFontConfig, - CosmicFontSystem, CosmicMetrics, CosmicText, CosmicTextPosition, + ActiveEditor, AttrsOwned, CosmicAttrs, CosmicEditPlugin, CosmicEditSpriteBundle, + CosmicFontConfig, CosmicMetrics, CosmicText, CosmicTextPosition, }; -use cosmic_text::AttrsOwned; -fn setup( - mut commands: Commands, - windows: Query<&Window, With<PrimaryWindow>>, - mut font_system: ResMut<CosmicFontSystem>, -) { +fn setup(mut commands: Commands, windows: Query<&Window, With<PrimaryWindow>>) { let primary_window = windows.single(); let camera_bundle = Camera2dBundle { camera_2d: Camera2d { @@ -37,13 +32,9 @@ fn setup( }, text_position: CosmicTextPosition::Center, cosmic_attrs: CosmicAttrs(AttrsOwned::new(attrs)), + set_text: CosmicText::OneStyle("😀😀😀 x => y".to_string()), ..default() - } - .set_text( - CosmicText::OneStyle("😀😀😀 x => y".to_string()), - AttrsOwned::new(attrs), - &mut font_system.0, - ); + }; let cosmic_edit = commands.spawn(cosmic_edit).id(); diff --git a/examples/basic_ui.rs b/examples/basic_ui.rs index 54bfdb5de909743dd9292638d15d6c99246716e9..f390de55cc3cff758814ee119b5042ab389a7420 100644 --- a/examples/basic_ui.rs +++ b/examples/basic_ui.rs @@ -1,15 +1,10 @@ use bevy::{core_pipeline::clear_color::ClearColorConfig, prelude::*, window::PrimaryWindow}; use bevy_cosmic_edit::{ - ActiveEditor, CosmicAttrs, CosmicEditPlugin, CosmicEditUiBundle, CosmicEditor, - CosmicFontConfig, CosmicFontSystem, CosmicMetrics, CosmicText, CosmicTextPosition, + ActiveEditor, AttrsOwned, CosmicAttrs, CosmicEditPlugin, CosmicEditUiBundle, CosmicEditor, + CosmicFontConfig, CosmicMetrics, CosmicText, CosmicTextPosition, }; -use cosmic_text::AttrsOwned; -fn setup( - mut commands: Commands, - windows: Query<&Window, With<PrimaryWindow>>, - mut font_system: ResMut<CosmicFontSystem>, -) { +fn setup(mut commands: Commands, windows: Query<&Window, With<PrimaryWindow>>) { let primary_window = windows.single(); let camera_bundle = Camera2dBundle { camera_2d: Camera2d { @@ -38,13 +33,9 @@ fn setup( }, text_position: CosmicTextPosition::Center, cosmic_attrs: CosmicAttrs(AttrsOwned::new(attrs)), + set_text: CosmicText::OneStyle("😀😀😀 x => y".to_string()), ..default() - } - .set_text( - CosmicText::OneStyle("😀😀😀 x => y".to_string()), - AttrsOwned::new(attrs), - &mut font_system.0, - ); + }; let cosmic_edit = commands.spawn(cosmic_edit).id(); diff --git a/examples/bevy_api_testing.rs b/examples/bevy_api_testing.rs index 822a17c9ebf1c3193b2daca9244847e1a314aec2..83a85f2becf044d63bc5b62812d3d4d1e54b3d75 100644 --- a/examples/bevy_api_testing.rs +++ b/examples/bevy_api_testing.rs @@ -1,9 +1,8 @@ use bevy::prelude::*; use bevy_cosmic_edit::{ - change_active_editor_sprite, change_active_editor_ui, ActiveEditor, CosmicAttrs, - CosmicEditPlugin, CosmicEditSpriteBundle, CosmicEditUiBundle, + bevy_color_to_cosmic, change_active_editor_sprite, change_active_editor_ui, ActiveEditor, + Attrs, AttrsOwned, CosmicAttrs, CosmicEditPlugin, CosmicEditSpriteBundle, CosmicEditUiBundle, }; -use cosmic_text::{Attrs, AttrsOwned}; fn setup(mut commands: Commands) { commands.spawn(Camera2dBundle::default()); @@ -19,7 +18,7 @@ fn setup(mut commands: Commands) { ..default() }, cosmic_attrs: CosmicAttrs(AttrsOwned::new( - Attrs::new().color(cosmic_text::Color::rgb(0, 255, 0)), + Attrs::new().color(bevy_color_to_cosmic(Color::GREEN)), )), ..default() }); diff --git a/examples/every_option.rs b/examples/every_option.rs new file mode 100644 index 0000000000000000000000000000000000000000..1a9697bc8dcb932779003edb6abd77207f71d23d --- /dev/null +++ b/examples/every_option.rs @@ -0,0 +1,97 @@ +use bevy::{prelude::*, ui::FocusPolicy, window::PrimaryWindow}; +use bevy_cosmic_edit::{ + bevy_color_to_cosmic, change_active_editor_sprite, change_active_editor_ui, get_x_offset, + ActiveEditor, Attrs, AttrsOwned, CosmicAttrs, CosmicBackground, CosmicEditPlugin, + CosmicEditUiBundle, CosmicEditor, CosmicMaxChars, CosmicMaxLines, CosmicMetrics, CosmicText, + CosmicTextPosition, Edit, +}; + +#[derive(Resource)] +struct TextChangeTimer(pub Timer); + +fn setup(mut commands: Commands, windows: Query<&Window, With<PrimaryWindow>>) { + commands.spawn(Camera2dBundle::default()); + + let attrs = + AttrsOwned::new(Attrs::new().color(bevy_color_to_cosmic(Color::rgb(0.27, 0.27, 0.27)))); + let primary_window = windows.single(); + + let editor = commands + .spawn(CosmicEditUiBundle { + node: Node::default(), + button: Button, + visibility: Visibility::Visible, + computed_visibility: ComputedVisibility::default(), + z_index: ZIndex::default(), + image: UiImage::default(), + transform: Transform::default(), + interaction: Interaction::default(), + focus_policy: FocusPolicy::default(), + text_position: CosmicTextPosition::default(), + background_color: BackgroundColor::default(), + global_transform: GlobalTransform::default(), + background_image: CosmicBackground::default(), + border_color: Color::LIME_GREEN.into(), + style: Style { + // Size and position of text box + border: UiRect::all(Val::Px(4.)), + 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., + scale_factor: primary_window.scale_factor() as f32, + }, + max_chars: CosmicMaxChars(15), + max_lines: CosmicMaxLines(1), + set_text: CosmicText::OneStyle("BANANA IS THE CODEWORD!".into()), + }) + .id(); + + commands.insert_resource(ActiveEditor { + entity: Some(editor), + }); + + commands.insert_resource(TextChangeTimer(Timer::from_seconds( + 1., + TimerMode::Repeating, + ))); +} + +// Test for update_buffer_text +fn text_swapper( + mut timer: ResMut<TextChangeTimer>, + 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() { + return; + } + + *count += 1; + 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() { + App::new() + .add_plugins(DefaultPlugins) + .add_plugins(CosmicEditPlugin::default()) + .add_systems(Startup, setup) + .add_systems(Update, change_active_editor_ui) + .add_systems(Update, change_active_editor_sprite) + .add_systems(Update, text_swapper) + .run(); +} diff --git a/examples/font_per_widget.rs b/examples/font_per_widget.rs index c3580c5c697ce56032909789a7118166dd29de6c..b8721cb0e2a2ca82f144eb55799b8b368e43066e 100644 --- a/examples/font_per_widget.rs +++ b/examples/font_per_widget.rs @@ -1,19 +1,13 @@ #![allow(clippy::type_complexity)] use bevy::{prelude::*, window::PrimaryWindow}; -use bevy_cosmic_edit::change_active_editor_sprite; -use bevy_cosmic_edit::change_active_editor_ui; use bevy_cosmic_edit::{ - ActiveEditor, CosmicAttrs, CosmicEditPlugin, CosmicEditUiBundle, CosmicFontConfig, - CosmicFontSystem, CosmicMetrics, CosmicText, CosmicTextPosition, + bevy_color_to_cosmic, change_active_editor_sprite, change_active_editor_ui, ActiveEditor, + Attrs, AttrsOwned, CosmicAttrs, CosmicEditPlugin, CosmicEditUiBundle, CosmicFontConfig, + CosmicMetrics, CosmicText, CosmicTextPosition, Family, FontStyle, FontWeight, }; -use cosmic_text::{Attrs, AttrsOwned, Family}; -fn setup( - mut commands: Commands, - windows: Query<&Window, With<PrimaryWindow>>, - mut font_system: ResMut<CosmicFontSystem>, -) { +fn setup(mut commands: Commands, windows: Query<&Window, With<PrimaryWindow>>) { commands.spawn(Camera2dBundle::default()); let root = commands .spawn(NodeBundle { @@ -36,24 +30,24 @@ fn setup( vec![ ( String::from("B"), - AttrsOwned::new(attrs.weight(cosmic_text::Weight::BOLD)), + AttrsOwned::new(attrs.weight(FontWeight::BOLD)), ), (String::from("old "), AttrsOwned::new(attrs)), ( String::from("I"), - AttrsOwned::new(attrs.style(cosmic_text::Style::Italic)), + AttrsOwned::new(attrs.style(FontStyle::Italic)), ), (String::from("talic "), AttrsOwned::new(attrs)), (String::from("f"), AttrsOwned::new(attrs)), (String::from("i "), AttrsOwned::new(attrs)), ( String::from("f"), - AttrsOwned::new(attrs.weight(cosmic_text::Weight::BOLD)), + AttrsOwned::new(attrs.weight(FontWeight::BOLD)), ), (String::from("i "), AttrsOwned::new(attrs)), ( String::from("f"), - AttrsOwned::new(attrs.style(cosmic_text::Style::Italic)), + AttrsOwned::new(attrs.style(FontStyle::Italic)), ), (String::from("i "), AttrsOwned::new(attrs)), ], @@ -61,37 +55,33 @@ fn setup( (String::from("Sans-Serif Normal "), AttrsOwned::new(attrs)), ( String::from("Sans-Serif Bold "), - AttrsOwned::new(attrs.weight(cosmic_text::Weight::BOLD)), + AttrsOwned::new(attrs.weight(FontWeight::BOLD)), ), ( String::from("Sans-Serif Italic "), - AttrsOwned::new(attrs.style(cosmic_text::Style::Italic)), + AttrsOwned::new(attrs.style(FontStyle::Italic)), ), ( String::from("Sans-Serif Bold Italic"), - AttrsOwned::new( - attrs - .weight(cosmic_text::Weight::BOLD) - .style(cosmic_text::Style::Italic), - ), + AttrsOwned::new(attrs.weight(FontWeight::BOLD).style(FontStyle::Italic)), ), ], vec![ (String::from("Serif Normal "), AttrsOwned::new(serif_attrs)), ( String::from("Serif Bold "), - AttrsOwned::new(serif_attrs.weight(cosmic_text::Weight::BOLD)), + AttrsOwned::new(serif_attrs.weight(FontWeight::BOLD)), ), ( String::from("Serif Italic "), - AttrsOwned::new(serif_attrs.style(cosmic_text::Style::Italic)), + AttrsOwned::new(serif_attrs.style(FontStyle::Italic)), ), ( String::from("Serif Bold Italic"), AttrsOwned::new( serif_attrs - .weight(cosmic_text::Weight::BOLD) - .style(cosmic_text::Style::Italic), + .weight(FontWeight::BOLD) + .style(FontStyle::Italic), ), ), ], @@ -99,129 +89,125 @@ fn setup( (String::from("Mono Normal "), AttrsOwned::new(mono_attrs)), ( String::from("Mono Bold "), - AttrsOwned::new(mono_attrs.weight(cosmic_text::Weight::BOLD)), + AttrsOwned::new(mono_attrs.weight(FontWeight::BOLD)), ), ( String::from("Mono Italic "), - AttrsOwned::new(mono_attrs.style(cosmic_text::Style::Italic)), + AttrsOwned::new(mono_attrs.style(FontStyle::Italic)), ), ( String::from("Mono Bold Italic"), - AttrsOwned::new( - mono_attrs - .weight(cosmic_text::Weight::BOLD) - .style(cosmic_text::Style::Italic), - ), + AttrsOwned::new(mono_attrs.weight(FontWeight::BOLD).style(FontStyle::Italic)), ), ], vec![ (String::from("Comic Normal "), AttrsOwned::new(comic_attrs)), ( String::from("Comic Bold "), - AttrsOwned::new(comic_attrs.weight(cosmic_text::Weight::BOLD)), + AttrsOwned::new(comic_attrs.weight(FontWeight::BOLD)), ), ( String::from("Comic Italic "), - AttrsOwned::new(comic_attrs.style(cosmic_text::Style::Italic)), + AttrsOwned::new(comic_attrs.style(FontStyle::Italic)), ), ( String::from("Comic Bold Italic"), AttrsOwned::new( comic_attrs - .weight(cosmic_text::Weight::BOLD) - .style(cosmic_text::Style::Italic), + .weight(FontWeight::BOLD) + .style(FontStyle::Italic), ), ), ], vec![ ( String::from("R"), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0xFF, 0x00, 0x00))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::RED))), ), ( String::from("A"), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0xFF, 0x7F, 0x00))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::ORANGE))), ), ( String::from("I"), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0xFF, 0xFF, 0x00))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::YELLOW))), ), ( String::from("N"), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0x00, 0xFF, 0x00))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::GREEN))), ), ( String::from("B"), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0x00, 0x00, 0xFF))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::BLUE))), ), ( String::from("O"), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0x4B, 0x00, 0x82))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::INDIGO))), ), ( String::from("W "), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0x94, 0x00, 0xD3))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::PURPLE))), ), ( String::from("Red "), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0xFF, 0x00, 0x00))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::RED))), ), ( String::from("Orange "), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0xFF, 0x7F, 0x00))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::ORANGE))), ), ( String::from("Yellow "), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0xFF, 0xFF, 0x00))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::YELLOW))), ), ( String::from("Green "), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0x00, 0xFF, 0x00))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::GREEN))), ), ( String::from("Blue "), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0x00, 0x00, 0xFF))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::BLUE))), ), ( String::from("Indigo "), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0x4B, 0x00, 0x82))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::INDIGO))), ), ( String::from("Violet "), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0x94, 0x00, 0xD3))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::PURPLE))), ), ( String::from("U"), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0x94, 0x00, 0xD3))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::PURPLE))), ), ( String::from("N"), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0x4B, 0x00, 0x82))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::INDIGO))), ), ( String::from("I"), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0x00, 0x00, 0xFF))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::BLUE))), ), ( String::from("C"), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0x00, 0xFF, 0x00))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::GREEN))), ), ( String::from("O"), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0xFF, 0xFF, 0x00))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::YELLOW))), ), ( String::from("R"), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0xFF, 0x7F, 0x00))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::ORANGE))), ), ( String::from("N"), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0xFF, 0x00, 0x00))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::RED))), ), ], vec![( String::from("生活,삶,जिंदगी 😀 FPS"), - AttrsOwned::new(attrs.color(cosmic_text::Color::rgb(0xFF, 0x00, 0x00))), + AttrsOwned::new(attrs.color(bevy_color_to_cosmic(Color::RED))), )], ]; @@ -239,17 +225,13 @@ fn setup( ..default() }, background_color: BackgroundColor(Color::WHITE), + set_text: CosmicText::MultiStyle(lines), ..default() - } - .set_text( - CosmicText::MultiStyle(lines), - AttrsOwned::new(attrs), - &mut font_system.0, - ); + }; - let mut attrs_2 = cosmic_text::Attrs::new(); - attrs_2 = attrs_2.family(cosmic_text::Family::Name("Times New Roman")); - attrs_2.color_opt = Some(cosmic_text::Color::rgb(0x94, 0x00, 0xD3)); + let mut attrs_2 = Attrs::new(); + attrs_2 = attrs_2.family(Family::Name("Times New Roman")); + attrs_2.color_opt = Some(bevy_color_to_cosmic(Color::PURPLE)); let cosmic_edit_2 = CosmicEditUiBundle { cosmic_attrs: CosmicAttrs(AttrsOwned::new(attrs_2)), @@ -265,13 +247,9 @@ fn setup( height: Val::Percent(100.), ..default() }, + set_text: CosmicText::OneStyle("Widget 2.\nClick on me =>".to_string()), ..default() - } - .set_text( - CosmicText::OneStyle("Widget 2.\nClick on me =>".to_string()), - AttrsOwned::new(attrs_2), - &mut font_system.0, - ); + }; let mut id = None; // Spawn the CosmicEditUiBundles as children of root diff --git a/examples/image_background.rs b/examples/image_background.rs index 6af3efcfb178b4364ebcc8cd31f2e3cd284f3493..135ee717158b9de7067339e1219abb115f3f916c 100644 --- a/examples/image_background.rs +++ b/examples/image_background.rs @@ -1,9 +1,8 @@ use bevy::prelude::*; use bevy_cosmic_edit::{ - change_active_editor_sprite, change_active_editor_ui, ActiveEditor, CosmicAttrs, - CosmicBackground, CosmicEditPlugin, CosmicEditUiBundle, + bevy_color_to_cosmic, change_active_editor_sprite, change_active_editor_ui, ActiveEditor, + Attrs, AttrsOwned, CosmicAttrs, CosmicBackground, CosmicEditPlugin, CosmicEditUiBundle, }; -use cosmic_text::{Attrs, AttrsOwned}; fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { commands.spawn(Camera2dBundle::default()); @@ -21,7 +20,7 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { ..default() }, cosmic_attrs: CosmicAttrs(AttrsOwned::new( - Attrs::new().color(cosmic_text::Color::rgb(0, 255, 0)), + Attrs::new().color(bevy_color_to_cosmic(Color::GREEN)), )), background_image: CosmicBackground(Some(bg_image_handle)), ..default() diff --git a/examples/multiple_sprites.rs b/examples/multiple_sprites.rs index d71e6b5860fd5f6f7bdc762183dab7da544ed4c5..fd240f1672ec85aa691afd932fa258c8450dd424 100644 --- a/examples/multiple_sprites.rs +++ b/examples/multiple_sprites.rs @@ -1,17 +1,11 @@ use bevy::{core_pipeline::clear_color::ClearColorConfig, prelude::*, window::PrimaryWindow}; -use bevy_cosmic_edit::change_active_editor_sprite; -use bevy_cosmic_edit::change_active_editor_ui; use bevy_cosmic_edit::{ - ActiveEditor, CosmicAttrs, CosmicEditPlugin, CosmicEditSpriteBundle, CosmicFontConfig, - CosmicFontSystem, CosmicMetrics, CosmicText, CosmicTextPosition, + bevy_color_to_cosmic, change_active_editor_sprite, change_active_editor_ui, ActiveEditor, + Attrs, AttrsOwned, CosmicAttrs, CosmicEditPlugin, CosmicEditSpriteBundle, CosmicFontConfig, + CosmicMetrics, CosmicText, CosmicTextPosition, Family, }; -use cosmic_text::AttrsOwned; -fn setup( - mut commands: Commands, - windows: Query<&Window, With<PrimaryWindow>>, - mut font_system: ResMut<CosmicFontSystem>, -) { +fn setup(mut commands: Commands, windows: Query<&Window, With<PrimaryWindow>>) { let primary_window = windows.single(); let camera_bundle = Camera2dBundle { camera_2d: Camera2d { @@ -21,9 +15,9 @@ fn setup( }; commands.spawn(camera_bundle); - let mut attrs = cosmic_text::Attrs::new(); - attrs = attrs.family(cosmic_text::Family::Name("Victor Mono")); - attrs = attrs.color(cosmic_text::Color::rgb(0x94, 0x00, 0xD3)); + let mut attrs = Attrs::new(); + attrs = attrs.family(Family::Name("Victor Mono")); + attrs = attrs.color(bevy_color_to_cosmic(Color::PURPLE)); let metrics = CosmicMetrics { font_size: 14., line_height: 18., @@ -43,13 +37,9 @@ fn setup( transform: Transform::from_translation(Vec3::new(-primary_window.width() / 4., 0., 1.)), text_position: CosmicTextPosition::Center, background_color: BackgroundColor(Color::ALICE_BLUE), + set_text: CosmicText::OneStyle("😀😀😀 x => y".to_string()), ..default() - } - .set_text( - CosmicText::OneStyle("😀😀😀 x => y".to_string()), - AttrsOwned::new(attrs), - &mut font_system.0, - ); + }; let cosmic_edit_2 = CosmicEditSpriteBundle { cosmic_attrs: CosmicAttrs(AttrsOwned::new(attrs)), @@ -68,13 +58,9 @@ fn setup( )), text_position: CosmicTextPosition::Center, background_color: BackgroundColor(Color::GRAY.with_a(0.5)), + set_text: CosmicText::OneStyle("Widget_2. Click on me".to_string()), ..default() - } - .set_text( - CosmicText::OneStyle("Widget_2. Click on me".to_string()), - AttrsOwned::new(attrs), - &mut font_system.0, - ); + }; let id = commands.spawn(cosmic_edit_1).id(); diff --git a/examples/readonly.rs b/examples/readonly.rs index 049d0431538cbb9aae633559d2838bd04c06b32c..4c67c1b45316eb39a6805983cf1c24a4ca48d822 100644 --- a/examples/readonly.rs +++ b/examples/readonly.rs @@ -1,15 +1,11 @@ use bevy::{prelude::*, window::PrimaryWindow}; use bevy_cosmic_edit::{ - ActiveEditor, CosmicAttrs, CosmicEditPlugin, CosmicEditUiBundle, CosmicFontConfig, - CosmicFontSystem, CosmicMetrics, CosmicText, CosmicTextPosition, ReadOnly, + bevy_color_to_cosmic, ActiveEditor, Attrs, AttrsOwned, CosmicAttrs, CosmicEditPlugin, + CosmicEditUiBundle, CosmicFontConfig, CosmicMetrics, CosmicText, CosmicTextPosition, Family, + ReadOnly, }; -use cosmic_text::AttrsOwned; -fn setup( - mut commands: Commands, - windows: Query<&Window, With<PrimaryWindow>>, - mut font_system: ResMut<CosmicFontSystem>, -) { +fn setup(mut commands: Commands, windows: Query<&Window, With<PrimaryWindow>>) { let primary_window = windows.single(); commands.spawn(Camera2dBundle::default()); let root = commands @@ -24,9 +20,9 @@ fn setup( }) .id(); - let mut attrs = cosmic_text::Attrs::new(); - attrs = attrs.family(cosmic_text::Family::Name("Victor Mono")); - attrs = attrs.color(cosmic_text::Color::rgb(0x94, 0x00, 0xD3)); + let mut attrs = Attrs::new(); + attrs = attrs.family(Family::Name("Victor Mono")); + attrs = attrs.color(bevy_color_to_cosmic(Color::PURPLE)); let cosmic_edit = CosmicEditUiBundle { style: Style { @@ -42,13 +38,9 @@ fn setup( line_height: 18., scale_factor: primary_window.scale_factor() as f32, }, + set_text: CosmicText::OneStyle("😀😀😀 x => y\nRead only widget".to_string()), ..default() - } - .set_text( - CosmicText::OneStyle("😀😀😀 x => y\nRead only widget".to_string()), - AttrsOwned::new(attrs), - &mut font_system.0, - ); + }; let mut id = None; // Spawn the CosmicEditUiBundle as a child of root diff --git a/examples/restricted_input.rs b/examples/restricted_input.rs index 01a130114d7e921faf609b1b750b95b5d4117371..847e0ebbf71078a15d0887f5545162d9c919394c 100644 --- a/examples/restricted_input.rs +++ b/examples/restricted_input.rs @@ -1,53 +1,43 @@ use bevy::{prelude::*, window::PrimaryWindow}; use bevy_cosmic_edit::{ - change_active_editor_sprite, change_active_editor_ui, ActiveEditor, CosmicAttrs, - CosmicEditPlugin, CosmicEditUiBundle, CosmicFontSystem, CosmicMaxChars, CosmicMaxLines, - CosmicMetrics, CosmicText, + bevy_color_to_cosmic, change_active_editor_sprite, change_active_editor_ui, ActiveEditor, + Attrs, AttrsOwned, CosmicAttrs, CosmicEditPlugin, CosmicEditUiBundle, CosmicMaxChars, + CosmicMaxLines, CosmicMetrics, CosmicText, }; -use cosmic_text::{Attrs, AttrsOwned}; -fn setup( - mut commands: Commands, - mut font_system: ResMut<CosmicFontSystem>, - windows: Query<&Window, With<PrimaryWindow>>, -) { +fn setup(mut commands: Commands, windows: Query<&Window, With<PrimaryWindow>>) { commands.spawn(Camera2dBundle::default()); - let attrs = AttrsOwned::new(Attrs::new().color(cosmic_text::Color::rgb(69, 69, 69))); + let attrs = + AttrsOwned::new(Attrs::new().color(bevy_color_to_cosmic(Color::rgb(0.27, 0.27, 0.27)))); let primary_window = windows.single(); let editor = commands - .spawn( - CosmicEditUiBundle { - border_color: Color::LIME_GREEN.into(), - style: Style { - // Size and position of text box - border: UiRect::all(Val::Px(4.)), - 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., - scale_factor: primary_window.scale_factor() as f32, - }, - max_chars: CosmicMaxChars(15), - max_lines: CosmicMaxLines(1), + .spawn(CosmicEditUiBundle { + border_color: Color::LIME_GREEN.into(), + style: Style { + // Size and position of text box + border: UiRect::all(Val::Px(4.)), + width: Val::Percent(20.), + height: Val::Px(50.), + left: Val::Percent(40.), + top: Val::Px(100.), ..default() - } - .set_text( - CosmicText::OneStyle( - "1 line 15 chars! But this\n is longer\n than is\n allowed by\n the limits.\n" - .into(), - ), - attrs, - &mut font_system.0, + }, + cosmic_attrs: CosmicAttrs(attrs.clone()), + cosmic_metrics: CosmicMetrics { + font_size: 16., + line_height: 16., + scale_factor: primary_window.scale_factor() as f32, + }, + max_chars: CosmicMaxChars(15), + max_lines: CosmicMaxLines(1), + set_text: CosmicText::OneStyle( + "1 line 15 chars! But this\n is longer\n than is\n allowed by\n the limits.\n" + .into(), ), - ) + ..default() + }) .id(); commands.insert_resource(ActiveEditor { diff --git a/src/lib.rs b/src/lib.rs index 3c5dca71b1a92c77914ef8992916e6223af000ec..0bdcd281d17aa73f72dfc76ce0353c261b393dd1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,18 +13,26 @@ use bevy::{ ui::FocusPolicy, window::{PrimaryWindow, WindowScaleFactorChanged}, }; +pub use cosmic_text::{ + Action, Attrs, AttrsOwned, Cursor, Edit, Family, Style as FontStyle, Weight as FontWeight, +}; use cosmic_text::{ - Action, Attrs, AttrsList, AttrsOwned, Buffer, BufferLine, Cursor, Edit, Editor, FontSystem, - Metrics, Shaping, SwashCache, + AttrsList, Buffer, BufferLine, Editor, FontSystem, Metrics, Shaping, SwashCache, }; use image::{imageops::FilterType, GenericImageView}; -#[derive(Clone)] +#[derive(Clone, Component, PartialEq)] pub enum CosmicText { OneStyle(String), MultiStyle(Vec<Vec<(String, AttrsOwned)>>), } +impl Default for CosmicText { + fn default() -> Self { + Self::OneStyle(String::new()) + } +} + /// Enum representing the position of the cosmic text. #[derive(Clone, Component, Default)] pub enum CosmicTextPosition { @@ -60,20 +68,14 @@ pub struct ReadOnly; // tag component #[derive(Component)] pub struct CosmicEditor(pub Editor); -impl Default for CosmicEditor { - fn default() -> Self { - Self(Editor::new(Buffer::new_empty(Metrics::new(12., 14.)))) - } -} - impl CosmicEditor { - pub fn set_text( + fn set_text( &mut self, text: CosmicText, attrs: AttrsOwned, - // i'd like to get the font system + attrs automagically but i'm too 3head -bytemunch font_system: &mut FontSystem, ) -> &mut Self { + // TODO invoke trim_text here let editor = &mut self.0; editor.buffer_mut().lines.clear(); match text { @@ -136,39 +138,31 @@ impl CosmicEditor { fn cosmic_editor_builder( mut added_editors: Query< ( - &mut CosmicEditor, + Entity, + &mut CosmicText, &CosmicAttrs, &CosmicMetrics, + &CosmicMaxChars, + &CosmicMaxLines, Option<&ReadOnly>, Option<&Node>, Option<&Sprite>, ), - Added<CosmicEditor>, + Added<CosmicText>, >, mut font_system: ResMut<CosmicFontSystem>, + mut commands: Commands, ) { - for (mut editor, attrs, metrics, readonly, node, sprite) in added_editors.iter_mut() { - // keep old text if set - let mut text = editor.get_text(); - - if text.is_empty() { - text = "".into(); - editor.0.buffer_mut().set_text( - &mut font_system.0, - text.as_str(), - attrs.0.as_attrs(), - Shaping::Advanced, - ); - } - - editor.0.buffer_mut().set_metrics( + for (entity, text, attrs, metrics, max_chars, max_lines, readonly, node, sprite) in + added_editors.iter_mut() + { + let mut editor = Editor::new(Buffer::new( &mut font_system.0, Metrics::new(metrics.font_size, metrics.line_height).scale(metrics.scale_factor), - ); + )); if let Some(node) = node { editor - .0 .buffer_mut() .set_size(&mut font_system.0, node.size().x, node.size().y) } @@ -176,18 +170,48 @@ fn cosmic_editor_builder( if let Some(sprite) = sprite { if let Some(size) = sprite.custom_size { editor - .0 .buffer_mut() .set_size(&mut font_system.0, size.x, size.y) } } // hide cursor on readonly buffers - let mut cursor = editor.0.cursor(); + // TODO do this seperately, allow for readonly to be toggled + let mut cursor = editor.cursor(); if readonly.is_some() { cursor.color = Some(cosmic_text::Color::rgba(0, 0, 0, 0)); } - editor.0.set_cursor(cursor); + editor.set_cursor(cursor); + + let mut editor_component = CosmicEditor(editor); + + let text = trim_text(text.to_owned(), max_chars.0, max_lines.0); + 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()); + } +} + +/// Updates editor buffer when text component changes +fn update_buffer_text( + mut editor_q: Query< + ( + &mut CosmicEditor, + &mut CosmicText, + &CosmicAttrs, + &CosmicMaxChars, + &CosmicMaxLines, + ), + Changed<CosmicText>, + >, + mut font_system: ResMut<CosmicFontSystem>, +) { + for (mut editor, text, attrs, max_chars, max_lines) in editor_q.iter_mut() { + let text = trim_text(text.to_owned(), max_chars.0, max_lines.0); + editor.set_text(text, attrs.0.clone(), &mut font_system.0); } } @@ -246,14 +270,10 @@ pub struct CosmicEditUiBundle { /// Indicates the depth at which the node should appear in the UI pub z_index: ZIndex, // cosmic bits - /// cosmic-text Editor, holds the text buffer + font system - pub editor: CosmicEditor, /// text positioning enum 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 @@ -262,100 +282,9 @@ pub struct CosmicEditUiBundle { pub max_lines: CosmicMaxLines, /// How many characters are allowed in buffer, 0 for no limit pub max_chars: CosmicMaxChars, -} - -impl CosmicEditUiBundle { - pub fn set_text( - mut self, - text: CosmicText, - 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) - } - } + /// Setting this will update the buffer's text + // TODO sync this with the buffer to allow getting from here as well as setting + pub set_text: CosmicText, } impl Default for CosmicEditUiBundle { @@ -374,14 +303,13 @@ impl Default for CosmicEditUiBundle { visibility: Default::default(), computed_visibility: Default::default(), z_index: Default::default(), - editor: 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(), max_chars: Default::default(), + set_text: Default::default(), } } } @@ -400,14 +328,10 @@ pub struct CosmicEditSpriteBundle { // pub background_color: BackgroundColor, // cosmic bits - /// cosmic-text Editor, holds the text buffer + font system - pub editor: CosmicEditor, /// text positioning enum 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 @@ -416,19 +340,7 @@ pub struct CosmicEditSpriteBundle { pub max_lines: CosmicMaxLines, /// How many characters are allowed in buffer, 0 for no limit pub max_chars: CosmicMaxChars, -} - -impl CosmicEditSpriteBundle { - pub fn set_text( - mut self, - text: CosmicText, - 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 - } + pub set_text: CosmicText, } impl Default for CosmicEditSpriteBundle { @@ -441,14 +353,13 @@ impl Default for CosmicEditSpriteBundle { visibility: Visibility::Hidden, computed_visibility: Default::default(), background_color: Default::default(), - editor: 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(), max_chars: Default::default(), + set_text: Default::default(), } } } @@ -475,7 +386,7 @@ impl Plugin for CosmicEditPlugin { fn build(&self, app: &mut App) { let font_system = create_cosmic_font_system(self.font_config.clone()); - app.add_systems(PreUpdate, cosmic_editor_builder) + app.add_systems(PreUpdate, (cosmic_editor_builder, update_buffer_text)) .add_systems( Update, ( @@ -530,6 +441,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(); @@ -695,7 +687,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>>, @@ -1490,15 +1482,11 @@ fn draw_pixel( mod tests { use crate::*; - fn test_spawn_cosmic_edit_system( - mut commands: Commands, - mut font_system: ResMut<CosmicFontSystem>, - ) { - commands.spawn(CosmicEditUiBundle::default().set_text( - CosmicText::OneStyle("Blah".into()), - AttrsOwned::new(Attrs::new()), - &mut font_system.0, - )); + fn test_spawn_cosmic_edit_system(mut commands: Commands) { + commands.spawn(CosmicEditUiBundle { + set_text: CosmicText::OneStyle("Blah".into()), + ..Default::default() + }); } #[test]