From 0afd6750d0d783b78e5008f000bb174cb170461a Mon Sep 17 00:00:00 2001 From: Freja Roberts Date: Thu, 28 Mar 2024 02:22:33 +0100 Subject: [PATCH] fix: chrome pixel scroll --- violet-core/src/layout/mod.rs | 2 +- violet-core/src/systems.rs | 10 +++- violet-core/src/widget/interactive/input.rs | 57 ++++++++++++--------- violet-core/src/widget/scroll.rs | 2 +- violet-demo/public/index.html | 4 ++ violet-wgpu/src/app.rs | 19 +++---- violet-wgpu/src/systems.rs | 3 ++ 7 files changed, 58 insertions(+), 39 deletions(-) diff --git a/violet-core/src/layout/mod.rs b/violet-core/src/layout/mod.rs index 1804aeb..bb5423a 100644 --- a/violet-core/src/layout/mod.rs +++ b/violet-core/src/layout/mod.rs @@ -582,7 +582,7 @@ pub(crate) fn apply_layout(world: &World, entity: &EntityRef, args: LayoutArgs) // validate_block(entity, &block, limits); - tracing::debug!(%limits, %args.content_area, %block.can_grow, %block.rect, "caching layout"); + // tracing::info!(%entity, %limits, %args.content_area, %block.can_grow, %block.rect, ?cache.layout, "caching layout"); cache.insert_layout(CachedValue::new(limits, args.content_area, block)); block diff --git a/violet-core/src/systems.rs b/violet-core/src/systems.rs index ed7b8c6..4da9d65 100644 --- a/violet-core/src/systems.rs +++ b/violet-core/src/systems.rs @@ -1,12 +1,12 @@ use std::{ - collections::HashSet, + collections::{BTreeMap, HashSet}, sync::{Arc, Weak}, }; use atomic_refcell::AtomicRefCell; use flax::{ archetype::Storage, - component::ComponentValue, + component::{ComponentDesc, ComponentKey, ComponentValue}, components::child_of, entity_ids, events::{EventData, EventSubscriber}, @@ -15,6 +15,7 @@ use flax::{ Query, QueryBorrow, System, World, }; use glam::{Mat4, Vec2, Vec3, Vec3Swizzles}; +use itertools::Itertools; use crate::{ components::{ @@ -101,6 +102,7 @@ pub fn invalidate_cached_layout_system(world: &mut World) -> BoxedSystem { let dirty = Arc::new(AtomicRefCell::new(HashSet::new())); let invalidator = QueryInvalidator { + // name_map: components.iter().map(|v| (v.key(), v.clone())).collect(), dirty: Arc::downgrade(&dirty), }; @@ -120,6 +122,7 @@ pub fn invalidate_cached_layout_system(world: &mut World) -> BoxedSystem { } struct QueryInvalidator { + // name_map: BTreeMap, dirty: Weak>>, } @@ -133,14 +136,17 @@ impl QueryInvalidator { impl EventSubscriber for QueryInvalidator { fn on_added(&self, _: &Storage, event: &EventData) { + // tracing::info!(component = ?self.name_map[&event.key], ?event.ids, "added"); self.mark_dirty(event.ids); } fn on_modified(&self, event: &EventData) { + // tracing::info!(component = ?self.name_map[&event.key], ?event.ids, "modified"); self.mark_dirty(event.ids); } fn on_removed(&self, _: &Storage, event: &EventData) { + // tracing::info!(component = ?self.name_map[&event.key], ?event.ids, "removed"); self.mark_dirty(event.ids); } diff --git a/violet-core/src/widget/interactive/input.rs b/violet-core/src/widget/interactive/input.rs index f6717b1..541388c 100644 --- a/violet-core/src/widget/interactive/input.rs +++ b/violet-core/src/widget/interactive/input.rs @@ -177,9 +177,8 @@ impl Widget for TextInput { // text_content.send(editor.lines().iter().map(|v| v.text()).join("\n")); } new_glyphs = layout_glyphs.select_next_some() => { - glyphs = new_glyphs; - - } + glyphs = new_glyphs; + } } if let Some(glyphs) = &glyphs { @@ -260,8 +259,15 @@ impl Widget for TextInput { scope .set(focusable(), ()) .set(focus_sticky(), ()) - .on_event(on_focus(), move |_, focus| { - focused.set(focus); + .on_event(on_focus(), { + to_owned![tx]; + move |_, focus| { + focused.set(focus); + + if !focus { + tx.send(Action::Editor(EditorAction::SelectionClear)).ok(); + } + } }) .on_event(on_mouse_input(), { to_owned![layout_glyphs, text_bounds, tx, dragging]; @@ -275,15 +281,13 @@ impl Widget for TextInput { - text_bounds.transform_point3(Vec3::ZERO).xy(); if let Some(hit) = glyphs.hit(text_pos) { - dragging.set(Some(hit)); + dragging.set(Some((input.cursor.local_pos, hit))); tx.send(Action::Editor(EditorAction::CursorMove( CursorMove::SetPosition(hit), ))) .ok(); tx.send(Action::Editor(EditorAction::SelectionClear)).ok(); } - - tracing::info!(?input, "click"); } else { dragging.set(None) } @@ -295,23 +299,28 @@ impl Widget for TextInput { move |_, input| { let dragging = dragging.get(); - if let Some(dragging) = dragging { - let glyphs = layout_glyphs.lock_ref(); + let Some((drag_start, dragging)) = dragging else { + return; + }; - if let Some(glyphs) = &*glyphs { - let text_pos = input.local_pos; + if input.local_pos.distance(drag_start) < 5.0 { + return; + } - tracing::info!(?text_pos); - if let Some(hit) = glyphs.hit(text_pos) { - tx.send(Action::Editor(EditorAction::SelectionMove( - CursorMove::SetPosition(dragging), - ))) - .ok(); - tx.send(Action::Editor(EditorAction::CursorMove( - CursorMove::SetPosition(hit), - ))) - .ok(); - } + let glyphs = layout_glyphs.lock_ref(); + + if let Some(glyphs) = &*glyphs { + let text_pos = input.local_pos; + + if let Some(hit) = glyphs.hit(text_pos) { + tx.send(Action::Editor(EditorAction::SelectionMove( + CursorMove::SetPosition(dragging), + ))) + .ok(); + tx.send(Action::Editor(EditorAction::CursorMove( + CursorMove::SetPosition(hit), + ))) + .ok(); } } } @@ -335,7 +344,7 @@ impl Widget for TextInput { .monitor_signal(components::layout_glyphs(), layout_glyphs.clone()) .monitor_signal(screen_transform(), text_bounds.clone()) })), - Float::new(SignalWidget(editor_props_rx)), + Float::new(StreamWidget(editor_props_rx.to_stream())), )) .with_background(self.style.background) .with_size_props(self.size) diff --git a/violet-core/src/widget/scroll.rs b/violet-core/src/widget/scroll.rs index 7efe2b3..2a14df2 100644 --- a/violet-core/src/widget/scroll.rs +++ b/violet-core/src/widget/scroll.rs @@ -60,7 +60,7 @@ impl Widget for ScrollArea { let outer_size = Mutable::new(Vec2::ZERO); let scroll_pos = Mutable::new(Vec2::ZERO); - let sensitivity = vec2(32.0, -32.0); + let sensitivity = vec2(1.0, -1.0); scope.on_event(on_scroll(), { to_owned![size, outer_size, scroll_pos]; move |_, scroll| { diff --git a/violet-demo/public/index.html b/violet-demo/public/index.html index bb12c4c..8b80694 100644 --- a/violet-demo/public/index.html +++ b/violet-demo/public/index.html @@ -11,11 +11,15 @@ padding: 0; margin: 0px; background-color: #222222; + overflow: hidden; } .main-canvas { margin: 0; width: 100vw; height: 100vh; + /* WebGl does not support surface sized >2048 pixels */ + max-width: 2048px; + max-height: 2048px; } diff --git a/violet-wgpu/src/app.rs b/violet-wgpu/src/app.rs index 1be4a8c..889c3f7 100644 --- a/violet-wgpu/src/app.rs +++ b/violet-wgpu/src/app.rs @@ -126,7 +126,6 @@ impl AppBuilder { (canvas.client_width() as f32 * sf) as u32, (canvas.client_height() as f32 * sf) as u32, ); - tracing::info!(w, h, sf, "setting canvas size"); canvas.set_width(w as _); canvas.set_height(h as _); @@ -282,9 +281,14 @@ impl AppBuilder { puffin::profile_scope!("MouseWheel"); match delta { winit::event::MouseScrollDelta::LineDelta(x, y) => { - input_state.on_scroll(&mut instance.frame, vec2(x, y)) + const LINE_SIZE: f32 = 16.0; + input_state + .on_scroll(&mut instance.frame, vec2(x * LINE_SIZE, y * LINE_SIZE)) + } + winit::event::MouseScrollDelta::PixelDelta(pos) => { + let pos = pos.to_logical::(instance.scale_factor); + input_state.on_scroll(&mut instance.frame, vec2(pos.x, pos.y)) } - winit::event::MouseScrollDelta::PixelDelta(_) => todo!(), } } WindowEvent::ScaleFactorChanged { @@ -344,15 +348,8 @@ impl App { AppBuilder::new() } - #[allow(unused_mut)] - pub fn on_resize(&mut self, mut physical_size: PhysicalSize) { - #[cfg(target_arch = "wasm32")] - { - physical_size.width = physical_size.width.min(2048); - physical_size.height = physical_size.height.min(2048); - } + pub fn on_resize(&mut self, physical_size: PhysicalSize) { self.window_size = physical_size; - // self.scale_factor = 2.0; tracing::info!(?physical_size, self.scale_factor, "Resizing window"); diff --git a/violet-wgpu/src/systems.rs b/violet-wgpu/src/systems.rs index e85b62f..8fb2d46 100644 --- a/violet-wgpu/src/systems.rs +++ b/violet-wgpu/src/systems.rs @@ -27,8 +27,11 @@ use super::{ #[derive(Fetch)] #[fetch(transforms = [Modified])] struct TextBufferQuery { + #[fetch(ignore)] state: Mutable, + #[fetch(ignore)] layout_glyphs: Mutable, + layout_bounds: Component, text: Component>, rect: Component,