From c527d1d0a3583278c88e2dfb68cc6f5b14a5d3ef Mon Sep 17 00:00:00 2001 From: Rob Parrett Date: Sat, 24 Aug 2024 12:29:31 -0700 Subject: [PATCH] Test: required components --- Cargo.toml | 7 +++- examples/basic.rs | 7 ++-- examples/focus.rs | 22 ++++++---- examples/password.rs | 26 ++++++------ examples/value.rs | 18 ++++---- src/lib.rs | 97 ++++++++++++-------------------------------- 6 files changed, 73 insertions(+), 104 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ff97b64..306480b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,14 +15,17 @@ exclude = [".github"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies.bevy] -git = "https://github.com/bevyengine/bevy" +git = "https://github.com/cart/bevy" +branch = "required-components" default-features = false features = ["bevy_ui", "bevy_asset", "bevy_text"] [dev-dependencies.bevy] -git = "https://github.com/bevyengine/bevy" +git = "https://github.com/cart/bevy" +branch = "required-components" default-features = true + [lints.rust] missing_docs = "warn" diff --git a/examples/basic.rs b/examples/basic.rs index 6510a57..056b0ad 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -1,8 +1,8 @@ //! An example showing a very basic implementation. -use bevy::prelude::*; +use bevy::{input::common_conditions::input_just_pressed, prelude::*}; use bevy_simple_text_input::{ - TextInputBundle, TextInputPlugin, TextInputSubmitEvent, TextInputSystem, + TextInput, TextInputPlugin, TextInputSubmitEvent, TextInputSystem, TextInputTextStyle, }; const BORDER_COLOR_ACTIVE: Color = Color::srgb(0.75, 0.52, 0.99); @@ -45,7 +45,8 @@ fn setup(mut commands: Commands) { background_color: BACKGROUND_COLOR.into(), ..default() }, - TextInputBundle::default().with_text_style(TextStyle { + TextInput, + TextInputTextStyle(TextStyle { font_size: 34., color: TEXT_COLOR, ..default() diff --git a/examples/focus.rs b/examples/focus.rs index 89fc4ef..3fbd3fb 100644 --- a/examples/focus.rs +++ b/examples/focus.rs @@ -2,7 +2,8 @@ use bevy::prelude::*; use bevy_simple_text_input::{ - TextInputBundle, TextInputInactive, TextInputPlugin, TextInputSystem, + TextInput, TextInputInactive, TextInputPlaceholder, TextInputPlugin, TextInputSystem, + TextInputTextStyle, }; const BORDER_COLOR_ACTIVE: Color = Color::srgb(0.75, 0.52, 0.99); @@ -54,14 +55,17 @@ fn setup(mut commands: Commands) { focus_policy: bevy::ui::FocusPolicy::Block, ..default() }, - TextInputBundle::default() - .with_text_style(TextStyle { - font_size: 34., - color: TEXT_COLOR, - ..default() - }) - .with_placeholder("Click Me", None) - .with_inactive(true), + TextInput, + TextInputTextStyle(TextStyle { + font_size: 34., + color: TEXT_COLOR, + ..default() + }), + TextInputPlaceholder { + value: "Click Me".to_string(), + text_style: None, + }, + TextInputInactive(true), )); }); } diff --git a/examples/password.rs b/examples/password.rs index 570a2d0..cb8b928 100644 --- a/examples/password.rs +++ b/examples/password.rs @@ -1,7 +1,9 @@ //! An example showing a masked input for passwords. use bevy::prelude::*; -use bevy_simple_text_input::{TextInputBundle, TextInputPlugin, TextInputSettings}; +use bevy_simple_text_input::{ + TextInput, TextInputPlugin, TextInputSettings, TextInputTextStyle, TextInputValue, +}; const BORDER_COLOR_ACTIVE: Color = Color::srgb(0.75, 0.52, 0.99); const TEXT_COLOR: Color = Color::srgb(0.9, 0.9, 0.9); @@ -42,17 +44,17 @@ fn setup(mut commands: Commands) { background_color: BACKGROUND_COLOR.into(), ..default() }, - TextInputBundle::default() - .with_value("password") - .with_text_style(TextStyle { - font_size: 34., - color: TEXT_COLOR, - ..default() - }) - .with_settings(TextInputSettings { - mask_character: Some('*'), - retain_on_submit: true, - }), + TextInput, + TextInputValue("password".to_string()), + TextInputTextStyle(TextStyle { + font_size: 34., + color: TEXT_COLOR, + ..default() + }), + TextInputSettings { + mask_character: Some('*'), + retain_on_submit: true, + }, )); }); } diff --git a/examples/value.rs b/examples/value.rs index edef971..c3ecead 100644 --- a/examples/value.rs +++ b/examples/value.rs @@ -1,7 +1,9 @@ //! An example showing a text input that is updated by a button. use bevy::prelude::*; -use bevy_simple_text_input::{TextInputBundle, TextInputPlugin, TextInputSettings, TextInputValue}; +use bevy_simple_text_input::{ + TextInput, TextInputPlugin, TextInputSettings, TextInputTextStyle, TextInputValue, +}; const BORDER_COLOR_ACTIVE: Color = Color::srgb(0.75, 0.52, 0.99); const BORDER_COLOR_INACTIVE: Color = Color::srgb(0.25, 0.25, 0.25); @@ -55,13 +57,13 @@ fn setup(mut commands: Commands) { background_color: BACKGROUND_COLOR.into(), ..default() }, - TextInputBundle::default() - .with_text_style(text_style.clone()) - .with_value("1") - .with_settings(TextInputSettings { - retain_on_submit: true, - ..default() - }), + TextInput, + TextInputTextStyle(text_style.clone()), + TextInputValue("1".to_string()), + TextInputSettings { + retain_on_submit: true, + ..default() + }, )); parent diff --git a/src/lib.rs b/src/lib.rs index 169f03b..a3ce689 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -77,9 +77,9 @@ impl Plugin for TextInputPlugin { const CURSOR_HANDLE: Handle = Handle::weak_from_u128(10482756907980398621); -/// A bundle providing the additional components required for a text input. +/// Marker component for a TextInput entity. /// -/// Add this to a Bevy `NodeBundle`. +/// Add this to a NodeBundle. /// /// # Example /// @@ -87,73 +87,20 @@ const CURSOR_HANDLE: Handle = Handle::weak_from_u128(10482756907980398621) /// # use bevy::prelude::*; /// use bevy_simple_text_input::TextInputBundle; /// fn setup(mut commands: Commands) { -/// commands.spawn((NodeBundle::default(), TextInputBundle::default())); +/// commands.spawn((NodeBundle::default(), TextInput)); /// } /// ``` -#[derive(Bundle, Default, Reflect)] -pub struct TextInputBundle { - /// A component containing the text input's settings. - pub settings: TextInputSettings, - /// A component containing the Bevy `TextStyle` that will be used when creating the text input's inner Bevy `TextBundle`. - pub text_style: TextInputTextStyle, - /// A component containing a value indicating whether the text input is active or not. - pub inactive: TextInputInactive, - /// A component that manages the cursor's blinking. - pub cursor_timer: TextInputCursorTimer, - /// A component containing the current text cursor position. - pub cursor_pos: TextInputCursorPos, - /// A component containing the current value of the text input. - pub value: TextInputValue, - /// A component containing the placeholder text that is displayed when the text input is empty and not focused. - pub placeholder: TextInputPlaceholder, - /// This component's value is managed by Bevy's UI systems and enables tracking of hovers and presses. - pub interaction: Interaction, -} - -impl TextInputBundle { - /// Returns this [`TextInputBundle`] with a new [`TextInputValue`] containing the provided `String`. - /// - /// This also sets [`TextInputCursorPos`] so that the cursor position is at the end of the provided `String`. - pub fn with_value(mut self, value: impl Into) -> Self { - let owned = value.into(); - - self.cursor_pos = TextInputCursorPos(owned.len()); - self.value = TextInputValue(owned); - - self - } - - /// Returns this [`TextInputBundle`] with a new [`TextInputPlaceholder`] containing the provided `String`. - pub fn with_placeholder( - mut self, - placeholder: impl Into, - text_style: Option, - ) -> Self { - self.placeholder = TextInputPlaceholder { - value: placeholder.into(), - text_style, - }; - self - } - - /// Returns this [`TextInputBundle`] with a new [`TextInputTextStyle`] containing the provided Bevy `TextStyle`. - pub fn with_text_style(mut self, text_style: TextStyle) -> Self { - self.text_style = TextInputTextStyle(text_style); - self - } - - /// Returns this [`TextInputBundle`] with a new [`TextInputInactive`] containing the provided `bool`. - pub fn with_inactive(mut self, inactive: bool) -> Self { - self.inactive = TextInputInactive(inactive); - self - } - - /// Returns this [`TextInputBundle`] with a new [`TextInputSettings`]. - pub fn with_settings(mut self, settings: TextInputSettings) -> Self { - self.settings = settings; - self - } -} +#[derive(Component)] +#[require( + TextInputSettings, + TextInputTextStyle, + TextInputInactive, + TextInputCursorTimer, + TextInputValue, + TextInputPlaceholder, + Interaction +)] +pub struct TextInput; /// The Bevy `TextStyle` that will be used when creating the text input's inner Bevy `TextBundle`. #[derive(Component, Default, Reflect)] @@ -603,17 +550,27 @@ fn create( trigger: Trigger, mut commands: Commands, query: Query<( + Entity, &TextInputTextStyle, &TextInputValue, - &TextInputCursorPos, + Option<&TextInputCursorPos>, &TextInputInactive, &TextInputSettings, &TextInputPlaceholder, )>, ) { - if let Ok((style, text_input, cursor_pos, inactive, settings, placeholder)) = + if let Ok((entity, style, text_input, maybe_cursor_pos, inactive, settings, placeholder)) = &query.get(trigger.entity()) { + let cursor_pos = match maybe_cursor_pos { + None => { + let len = text_input.0.len(); + commands.entity(*entity).insert(TextInputCursorPos(len)); + len + } + Some(cursor_pos) => cursor_pos.0, + }; + let mut sections = vec![ // Pre-cursor TextSection { @@ -642,7 +599,7 @@ fn create( set_section_values( &masked_value(&text_input.0, settings.mask_character), - cursor_pos.0, + cursor_pos, &mut sections, );