Introduce CursorRegion struct

This will blend in with an upcoming MouseRegion struct that sits next to it in the scene.

Co-Authored-By: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
Nathan Sobo 2022-05-26 11:00:10 -06:00
parent f4d13ef596
commit 0866f0ed55
6 changed files with 44 additions and 24 deletions

View file

@ -18,8 +18,9 @@ use gpui::{
json::{self, ToJson}, json::{self, ToJson},
platform::CursorStyle, platform::CursorStyle,
text_layout::{self, Line, RunStyle, TextLayoutCache}, text_layout::{self, Line, RunStyle, TextLayoutCache},
AppContext, Axis, Border, Element, ElementBox, Event, EventContext, LayoutContext, AppContext, Axis, Border, CursorRegion, Element, ElementBox, Event, EventContext,
MutableAppContext, PaintContext, Quad, Scene, SizeConstraint, ViewContext, WeakViewHandle, LayoutContext, MutableAppContext, PaintContext, Quad, Scene, SizeConstraint, ViewContext,
WeakViewHandle,
}; };
use json::json; use json::json;
use language::{Bias, DiagnosticSeverity}; use language::{Bias, DiagnosticSeverity};
@ -330,7 +331,10 @@ impl EditorElement {
let content_origin = bounds.origin() + vec2f(layout.gutter_margin, 0.); let content_origin = bounds.origin() + vec2f(layout.gutter_margin, 0.);
cx.scene.push_layer(Some(bounds)); cx.scene.push_layer(Some(bounds));
cx.scene.push_cursor_style(bounds, CursorStyle::IBeam); cx.scene.push_cursor_region(CursorRegion {
bounds,
style: CursorStyle::IBeam,
});
for (range, color) in &layout.highlighted_ranges { for (range, color) in &layout.highlighted_ranges {
self.paint_highlighted_range( self.paint_highlighted_range(

View file

@ -7,7 +7,7 @@ use crate::{
}, },
json::ToJson, json::ToJson,
platform::CursorStyle, platform::CursorStyle,
scene::{self, Border, Quad}, scene::{self, Border, CursorRegion, Quad},
Element, ElementBox, Event, EventContext, LayoutContext, PaintContext, SizeConstraint, Element, ElementBox, Event, EventContext, LayoutContext, PaintContext, SizeConstraint,
}; };
use serde::Deserialize; use serde::Deserialize;
@ -213,7 +213,10 @@ impl Element for Container {
} }
if let Some(style) = self.style.cursor { if let Some(style) = self.style.cursor {
cx.scene.push_cursor_style(quad_bounds, style); cx.scene.push_cursor_region(CursorRegion {
bounds: quad_bounds,
style,
});
} }
let child_origin = let child_origin =

View file

@ -5,6 +5,7 @@ use crate::{
vector::{vec2f, Vector2F}, vector::{vec2f, Vector2F},
}, },
platform::CursorStyle, platform::CursorStyle,
scene::CursorRegion,
DebugContext, Element, ElementBox, ElementStateContext, ElementStateHandle, Event, DebugContext, Element, ElementBox, ElementStateContext, ElementStateHandle, Event,
EventContext, LayoutContext, PaintContext, SizeConstraint, EventContext, LayoutContext, PaintContext, SizeConstraint,
}; };
@ -100,9 +101,11 @@ impl Element for MouseEventHandler {
_: &mut Self::LayoutState, _: &mut Self::LayoutState,
cx: &mut PaintContext, cx: &mut PaintContext,
) -> Self::PaintState { ) -> Self::PaintState {
if let Some(cursor_style) = self.cursor_style { if let Some(style) = self.cursor_style {
cx.scene cx.scene.push_cursor_region(CursorRegion {
.push_cursor_style(self.hit_bounds(bounds), cursor_style); bounds: self.hit_bounds(bounds),
style,
});
} }
self.child.paint(bounds.origin(), visible_bounds, cx); self.child.paint(bounds.origin(), visible_bounds, cx);
} }

View file

@ -16,7 +16,7 @@ pub mod fonts;
pub mod geometry; pub mod geometry;
mod presenter; mod presenter;
mod scene; mod scene;
pub use scene::{Border, Quad, Scene}; pub use scene::{Border, CursorRegion, Quad, Scene};
pub mod text_layout; pub mod text_layout;
pub use text_layout::TextLayoutCache; pub use text_layout::TextLayoutCache;
mod util; mod util;

View file

