Skip to content
Snippets Groups Projects
Unverified Commit 91ba7561 authored by sam's avatar sam Committed by GitHub
Browse files

rework placeholders to use single editor (#105)

* rework placeholders to use single editor

* add default placeholder color

* move placeholder systems out of main render

* explicit ordering for password/placeholder systems
parent 2ea39ed6
No related branches found
No related tags found
No related merge requests found
......@@ -21,8 +21,9 @@ use input::{input_kb, input_mouse, undo_redo, ClickTimer};
use input::{poll_wasm_paste, WasmPaste, WasmPasteAsyncChannel};
use render::{
blink_cursor, cosmic_edit_redraw_buffer, freeze_cursor_blink, hide_inactive_or_readonly_cursor,
hide_password_text, on_scale_factor_change, restore_password_text, set_initial_scale,
CursorBlinkTimer, CursorVisibility, PasswordValues, SwashCacheState,
hide_password_text, on_scale_factor_change, restore_password_text, restore_placeholder_text,
set_initial_scale, show_placeholder, CursorBlinkTimer, CursorVisibility, PasswordValues,
SwashCacheState,
};
#[cfg(feature = "multicam")]
......@@ -196,15 +197,20 @@ pub struct CosmicMaxChars(pub usize);
#[derive(Component, Default)]
pub struct FillColor(pub Color);
#[derive(Component)]
pub struct Placeholder(pub CosmicEditor);
#[derive(Component, Default)]
pub struct PlaceholderText(pub CosmicText);
#[derive(Component)]
pub struct PlaceholderAttrs(pub AttrsOwned);
impl Default for PlaceholderAttrs {
fn default() -> Self {
Self(AttrsOwned::new(
Attrs::new().color(CosmicColor::rgb(128, 128, 128)),
))
}
}
#[derive(Component)]
pub struct PasswordInput(pub char);
......@@ -214,12 +220,6 @@ impl Default for PasswordInput {
}
}
impl Default for PlaceholderAttrs {
fn default() -> Self {
Self(AttrsOwned::new(Attrs::new()))
}
}
#[derive(Component)]
pub struct CosmicCanvas(pub Handle<Image>);
......@@ -297,7 +297,6 @@ impl Plugin for CosmicEditPlugin {
fn build(&self, app: &mut App) {
let font_system = create_cosmic_font_system(self.font_config.clone());
let update_texts = (update_buffer_text, update_placeholder_text);
let main_unordered = (
init_history,
input_kb,
......@@ -314,12 +313,7 @@ impl Plugin for CosmicEditPlugin {
First,
(
set_initial_scale,
(
cosmic_editor_builder,
placeholder_builder,
on_scale_factor_change,
)
.after(set_initial_scale),
(cosmic_editor_builder, on_scale_factor_change).after(set_initial_scale),
render::cosmic_ui_to_canvas,
render::cosmic_sprite_to_canvas,
),
......@@ -327,7 +321,7 @@ impl Plugin for CosmicEditPlugin {
.add_systems(
PreUpdate,
(
update_texts,
update_buffer_text,
main_unordered,
hide_password_text,
input_mouse,
......@@ -339,12 +333,13 @@ impl Plugin for CosmicEditPlugin {
PostUpdate,
(
hide_password_text,
cosmic_edit_redraw_buffer
.after(TransformSystem::TransformPropagate)
.after(hide_password_text)
.before(restore_password_text),
show_placeholder,
cosmic_edit_redraw_buffer.after(TransformSystem::TransformPropagate),
apply_deferred, // Prevents one-frame inputs adding placeholder to editor
restore_password_text,
),
restore_placeholder_text,
)
.chain(),
)
.init_resource::<Focus>()
.init_resource::<PasswordValues>()
......@@ -441,23 +436,6 @@ fn cosmic_editor_builder(
}
}
fn placeholder_builder(
mut added_editors: Query<(Entity, &CosmicMetrics), Added<PlaceholderText>>,
mut font_system: ResMut<CosmicFontSystem>,
mut commands: Commands,
) {
for (entity, metrics) in added_editors.iter_mut() {
let buffer = Buffer::new(
&mut font_system.0,
Metrics::new(metrics.font_size, metrics.line_height).scale(metrics.scale_factor),
);
let editor = CosmicEditor(Editor::new(buffer));
commands.entity(entity).insert(Placeholder(editor));
}
}
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();
......@@ -531,21 +509,6 @@ fn update_buffer_text(
}
}
/// Updates editor buffer when text component changes
fn update_placeholder_text(
mut editor_q: Query<
(&mut Placeholder, &mut PlaceholderText, &PlaceholderAttrs),
Changed<PlaceholderText>,
>,
mut font_system: ResMut<CosmicFontSystem>,
) {
for (mut editor, text, attrs) in editor_q.iter_mut() {
editor
.0
.set_text(text.0.to_owned(), attrs.0.clone(), &mut font_system.0);
}
}
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
......
......@@ -13,8 +13,8 @@ use image::{imageops::FilterType, GenericImageView};
use crate::{
get_text_size, get_x_offset_center, get_y_offset_center, CosmicAttrs, CosmicBackground,
CosmicCanvas, CosmicEditor, CosmicFontSystem, CosmicMetrics, CosmicMode, CosmicText,
CosmicTextPosition, FillColor, Focus, PasswordInput, Placeholder, ReadOnly, XOffset,
DEFAULT_SCALE_PLACEHOLDER,
CosmicTextPosition, FillColor, Focus, PasswordInput, PlaceholderAttrs, PlaceholderText,
ReadOnly, XOffset, DEFAULT_SCALE_PLACEHOLDER,
};
#[derive(Resource)]
......@@ -31,6 +31,9 @@ pub(crate) struct CursorVisibility(pub bool);
#[derive(Resource, Default)]
pub(crate) struct PasswordValues(pub HashMap<Entity, (String, usize)>);
#[derive(Component)]
pub(crate) struct Placeholder;
pub(crate) fn cosmic_edit_redraw_buffer(
windows: Query<&Window, With<PrimaryWindow>>,
mut images: ResMut<Assets<Image>>,
......@@ -47,7 +50,6 @@ pub(crate) fn cosmic_edit_redraw_buffer(
Option<&mut Sprite>,
&mut XOffset,
&CosmicMode,
Option<&mut Placeholder>,
)>,
mut font_system: ResMut<CosmicFontSystem>,
) {
......@@ -66,30 +68,13 @@ pub(crate) fn cosmic_edit_redraw_buffer(
sprite_opt,
mut x_offset,
mode,
mut placeholder_opt,
) in &mut cosmic_edit_query.iter_mut()
{
if !cosmic_editor.0.buffer().redraw() {
continue;
}
let current_text = cosmic_editor.get_text();
// Check for placeholder, replace editor if found and buffer is empty
let editor = if current_text.is_empty() && placeholder_opt.is_some() {
let placeholder = &mut placeholder_opt.as_mut().unwrap().0 .0;
placeholder.buffer_mut().set_redraw(true);
cosmic_editor.0.buffer_mut().set_redraw(true);
let mut cursor = placeholder.cursor();
cursor.index = 0;
placeholder.set_cursor(cursor);
*x_offset = XOffset(None);
placeholder
} else {
&mut cosmic_editor.0
};
let editor = &mut cosmic_editor.0;
editor.shape_as_needed(&mut font_system.0);
......@@ -326,7 +311,6 @@ pub(crate) fn blink_cursor(
time: Res<Time>,
active_editor: ResMut<Focus>,
mut cosmic_editor_q: Query<&mut CosmicEditor, Without<ReadOnly>>,
mut placeholder_editor_q: Query<&mut Placeholder, Without<ReadOnly>>,
) {
if let Some(e) = active_editor.0 {
timer.0.tick(time.delta());
......@@ -354,14 +338,6 @@ pub(crate) fn blink_cursor(
editor.set_cursor(cursor);
editor.buffer_mut().set_redraw(true);
}
if let Ok(mut placeholder) = placeholder_editor_q.get_mut(e) {
let placeholder = &mut placeholder.0 .0;
let mut cursor_p = placeholder.cursor();
cursor_p.color = new_color;
placeholder.set_cursor(cursor_p);
placeholder.buffer_mut().set_redraw(true);
}
}
}
......@@ -399,7 +375,6 @@ pub(crate) fn freeze_cursor_blink(
pub(crate) fn hide_inactive_or_readonly_cursor(
mut cosmic_editor_q_readonly: Query<&mut CosmicEditor, With<ReadOnly>>,
mut cosmic_editor_q_placeholder: Query<(Entity, &mut Placeholder, Option<&ReadOnly>)>,
mut cosmic_editor_q_editable: Query<(Entity, &mut CosmicEditor), Without<ReadOnly>>,
active_editor: Res<Focus>,
) {
......@@ -410,20 +385,6 @@ pub(crate) fn hide_inactive_or_readonly_cursor(
editor.0.buffer_mut().set_redraw(true);
}
for (e, mut editor, readonly_opt) in &mut cosmic_editor_q_placeholder.iter_mut() {
// filthy short circuiting instead of correct unwrapping
if active_editor.is_none() || e != active_editor.0.unwrap() || readonly_opt.is_some() {
let editor = &mut editor.0;
let mut cursor = editor.0.cursor();
if cursor.color == Some(cosmic_text::Color::rgba(0, 0, 0, 0)) {
continue;
}
cursor.color = Some(cosmic_text::Color::rgba(0, 0, 0, 0));
editor.0.set_cursor(cursor);
editor.0.buffer_mut().set_redraw(true);
}
}
for (e, mut editor) in &mut cosmic_editor_q_editable.iter_mut() {
if active_editor.is_none() || e != active_editor.0.unwrap() {
let mut cursor = editor.0.cursor();
......@@ -592,3 +553,41 @@ pub(crate) fn restore_password_text(
}
}
}
pub(crate) fn show_placeholder(
mut editor_q: Query<(
Entity,
&mut CosmicEditor,
&PlaceholderText,
&PlaceholderAttrs,
)>,
mut font_system: ResMut<CosmicFontSystem>,
mut commands: Commands,
) {
for (entity, mut cosmic_editor, placeholder, attrs) in editor_q.iter_mut() {
if cosmic_editor.get_text().is_empty() {
cosmic_editor.set_text(placeholder.0.clone(), attrs.0.clone(), &mut font_system.0);
let mut cursor = cosmic_editor.0.cursor();
cursor.index = 0;
cosmic_editor.0.set_cursor(cursor);
commands.entity(entity).insert(Placeholder);
} else {
commands.entity(entity).remove::<Placeholder>();
}
}
}
pub(crate) fn restore_placeholder_text(
mut editor_q: Query<(&mut CosmicEditor, &CosmicAttrs), With<Placeholder>>,
mut font_system: ResMut<CosmicFontSystem>,
) {
for (mut cosmic_editor, attrs) in editor_q.iter_mut() {
cosmic_editor.set_text(
CosmicText::OneStyle("".into()),
attrs.0.clone(),
&mut font_system.0,
);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment