mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-07 02:57:34 +00:00
Introduce MouseEventHandler::on_drag
This commit is contained in:
parent
386631debf
commit
8a10234b14
1 changed files with 25 additions and 0 deletions
|
@ -9,12 +9,14 @@ pub struct MouseEventHandler {
|
||||||
state: ValueHandle<MouseState>,
|
state: ValueHandle<MouseState>,
|
||||||
child: ElementBox,
|
child: ElementBox,
|
||||||
click_handler: Option<Box<dyn FnMut(&mut EventContext)>>,
|
click_handler: Option<Box<dyn FnMut(&mut EventContext)>>,
|
||||||
|
drag_handler: Option<Box<dyn FnMut(Vector2F, &mut EventContext)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
pub struct MouseState {
|
pub struct MouseState {
|
||||||
pub hovered: bool,
|
pub hovered: bool,
|
||||||
pub clicked: bool,
|
pub clicked: bool,
|
||||||
|
prev_drag_position: Option<Vector2F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MouseEventHandler {
|
impl MouseEventHandler {
|
||||||
|
@ -30,6 +32,7 @@ impl MouseEventHandler {
|
||||||
state: state_handle,
|
state: state_handle,
|
||||||
child,
|
child,
|
||||||
click_handler: None,
|
click_handler: None,
|
||||||
|
drag_handler: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +40,11 @@ impl MouseEventHandler {
|
||||||
self.click_handler = Some(Box::new(handler));
|
self.click_handler = Some(Box::new(handler));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn on_drag(mut self, handler: impl FnMut(Vector2F, &mut EventContext) + 'static) -> Self {
|
||||||
|
self.drag_handler = Some(Box::new(handler));
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Element for MouseEventHandler {
|
impl Element for MouseEventHandler {
|
||||||
|
@ -69,6 +77,7 @@ impl Element for MouseEventHandler {
|
||||||
cx: &mut EventContext,
|
cx: &mut EventContext,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let click_handler = self.click_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 handled_in_child = self.child.dispatch_event(event, cx);
|
||||||
|
|
||||||
|
@ -86,6 +95,7 @@ impl Element for MouseEventHandler {
|
||||||
Event::LeftMouseDown { position, .. } => {
|
Event::LeftMouseDown { position, .. } => {
|
||||||
if !handled_in_child && bounds.contains_point(*position) {
|
if !handled_in_child && bounds.contains_point(*position) {
|
||||||
state.clicked = true;
|
state.clicked = true;
|
||||||
|
state.prev_drag_position = Some(*position);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
|
@ -93,6 +103,7 @@ impl Element for MouseEventHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::LeftMouseUp { position, .. } => {
|
Event::LeftMouseUp { position, .. } => {
|
||||||
|
state.prev_drag_position = None;
|
||||||
if !handled_in_child && state.clicked {
|
if !handled_in_child && state.clicked {
|
||||||
state.clicked = false;
|
state.clicked = false;
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
@ -106,6 +117,20 @@ impl Element for MouseEventHandler {
|
||||||
handled_in_child
|
handled_in_child
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Event::LeftMouseDragged { position, .. } => {
|
||||||
|
if !handled_in_child && state.clicked {
|
||||||
|
let prev_drag_position = state.prev_drag_position.replace(*position);
|
||||||
|
if let Some((handler, prev_position)) = drag_handler.zip(prev_drag_position) {
|
||||||
|
let delta = *position - prev_position;
|
||||||
|
if !delta.is_zero() {
|
||||||
|
(handler)(delta, cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
handled_in_child
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => handled_in_child,
|
_ => handled_in_child,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue