From efe2ac7cedc0e7e475d553d21c0f2a4dc1cb1660 Mon Sep 17 00:00:00 2001
From: sam edelsten <samedelsten1@gmail.com>
Date: Tue, 9 Apr 2024 09:41:09 +0100
Subject: [PATCH] use editor buffer for infinite line

need to get my numbers right but the implementation is doing at least
something again
---
 examples/sprite_and_ui_clickable.rs |  1 +
 src/input.rs                        |  4 +--
 src/layout.rs                       | 52 ++++++++++++++++-------------
 src/lib.rs                          | 13 +++++---
 src/render.rs                       |  2 +-
 5 files changed, 40 insertions(+), 32 deletions(-)

diff --git a/examples/sprite_and_ui_clickable.rs b/examples/sprite_and_ui_clickable.rs
index 31d4e76..375c1eb 100644
--- a/examples/sprite_and_ui_clickable.rs
+++ b/examples/sprite_and_ui_clickable.rs
@@ -15,6 +15,7 @@ fn setup(mut commands: Commands) {
                 Attrs::new().color(bevy_color_to_cosmic(Color::GREEN)),
             )),
             max_lines: CosmicMaxLines(1),
+            mode: CosmicMode::InfiniteLine,
             ..default()
         })
         .id();
diff --git a/src/input.rs b/src/input.rs
index 087cef0..ab4af4e 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -153,7 +153,7 @@ pub(crate) fn input_mouse(
                 camera_transform,
             ) {
                 let (mut x, y) = point(node_cursor_pos);
-                x += x_offset.0.unwrap_or((0., 0.)).0 as i32;
+                x += x_offset.min as i32;
                 if shift {
                     editor.action(&mut font_system.0, Action::Drag { x, y });
                 } else {
@@ -193,7 +193,7 @@ pub(crate) fn input_mouse(
                 camera_transform,
             ) {
                 let (mut x, y) = point(node_cursor_pos);
-                x += x_offset.0.unwrap_or((0., 0.)).0 as i32;
+                x += x_offset.min as i32;
                 if active_editor.is_changed() && !shift {
                     editor.action(&mut font_system.0, Action::Click { x, y });
                 } else {
diff --git a/src/layout.rs b/src/layout.rs
index 2665d9a..b0cd386 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -4,10 +4,10 @@ use cosmic_text::Affinity;
 
 use self::buffer::{get_x_offset_center, get_y_offset_center};
 
-#[derive(Component, Default)]
+#[derive(Component, Default, Deref, DerefMut, Debug)]
 pub struct CosmicPadding(pub Vec2);
 
-#[derive(Component, Default)]
+#[derive(Component, Default, Deref, DerefMut)]
 pub struct CosmicWidgetSize(pub Vec2);
 
 pub fn reshape(mut query: Query<&mut CosmicEditor>, mut font_system: ResMut<CosmicFontSystem>) {
@@ -114,47 +114,51 @@ pub fn new_image_from_default(
     }
 }
 
-pub fn set_cursor(
+pub fn set_x_offset(
     mut query: Query<(
         &mut XOffset,
         &CosmicMode,
         &CosmicEditor,
-        &CosmicBuffer,
         &CosmicWidgetSize,
         &CosmicPadding,
     )>,
 ) {
-    for (mut x_offset, mode, editor, buffer, size, padding) in query.iter_mut() {
+    for (mut x_offset, mode, editor, size, padding) in query.iter_mut() {
+        if mode != &CosmicMode::InfiniteLine {
+            return;
+        }
+
         let mut cursor_x = 0.;
-        if mode == &CosmicMode::InfiniteLine {
-            if let Some(line) = buffer.layout_runs().next() {
-                for (idx, glyph) in line.glyphs.iter().enumerate() {
-                    if editor.cursor().affinity == Affinity::Before {
-                        if idx <= editor.cursor().index {
-                            cursor_x += glyph.w;
-                        }
-                    } else if idx < editor.cursor().index {
+
+        if let Some(line) = editor.with_buffer(|b| b.clone()).layout_runs().next() {
+            for (idx, glyph) in line.glyphs.iter().enumerate() {
+                if editor.cursor().affinity == Affinity::Before {
+                    if idx <= editor.cursor().index {
                         cursor_x += glyph.w;
                     } else {
                         break;
                     }
+                } else if idx < editor.cursor().index {
+                    cursor_x += glyph.w;
+                } else {
+                    break;
                 }
             }
         }
 
-        if mode == &CosmicMode::InfiniteLine && x_offset.0.is_none() {
-            *x_offset = XOffset(Some((0., size.0.x - 2. * padding.0.x)));
+        if x_offset.min == 0. && x_offset.max == 0. {
+            x_offset.max = size.x;
         }
 
-        if let Some((x_min, x_max)) = x_offset.0 {
-            if cursor_x > x_max {
-                let diff = cursor_x - x_max;
-                *x_offset = XOffset(Some((x_min + diff, cursor_x)));
-            }
-            if cursor_x < x_min {
-                let diff = x_min - cursor_x;
-                *x_offset = XOffset(Some((cursor_x, x_max - diff)));
-            }
+        if cursor_x > x_offset.max {
+            let diff = cursor_x - x_offset.max;
+            x_offset.min += diff;
+            x_offset.max = cursor_x;
+        }
+        if cursor_x < x_offset.min {
+            let diff = x_offset.min - cursor_x;
+            x_offset.min = cursor_x;
+            x_offset.max -= diff;
         }
     }
 }
diff --git a/src/lib.rs b/src/lib.rs
index be98184..96b04a1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -30,8 +30,8 @@ use input::{input_kb, input_mouse, ClickTimer};
 #[cfg(target_arch = "wasm32")]
 use input::{poll_wasm_paste, WasmPaste, WasmPasteAsyncChannel};
 use layout::{
-    new_image_from_default, reshape, set_buffer_size, set_cursor, set_padding,
-    set_sprite_size_from_ui, set_widget_size, CosmicPadding, CosmicWidgetSize,
+    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};
 
@@ -77,7 +77,10 @@ pub struct CosmicFontSystem(pub FontSystem);
 pub struct ReadOnly; // tag component
 
 #[derive(Component, Debug, Default)]
-pub struct XOffset(Option<(f32, f32)>);
+pub struct XOffset {
+    pub min: f32,
+    pub max: f32,
+}
 
 #[derive(Component, Deref, DerefMut)]
 pub struct CosmicEditor {
@@ -170,7 +173,7 @@ impl Default for CosmicEditBundle {
                 visibility: Visibility::Hidden,
                 ..default()
             },
-            x_offset: XOffset(None),
+            x_offset: Default::default(),
             padding: Default::default(),
             widget_size: Default::default(),
         }
@@ -215,7 +218,7 @@ impl Plugin for CosmicEditPlugin {
             set_widget_size,
             set_buffer_size,
             set_padding,
-            set_cursor,
+            set_x_offset,
         )
             .chain();
 
diff --git a/src/render.rs b/src/render.rs
index 730d8c0..e66e95d 100644
--- a/src/render.rs
+++ b/src/render.rs
@@ -140,7 +140,7 @@ pub(crate) fn render_texture(
                         &mut pixels,
                         size.0.x as i32,
                         size.0.y as i32,
-                        x + col + padding.0.x as i32 - x_offset.0.unwrap_or((0., 0.)).0 as i32,
+                        x + col + padding.0.x as i32 - x_offset.min as i32,
                         y + row + padding.0.y as i32,
                         color,
                     );
-- 
GitLab