Apply cursor styles during paint
This makes the editor's cursor an IBeam and properly deals with nested cursor styles. Co-Authored-By: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
parent
53bf7b61c0
commit
92f040df00
16 changed files with 124 additions and 96 deletions
|
@ -1,17 +1,17 @@
|
|||
use pathfinder_geometry::rect::RectF;
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{
|
||||
color::Color,
|
||||
geometry::{
|
||||
deserialize_vec2f,
|
||||
rect::RectF,
|
||||
vector::{vec2f, Vector2F},
|
||||
},
|
||||
json::ToJson,
|
||||
platform::CursorStyle,
|
||||
scene::{self, Border, Quad},
|
||||
Element, ElementBox, Event, EventContext, LayoutContext, PaintContext, SizeConstraint,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Deserialize)]
|
||||
pub struct ContainerStyle {
|
||||
|
@ -27,6 +27,8 @@ pub struct ContainerStyle {
|
|||
pub corner_radius: f32,
|
||||
#[serde(default)]
|
||||
pub shadow: Option<Shadow>,
|
||||
#[serde(default)]
|
||||
pub cursor: Option<CursorStyle>,
|
||||
}
|
||||
|
||||
pub struct Container {
|
||||
|
@ -128,6 +130,11 @@ impl Container {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn with_cursor(mut self, style: CursorStyle) -> Self {
|
||||
self.style.cursor = Some(style);
|
||||
self
|
||||
}
|
||||
|
||||
fn margin_size(&self) -> Vector2F {
|
||||
vec2f(
|
||||
self.style.margin.left + self.style.margin.right,
|
||||
|
@ -205,6 +212,10 @@ impl Element for Container {
|
|||
});
|
||||
}
|
||||
|
||||
if let Some(style) = self.style.cursor {
|
||||
cx.scene.push_cursor_style(quad_bounds, style);
|
||||
}
|
||||
|
||||
let child_origin =
|
||||
quad_bounds.origin() + vec2f(self.style.padding.left, self.style.padding.top);
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@ use crate::{
|
|||
vector::{vec2f, Vector2F},
|
||||
},
|
||||
platform::CursorStyle,
|
||||
CursorStyleHandle, DebugContext, Element, ElementBox, ElementStateContext, ElementStateHandle,
|
||||
Event, EventContext, LayoutContext, PaintContext, SizeConstraint,
|
||||
DebugContext, Element, ElementBox, ElementStateContext, ElementStateHandle, Event,
|
||||
EventContext, LayoutContext, PaintContext, SizeConstraint,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
|
@ -25,7 +25,6 @@ pub struct MouseState {
|
|||
pub hovered: bool,
|
||||
pub clicked: bool,
|
||||
prev_drag_position: Option<Vector2F>,
|
||||
cursor_style_handle: Option<CursorStyleHandle>,
|
||||
}
|
||||
|
||||
impl MouseEventHandler {
|
||||
|
@ -72,6 +71,14 @@ impl MouseEventHandler {
|
|||
self.padding = padding;
|
||||
self
|
||||
}
|
||||
|
||||
fn hit_bounds(&self, bounds: RectF) -> RectF {
|
||||
RectF::from_points(
|
||||
bounds.origin() - vec2f(self.padding.left, self.padding.top),
|
||||
bounds.lower_right() + vec2f(self.padding.right, self.padding.bottom),
|
||||
)
|
||||
.round_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl Element for MouseEventHandler {
|
||||
|
@ -93,6 +100,10 @@ impl Element for MouseEventHandler {
|
|||
_: &mut Self::LayoutState,
|
||||
cx: &mut PaintContext,
|
||||
) -> Self::PaintState {
|
||||
if let Some(cursor_style) = self.cursor_style {
|
||||
cx.scene
|
||||
.push_cursor_style(self.hit_bounds(bounds), cursor_style);
|
||||
}
|
||||
self.child.paint(bounds.origin(), visible_bounds, cx);
|
||||
}
|
||||
|
||||
|
@ -105,19 +116,13 @@ impl Element for MouseEventHandler {
|
|||
_: &mut Self::PaintState,
|
||||
cx: &mut EventContext,
|
||||
) -> bool {
|
||||
let cursor_style = self.cursor_style;
|
||||
let hit_bounds = self.hit_bounds(visible_bounds);
|
||||
let mouse_down_handler = self.mouse_down_handler.as_mut();
|
||||
let click_handler = self.click_handler.as_mut();
|
||||
let drag_handler = self.drag_handler.as_mut();
|
||||
|
||||
let handled_in_child = self.child.dispatch_event(event, cx);
|
||||
|
||||
let hit_bounds = RectF::from_points(
|
||||
visible_bounds.origin() - vec2f(self.padding.left, self.padding.top),
|
||||
visible_bounds.lower_right() + vec2f(self.padding.right, self.padding.bottom),
|
||||
)
|
||||
.round_out();
|
||||
|
||||
self.state.update(cx, |state, cx| match event {
|
||||
Event::MouseMoved {
|
||||
position,
|
||||
|
@ -127,16 +132,6 @@ impl Element for MouseEventHandler {
|
|||
let mouse_in = hit_bounds.contains_point(*position);
|
||||
if state.hovered != mouse_in {
|
||||
state.hovered = mouse_in;
|
||||
if let Some(cursor_style) = cursor_style {
|
||||
if !state.clicked {
|
||||
if state.hovered {
|
||||
state.cursor_style_handle =
|
||||
Some(cx.set_cursor_style(cursor_style));
|
||||
} else {
|
||||
state.cursor_style_handle = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
cx.notify();
|
||||
return true;
|
||||
}
|
||||
|
@ -160,9 +155,6 @@ impl Element for MouseEventHandler {
|
|||
state.prev_drag_position = None;
|
||||
if !handled_in_child && state.clicked {
|
||||
state.clicked = false;
|
||||
if !state.hovered {
|
||||
state.cursor_style_handle = None;
|
||||
}
|
||||
cx.notify();
|
||||
if let Some(handler) = click_handler {
|
||||
if hit_bounds.contains_point(*position) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue