From 7a8f2192516a28e4ffc0d89449270d09d3e404d8 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 8 Nov 2023 16:02:10 -0800 Subject: [PATCH] Account for element's bounds in Editor::bounds_for_range Co-authored-by: Marshall --- crates/editor2/src/editor.rs | 40 +++++++++++++++++++----- crates/gpui2/src/window.rs | 3 +- crates/gpui2/src/window_input_handler.rs | 2 +- test.rs | 24 +++++++------- 4 files changed, 46 insertions(+), 23 deletions(-) diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index 9542eaddc631f7132142e87bb7e1a8e704bdfc8e..9d7c0b7fa3130f99b6337bfd14fa30e209db5e34 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -39,10 +39,10 @@ use futures::FutureExt; use fuzzy::{StringMatch, StringMatchCandidate}; use git::diff_hunk_to_display; use gpui::{ - action, actions, div, px, relative, AnyElement, AppContext, BackgroundExecutor, ClipboardItem, - Context, DispatchContext, Div, Element, Entity, EventEmitter, FocusHandle, FontStyle, - FontWeight, HighlightStyle, Hsla, InputHandler, Model, Pixels, PlatformInputHandler, Render, - Styled, Subscription, Task, TextStyle, View, ViewContext, VisualContext, WeakView, + action, actions, div, point, px, relative, AnyElement, AppContext, BackgroundExecutor, Bounds, + ClipboardItem, Context, DispatchContext, Div, Element, Entity, EventEmitter, FocusHandle, + FontStyle, FontWeight, HighlightStyle, Hsla, InputHandler, Model, Pixels, PlatformInputHandler, + Render, Styled, Subscription, Task, TextStyle, View, ViewContext, VisualContext, WeakView, WindowContext, }; use highlight_matching_bracket::refresh_matching_bracket_highlights; @@ -9750,14 +9750,38 @@ impl InputHandler for Editor { } fn bounds_for_range( - &self, + &mut self, range_utf16: Range, element_bounds: gpui::Bounds, cx: &mut ViewContext, ) -> Option> { - // todo!() - // See how we did it before: `rect_for_range` - None + let text_layout_details = self.text_layout_details(cx); + let style = &text_layout_details.editor_style; + let font_id = cx.text_system().font_id(&style.text.font()).unwrap(); + let font_size = style.text.font_size.to_pixels(cx.rem_size()); + let line_height = style.text.line_height_in_pixels(cx.rem_size()); + let em_width = cx + .text_system() + .typographic_bounds(font_id, font_size, 'm') + .unwrap() + .size + .width; + + let snapshot = self.snapshot(cx); + let scroll_position = snapshot.scroll_position(); + let scroll_left = scroll_position.x * em_width; + + let start = OffsetUtf16(range_utf16.start).to_display_point(&snapshot); + let end = OffsetUtf16(range_utf16.end).to_display_point(&snapshot); + let start_y = line_height * (start.row() as f32 - scroll_position.y); + let end_y = line_height * (end.row() as f32 - scroll_position.y); + let start_x = snapshot.x_for_point(start, &text_layout_details) - scroll_left; + let end_x = snapshot.x_for_point(end, &text_layout_details) - scroll_left; + + Some(Bounds::from_corners( + element_bounds.origin + point(start_x, start_y), + element_bounds.origin + point(end_x, end_y), + )) } } diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index b1e756fe6f72dc86d772c616c3e723cbbd2c5572..9a1e8916c44267ecadfebbe64eed44f91da75a41 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -8,8 +8,7 @@ use crate::{ PlatformInputHandler, PlatformWindow, Point, PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, SubscriberSet, Subscription, TaffyLayoutEngine, Task, Underline, - UnderlineStyle, View, VisualContext, WeakView, WindowBounds, WindowInputHandler, WindowOptions, - SUBPIXEL_VARIANTS, + UnderlineStyle, View, VisualContext, WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS, }; use anyhow::{anyhow, Result}; use collections::HashMap; diff --git a/crates/gpui2/src/window_input_handler.rs b/crates/gpui2/src/window_input_handler.rs index 3ce9f01ddaabcc8c7c1e1de952ac88062937e012..d09a842a6bea35f772f23e22da11461db59e7b8f 100644 --- a/crates/gpui2/src/window_input_handler.rs +++ b/crates/gpui2/src/window_input_handler.rs @@ -159,7 +159,7 @@ pub trait InputHandler: Sized { cx: &mut ViewContext, ); fn bounds_for_range( - &self, + &mut self, range_utf16: std::ops::Range, element_bounds: crate::Bounds, cx: &mut ViewContext, diff --git a/test.rs b/test.rs index 4a7b9faa8ff9b56cc0779b79f5152b3b1694c2c7..36996263b0f053922598402b86f77382b687ea57 100644 --- a/test.rs +++ b/test.rs @@ -10,49 +10,49 @@ use element::Element; use frame::frame; use gpui::{ geometry::{rect::RectF, vector::vec2f}, - platform::WindowOptions, + platform::WindowOptions,aa }; -use log::LevelFilter; +use log::LevelFilter;a use simplelog::SimpleLogger; use themes::{rose_pine, ThemeColors}; -use view::view; +use view::view;a mod adapter { use crate::element::AnyElement; use crate::element::{LayoutContext, PaintContext}; - use gpui::{geometry::rect::RectF, LayoutEngine}; + use gpui::{geometry::rect::RectF, LayoutEngine};aaaa use util::ResultExt; pub struct Adapter(pub(crate) AnyElement); - impl gpui::Element for Adapter { - type LayoutState = Option; + impl gpui::Element for Adapter {aa + type LayoutState = Option; type PaintState = (); fn layout( &mut self, constraint: gpui::SizeConstraint, view: &mut V, - cx: &mut LayoutContext, + cx: &mut LayoutContext,aa ) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) { cx.push_layout_engine(LayoutEngine::new()); - let node = self.0.layout(view, cx).log_err(); + let node = self.0.layout(view, cx).log_err();a if let Some(node) = node { let layout_engine = cx.layout_engine().unwrap(); layout_engine.compute_layout(node, constraint.max).log_err(); } let layout_engine = cx.pop_layout_engine(); - if true { + if true {a if !layout_engine.is_some() { ::core::panicking::panic("assertion failed: layout_engine.is_some()") } } - (constraint.max, layout_engine) + (constraint.max, layout_engine)a } - fn paint( + fn paint(a &mut self, scene: &mut gpui::SceneBuilder, bounds: RectF, visible_bounds: RectF, layout_engine: &mut Option, view: &mut V, - legacy_cx: &mut gpui::PaintContext, + legacy_cx: &mut gpui::PaintContext,aaa ) -> Self::PaintState { legacy_cx.push_layout_engine(layout_engine.take().unwrap()); let mut cx = PaintContext::new(legacy_cx, scene);