From 423cb244b238d71a22f7c60bb28eaa9060ac4c23 Mon Sep 17 00:00:00 2001 From: sam edelsten <samedelsten1@gmail.com> Date: Mon, 29 Apr 2024 19:22:34 +0100 Subject: [PATCH] restructure everything into plugins --- examples/basic_sprite.rs | 2 +- examples/basic_ui.rs | 2 +- examples/password.rs | 4 +- src/buffer.rs | 21 +++ src/cursor.rs | 27 ++- src/focus.rs | 17 ++ src/input.rs | 22 ++- src/lib.rs | 167 +++++------------- src/{plugins/password/mod.rs => password.rs} | 8 +- .../placeholder/mod.rs => placeholder.rs} | 10 +- src/plugins/mod.rs | 2 - src/render.rs | 22 ++- src/{layout.rs => widget.rs} | 29 ++- util/src/lib.rs | 2 +- 14 files changed, 193 insertions(+), 142 deletions(-) rename src/{plugins/password/mod.rs => password.rs} (95%) rename src/{plugins/placeholder/mod.rs => placeholder.rs} (96%) delete mode 100644 src/plugins/mod.rs rename src/{layout.rs => widget.rs} (87%) diff --git a/examples/basic_sprite.rs b/examples/basic_sprite.rs index 09073d0..5c37182 100644 --- a/examples/basic_sprite.rs +++ b/examples/basic_sprite.rs @@ -1,5 +1,5 @@ use bevy::{prelude::*, window::PrimaryWindow}; -use bevy_cosmic_edit::*; +use bevy_cosmic_edit::{focus::FocusedWidget, *}; use util::{change_active_editor_sprite, deselect_editor_on_esc, print_editor_text}; fn setup( diff --git a/examples/basic_ui.rs b/examples/basic_ui.rs index 94eb841..ef01735 100644 --- a/examples/basic_ui.rs +++ b/examples/basic_ui.rs @@ -1,5 +1,5 @@ use bevy::prelude::*; -use bevy_cosmic_edit::*; +use bevy_cosmic_edit::{focus::FocusedWidget, *}; use util::{change_active_editor_ui, deselect_editor_on_esc, print_editor_text}; fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) { diff --git a/examples/password.rs b/examples/password.rs index 0539f39..cfff358 100644 --- a/examples/password.rs +++ b/examples/password.rs @@ -1,5 +1,5 @@ use bevy::prelude::*; -use bevy_cosmic_edit::{password::Password, placeholder::Placeholder, *}; +use bevy_cosmic_edit::*; use util::{change_active_editor_sprite, deselect_editor_on_esc, print_editor_text}; fn setup(mut commands: Commands) { @@ -40,7 +40,7 @@ fn main() { ( change_active_editor_sprite, deselect_editor_on_esc, - print_editor_text.after(KbInput), + print_editor_text.after(InputSet), ), ) .run(); diff --git a/src/buffer.rs b/src/buffer.rs index 1244e35..422c605 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -1,6 +1,27 @@ use crate::*; use bevy::{prelude::*, window::PrimaryWindow}; +#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] +pub struct BufferSet; + +pub struct BufferPlugin; + +impl Plugin for BufferPlugin { + fn build(&self, app: &mut App) { + app.add_systems( + First, + ( + add_font_system, + set_initial_scale, + set_redraw, + set_editor_redraw, + swap_target_handle, + ) + .chain(), + ); + } +} + pub trait BufferExtras { fn get_text(&self) -> String; } diff --git a/src/cursor.rs b/src/cursor.rs index a044bcf..b7dc8eb 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -1,10 +1,35 @@ use bevy::{input::mouse::MouseMotion, prelude::*, window::PrimaryWindow}; -use crate::{CosmicBuffer, CosmicSource, CosmicTextChanged}; +use crate::{CosmicBuffer, CosmicSource, CosmicTextChanged, CursorConfig}; #[cfg(feature = "multicam")] use crate::CosmicPrimaryCamera; +#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] +pub struct CursorSet; + +pub struct CursorPlugin { + pub change_cursor: CursorConfig, +} + +impl Plugin for CursorPlugin { + fn build(&self, app: &mut App) { + match self.change_cursor { + CursorConfig::Default => { + app.add_systems(Update, (hover_sprites, hover_ui, change_cursor)) + .add_event::<TextHoverIn>() + .add_event::<TextHoverOut>(); + } + CursorConfig::Events => { + app.add_systems(Update, (hover_sprites, hover_ui)) + .add_event::<TextHoverIn>() + .add_event::<TextHoverOut>(); + } + CursorConfig::None => {} + } + } +} + /// For use with custom cursor control; Event is emitted when cursor enters a text widget #[derive(Event)] pub struct TextHoverIn; diff --git a/src/focus.rs b/src/focus.rs index 6520f0d..edef5dc 100644 --- a/src/focus.rs +++ b/src/focus.rs @@ -3,6 +3,23 @@ use cosmic_text::{Edit, Editor}; use crate::{CosmicBuffer, CosmicEditor}; +#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] +pub struct FocusSet; + +pub struct FocusPlugin; + +impl Plugin for FocusPlugin { + fn build(&self, app: &mut App) { + app.add_systems( + PostUpdate, + (drop_editor_unfocused, add_editor_to_focused) + .chain() + .in_set(FocusSet), + ) + .init_resource::<FocusedWidget>(); + } +} + /// Resource struct that keeps track of the currently active editor entity. #[derive(Resource, Default, Deref, DerefMut)] pub struct FocusedWidget(pub Option<Entity>); diff --git a/src/input.rs b/src/input.rs index be89f1f..53481ca 100644 --- a/src/input.rs +++ b/src/input.rs @@ -21,11 +21,29 @@ use wasm_bindgen_futures::JsFuture; use crate::{ buffer::{get_x_offset_center, get_y_offset_center, BufferExtras}, + focus::FocusedWidget, get_node_cursor_pos, CosmicBuffer, CosmicEditor, CosmicFontSystem, CosmicMaxChars, - CosmicMaxLines, CosmicSource, CosmicTextChanged, CosmicTextPosition, FocusedWidget, ReadOnly, - XOffset, + CosmicMaxLines, CosmicSource, CosmicTextChanged, CosmicTextPosition, ReadOnly, XOffset, }; +#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] +pub struct InputSet; + +pub struct InputPlugin; + +impl Plugin for InputPlugin { + fn build(&self, app: &mut App) { + app.add_systems(PreUpdate, input_mouse.in_set(InputSet)) + .add_systems( + Update, + (kb_move_cursor, kb_input_text, kb_clipboard) + .chain() + .in_set(InputSet), + ) + .insert_resource(ClickTimer(Timer::from_seconds(0.5, TimerMode::Once))); + } +} + #[derive(Resource)] pub struct ClickTimer(pub Timer); diff --git a/src/lib.rs b/src/lib.rs index 1cc13e0..f877f2a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,36 +4,64 @@ mod buffer; mod cursor; pub mod focus; mod input; -mod layout; +pub mod password; +pub mod placeholder; mod render; - -mod plugins; -pub use plugins::*; +mod widget; use std::{path::PathBuf, time::Duration}; use bevy::{prelude::*, transform::TransformSystem}; -use buffer::{ - add_font_system, set_editor_redraw, set_initial_scale, set_redraw, swap_target_handle, -}; -pub use buffer::{get_x_offset_center, get_y_offset_center, CosmicBuffer}; +pub use buffer::*; pub use cosmic_text::{ - Action, Attrs, AttrsOwned, Color as CosmicColor, Cursor, Edit, Family, Metrics, Shaping, - Style as FontStyle, Weight as FontWeight, + Action, Attrs, AttrsOwned, Buffer, Color as CosmicColor, Cursor, Edit, Editor, Family, + FontSystem, Metrics, Shaping, Style as FontStyle, Weight as FontWeight, }; -use cosmic_text::{Buffer, Editor, FontSystem, SwashCache}; -use cursor::{change_cursor, hover_sprites, hover_ui}; -pub use cursor::{TextHoverIn, TextHoverOut}; +pub use cursor::*; pub use focus::*; -use input::{input_mouse, kb_clipboard, kb_input_text, kb_move_cursor, ClickTimer}; +pub use input::*; #[cfg(target_arch = "wasm32")] use input::{poll_wasm_paste, WasmPaste, WasmPasteAsyncChannel}; -use layout::{ - new_image_from_default, reshape, set_buffer_size, set_padding, set_sprite_size_from_ui, - set_widget_size, set_x_offset, CosmicPadding, CosmicWidgetSize, -}; -use render::{blink_cursor, render_texture, SwashCacheState}; +pub use password::*; +pub use placeholder::*; +pub use render::*; +pub use widget::*; + +/// Plugin struct that adds systems and initializes resources related to cosmic edit functionality. +#[derive(Default)] +pub struct CosmicEditPlugin { + pub font_config: CosmicFontConfig, + pub change_cursor: CursorConfig, +} + +impl Plugin for CosmicEditPlugin { + fn build(&self, app: &mut App) { + let font_system = create_cosmic_font_system(self.font_config.clone()); + + app.add_plugins(( + BufferPlugin, + RenderPlugin, + WidgetPlugin, + InputPlugin, + FocusPlugin, + CursorPlugin { + change_cursor: self.change_cursor.clone(), + }, + PlaceholderPlugin, + PasswordPlugin, + )) + .insert_resource(CosmicFontSystem(font_system)) + .add_event::<CosmicTextChanged>(); + + #[cfg(target_arch = "wasm32")] + { + let (tx, rx) = crossbeam_channel::bounded::<WasmPaste>(1); + app.insert_resource(WasmPasteAsyncChannel { tx, rx }) + .add_systems(Update, poll_wasm_paste); + } + } +} #[cfg(feature = "multicam")] #[derive(Component)] @@ -46,7 +74,7 @@ pub enum CosmicMode { Wrap, } -#[derive(Default)] +#[derive(Default, Clone)] pub enum CursorConfig { #[default] Default, @@ -200,105 +228,6 @@ impl Default for CosmicFontConfig { } } -#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] -pub struct KbInput; - -#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] -pub struct Render; - -/// Plugin struct that adds systems and initializes resources related to cosmic edit functionality. -#[derive(Default)] -pub struct CosmicEditPlugin { - pub font_config: CosmicFontConfig, - pub change_cursor: CursorConfig, -} - -impl Plugin for CosmicEditPlugin { - fn build(&self, app: &mut App) { - let font_system = create_cosmic_font_system(self.font_config.clone()); - - let layout_systems = ( - (new_image_from_default, set_sprite_size_from_ui), - set_widget_size, - set_buffer_size, - set_padding, - set_x_offset, - ) - .chain(); - - app.add_systems( - First, - ( - add_font_system, - set_initial_scale, - set_redraw, - set_editor_redraw, - swap_target_handle, - ) - .chain(), - ) - .add_systems(PreUpdate, (input_mouse,).chain()) - .add_systems( - Update, - ( - (kb_move_cursor, kb_input_text, kb_clipboard, reshape) - .chain() - .in_set(KbInput), - blink_cursor, - ), - ) - .add_systems( - PostUpdate, - ( - layout_systems, - drop_editor_unfocused, - add_editor_to_focused, - render_texture, - ) - .chain() - .in_set(Render) - .after(TransformSystem::TransformPropagate), - ) - .init_resource::<FocusedWidget>() - .insert_resource(SwashCacheState { - swash_cache: SwashCache::new(), - }) - .insert_resource(CosmicFontSystem(font_system)) - .insert_resource(ClickTimer(Timer::from_seconds(0.5, TimerMode::Once))) - .add_event::<CosmicTextChanged>(); - - match self.change_cursor { - CursorConfig::Default => { - app.add_systems(Update, (hover_sprites, hover_ui, change_cursor)) - .add_event::<TextHoverIn>() - .add_event::<TextHoverOut>(); - } - CursorConfig::Events => { - app.add_systems(Update, (hover_sprites, hover_ui)) - .add_event::<TextHoverIn>() - .add_event::<TextHoverOut>(); - } - CursorConfig::None => {} - } - - #[cfg(target_arch = "wasm32")] - { - let (tx, rx) = crossbeam_channel::bounded::<WasmPaste>(1); - app.insert_resource(WasmPasteAsyncChannel { tx, rx }) - .add_systems(Update, poll_wasm_paste); - } - - add_feature_plugins(app); - } -} - -fn add_feature_plugins(app: &mut App) -> &mut App { - app.add_plugins(plugins::placeholder::PlaceholderPlugin); - app.add_plugins(plugins::password::PasswordPlugin); - - app -} - 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(); diff --git a/src/plugins/password/mod.rs b/src/password.rs similarity index 95% rename from src/plugins/password/mod.rs rename to src/password.rs index a36109c..fcfac40 100644 --- a/src/plugins/password/mod.rs +++ b/src/password.rs @@ -1,11 +1,11 @@ -use crate::{buffer::BufferExtras, placeholder::Placeholder}; +use crate::{buffer::BufferExtras, placeholder::Placeholder, render::RenderSet}; use bevy::prelude::*; use cosmic_text::{Cursor, Edit, Selection, Shaping}; use unicode_segmentation::UnicodeSegmentation; use crate::{ input::{input_mouse, kb_input_text, kb_move_cursor}, - CosmicBuffer, CosmicEditor, CosmicFontSystem, DefaultAttrs, Render, + CosmicBuffer, CosmicEditor, CosmicFontSystem, DefaultAttrs, }; pub struct PasswordPlugin; @@ -25,8 +25,8 @@ impl Plugin for PasswordPlugin { .add_systems( PostUpdate, ( - hide_password_text.before(Render).in_set(PasswordSet), - restore_password_text.after(Render), + hide_password_text.before(RenderSet).in_set(PasswordSet), + restore_password_text.after(RenderSet), ), ); } diff --git a/src/plugins/placeholder/mod.rs b/src/placeholder.rs similarity index 96% rename from src/plugins/placeholder/mod.rs rename to src/placeholder.rs index a180779..f38a94b 100644 --- a/src/plugins/placeholder/mod.rs +++ b/src/placeholder.rs @@ -1,10 +1,8 @@ -use crate::{buffer::BufferExtras, Render}; +use crate::{buffer::BufferExtras, input::InputSet, render::RenderSet}; use bevy::prelude::*; use cosmic_text::{Attrs, Edit}; -use crate::{ - CosmicBuffer, CosmicEditor, CosmicFontSystem, CosmicTextChanged, DefaultAttrs, KbInput, -}; +use crate::{CosmicBuffer, CosmicEditor, CosmicFontSystem, CosmicTextChanged, DefaultAttrs}; #[derive(Component)] pub struct Placeholder { @@ -40,8 +38,8 @@ impl Plugin for PlaceholderPlugin { remove_placeholder_on_input, ) .chain() - .after(KbInput) - .before(Render), + .after(InputSet) + .before(RenderSet), ); } } diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs deleted file mode 100644 index 08a7f60..0000000 --- a/src/plugins/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod password; -pub mod placeholder; diff --git a/src/render.rs b/src/render.rs index 78e376e..6283d54 100644 --- a/src/render.rs +++ b/src/render.rs @@ -3,11 +3,29 @@ use cosmic_text::{Color, Edit, SwashCache}; use image::{imageops::FilterType, GenericImageView}; use crate::{ - layout::{CosmicPadding, CosmicWidgetSize}, + widget::{CosmicPadding, CosmicWidgetSize, WidgetSet}, CosmicBackground, CosmicBuffer, CosmicEditor, CosmicFontSystem, CosmicTextPosition, CursorColor, DefaultAttrs, FillColor, ReadOnly, SelectionColor, XOffset, }; +#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] +pub struct RenderSet; + +pub struct RenderPlugin; + +impl Plugin for RenderPlugin { + fn build(&self, app: &mut App) { + app.insert_resource(SwashCacheState { + swash_cache: SwashCache::new(), + }) + .add_systems(Update, blink_cursor) + .add_systems( + PostUpdate, + (render_texture,).in_set(RenderSet).after(WidgetSet), + ); + } +} + #[derive(Resource)] pub(crate) struct SwashCacheState { pub swash_cache: SwashCache, @@ -63,7 +81,7 @@ fn draw_pixel(buffer: &mut [u8], width: i32, height: i32, x: i32, y: i32, color: buffer[offset + 3] = (out.a() * 255.0) as u8; } -pub(crate) fn render_texture( +fn render_texture( mut query: Query<( Option<&mut CosmicEditor>, &mut CosmicBuffer, diff --git a/src/layout.rs b/src/widget.rs similarity index 87% rename from src/layout.rs rename to src/widget.rs index f5d0bce..e20047a 100644 --- a/src/layout.rs +++ b/src/widget.rs @@ -2,7 +2,34 @@ use crate::*; use bevy::{prelude::*, window::PrimaryWindow}; use cosmic_text::Affinity; -use self::buffer::{get_x_offset_center, get_y_offset_center}; +use self::{ + buffer::{get_x_offset_center, get_y_offset_center}, + input::InputSet, +}; + +#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] +pub struct WidgetSet; + +pub struct WidgetPlugin; + +impl Plugin for WidgetPlugin { + fn build(&self, app: &mut App) { + app.add_systems(Update, reshape.in_set(WidgetSet).after(InputSet)) + .add_systems( + PostUpdate, + ( + (new_image_from_default, set_sprite_size_from_ui), + set_widget_size, + set_buffer_size, + set_padding, + set_x_offset, + ) + .chain() + .in_set(WidgetSet) + .after(TransformSystem::TransformPropagate), + ); + } +} #[derive(Component, Default, Deref, DerefMut, Debug)] pub struct CosmicPadding(pub Vec2); diff --git a/util/src/lib.rs b/util/src/lib.rs index 405152c..e1e1dd1 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -1,6 +1,6 @@ // Common functions for examples use bevy::{prelude::*, window::PrimaryWindow}; -use bevy_cosmic_edit::*; +use bevy_cosmic_edit::{focus::FocusedWidget, *}; pub fn deselect_editor_on_esc(i: Res<ButtonInput<KeyCode>>, mut focus: ResMut<FocusedWidget>) { if i.just_pressed(KeyCode::Escape) { -- GitLab