@ -5,6 +5,7 @@ use crate::{
geometry::rect::RectF, geometry::rect::RectF,
json::{self, ToJson}, json::{self, ToJson},
platform::{CursorStyle, Event}, platform::{CursorStyle, Event},
scene::CursorRegion,
text_layout::TextLayoutCache, text_layout::TextLayoutCache,
Action, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AssetCache, ElementBox, Action, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AssetCache, ElementBox,
ElementStateContext, Entity, FontSystem, ModelHandle, ReadModel, ReadView, Scene, ElementStateContext, Entity, FontSystem, ModelHandle, ReadModel, ReadView, Scene,
@ -22,7 +23,7 @@ pub struct Presenter {
window_id: usize, window_id: usize,
pub(crate) rendered_views: HashMap<usize, ElementBox>, pub(crate) rendered_views: HashMap<usize, ElementBox>,
parents: HashMap<usize, usize>, parents: HashMap<usize, usize>,
cursor_styles: Vec<(RectF, CursorStyle)>, cursor_regions: Vec<CursorRegion>,
font_cache: Arc<FontCache>, font_cache: Arc<FontCache>,
text_layout_cache: TextLayoutCache, text_layout_cache: TextLayoutCache,
asset_cache: Arc<AssetCache>, asset_cache: Arc<AssetCache>,
@ -43,7 +44,7 @@ impl Presenter {
window_id, window_id,
rendered_views: cx.render_views(window_id, titlebar_height), rendered_views: cx.render_views(window_id, titlebar_height),
parents: HashMap::new(), parents: HashMap::new(),
cursor_styles: Default::default(), cursor_regions: Default::default(),
font_cache, font_cache,
text_layout_cache, text_layout_cache,
asset_cache, asset_cache,
@ -120,7 +121,7 @@ impl Presenter {
RectF::new(Vector2F::zero(), window_size), RectF::new(Vector2F::zero(), window_size),
); );
self.text_layout_cache.finish_frame(); self.text_layout_cache.finish_frame();
self.cursor_styles = scene.cursor_styles(); self.cursor_regions = scene.cursor_regions();
if cx.window_is_active(self.window_id) { if cx.window_is_active(self.window_id) {
if let Some(event) = self.last_mouse_moved_event.clone() { if let Some(event) = self.last_mouse_moved_event.clone() {
@ -184,9 +185,9 @@ impl Presenter {
if !left_mouse_down { if !left_mouse_down {
let mut style_to_assign = CursorStyle::Arrow; let mut style_to_assign = CursorStyle::Arrow;
for (bounds, style) in self.cursor_styles.iter().rev() { for region in self.cursor_regions.iter().rev() {
if bounds.contains_point(position) { if region.bounds.contains_point(position) {
style_to_assign = *style; style_to_assign = region.style;
break; break;
} }
} }

View file

@ -33,7 +33,13 @@ pub struct Layer {
image_glyphs: Vec<ImageGlyph>, image_glyphs: Vec<ImageGlyph>,
icons: Vec<Icon>, icons: Vec<Icon>,
paths: Vec<Path>, paths: Vec<Path>,
cursor_styles: Vec<(RectF, CursorStyle)>, cursor_regions: Vec<CursorRegion>,
}
#[derive(Copy, Clone)]
pub struct CursorRegion {
pub bounds: RectF,
pub style: CursorStyle,
} }
#[derive(Default, Debug)] #[derive(Default, Debug)]
@ -175,9 +181,9 @@ impl Scene {
self.stacking_contexts.iter().flat_map(|s| &s.layers) self.stacking_contexts.iter().flat_map(|s| &s.layers)
} }
pub fn cursor_styles(&self) -> Vec<(RectF, CursorStyle)> { pub fn cursor_regions(&self) -> Vec<CursorRegion> {
self.layers() self.layers()
.flat_map(|layer| &layer.cursor_styles) .flat_map(|layer| &layer.cursor_regions)
.copied() .copied()
.collect() .collect()
} }
@ -206,8 +212,8 @@ impl Scene {
self.active_layer().push_quad(quad) self.active_layer().push_quad(quad)
} }
pub fn push_cursor_style(&mut self, bounds: RectF, style: CursorStyle) { pub fn push_cursor_region(&mut self, region: CursorRegion) {
self.active_layer().push_cursor_style(bounds, style); self.active_layer().push_cursor_region(region);
} }
pub fn push_image(&mut self, image: Image) { pub fn push_image(&mut self, image: Image) {
@ -298,7 +304,7 @@ impl Layer {
glyphs: Default::default(), glyphs: Default::default(),
icons: Default::default(), icons: Default::default(),
paths: Default::default(), paths: Default::default(),
cursor_styles: Default::default(), cursor_regions: Default::default(),
} }
} }
@ -316,10 +322,13 @@ impl Layer {
self.quads.as_slice() self.quads.as_slice()
} }
fn push_cursor_style(&mut self, bounds: RectF, style: CursorStyle) { fn push_cursor_region(&mut self, region: CursorRegion) {
if let Some(bounds) = bounds.intersection(self.clip_bounds.unwrap_or(bounds)) { if let Some(bounds) = region
.bounds
.intersection(self.clip_bounds.unwrap_or(region.bounds))
{
if can_draw(bounds) { if can_draw(bounds) {
self.cursor_styles.push((bounds, style)); self.cursor_regions.push(region);
} }
} }
} }