mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-02 14:51:15 +00:00
161 lines
5.1 KiB
Rust
161 lines
5.1 KiB
Rust
/* LICENSE BEGIN
|
|
This file is part of the SixtyFPS Project -- https://sixtyfps.io
|
|
Copyright (c) 2020 Olivier Goffart <olivier.goffart@sixtyfps.io>
|
|
Copyright (c) 2020 Simon Hausmann <simon.hausmann@sixtyfps.io>
|
|
|
|
SPDX-License-Identifier: GPL-3.0-only
|
|
This file is also available under commercial licensing terms.
|
|
Please contact info@sixtyfps.io for more information.
|
|
LICENSE END */
|
|
/*! Module handling mouse events
|
|
|
|
TODO: Keyboard events
|
|
*/
|
|
|
|
use crate::component::ComponentRefPin;
|
|
use crate::graphics::Point;
|
|
use crate::item_tree::{ItemVisitorResult, VisitChildrenResult};
|
|
use euclid::default::Vector2D;
|
|
|
|
/// The type of a MouseEvent
|
|
#[repr(C)]
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub enum MouseEventType {
|
|
/// The mouse was pressed
|
|
MousePressed,
|
|
/// The mouse was relased
|
|
MouseReleased,
|
|
/// The mouse position has changed
|
|
MouseMoved,
|
|
/// The mouse exited the item or component
|
|
MouseExit,
|
|
}
|
|
|
|
/// Structur representing a mouse event
|
|
#[repr(C)]
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub struct MouseEvent {
|
|
/// The position of the cursor
|
|
pub pos: Point,
|
|
/// The action performed (pressed/released/moced)
|
|
pub what: MouseEventType,
|
|
}
|
|
|
|
/// This value is returned by the input handler of a component
|
|
/// to notify the run-time about how the event was handled and
|
|
/// what the next steps are.
|
|
#[repr(C)]
|
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
|
pub enum InputEventResult {
|
|
/// The event was accepted. This may result in additional events, for example
|
|
/// accepting a mouse move will result in a MouseExit event later.
|
|
EventAccepted,
|
|
EventIgnored,
|
|
/* /// Same as grab, but continue forwarding the event to children.
|
|
/// If a child grab the mouse, the grabber will be stored in the item itself.
|
|
/// Only item that have grabbed storage can return this.
|
|
/// The new_grabber is a reference to a usize to store thenext grabber
|
|
TentativeGrab {
|
|
new_grabber: &'a Cell<usize>,
|
|
},
|
|
/// While we have a TentaztiveGrab
|
|
Forward {
|
|
to: usize,
|
|
},*/
|
|
/// All further mouse event need to be sent to this item or component
|
|
GrabMouse,
|
|
}
|
|
|
|
pub fn process_ungrabbed_mouse_event(
|
|
component: ComponentRefPin,
|
|
event: MouseEvent,
|
|
) -> (InputEventResult, VisitChildrenResult) {
|
|
let offset = Vector2D::new(0., 0.);
|
|
|
|
let mut result = InputEventResult::EventIgnored;
|
|
let item_index = crate::item_tree::visit_items(
|
|
component,
|
|
crate::item_tree::TraversalOrder::FrontToBack,
|
|
|_, item, offset| -> ItemVisitorResult<Vector2D<f32>> {
|
|
let geom = item.as_ref().geometry();
|
|
let geom = geom.translate(*offset);
|
|
|
|
if geom.contains(event.pos) {
|
|
let mut event2 = event.clone();
|
|
event2.pos -= geom.origin.to_vector();
|
|
match item.as_ref().input_event(event2) {
|
|
InputEventResult::EventAccepted => {
|
|
result = InputEventResult::EventAccepted;
|
|
return ItemVisitorResult::Abort;
|
|
}
|
|
InputEventResult::EventIgnored => (),
|
|
InputEventResult::GrabMouse => {
|
|
result = InputEventResult::GrabMouse;
|
|
return ItemVisitorResult::Abort;
|
|
}
|
|
};
|
|
}
|
|
|
|
ItemVisitorResult::Continue(geom.origin.to_vector())
|
|
},
|
|
offset,
|
|
);
|
|
|
|
(
|
|
result,
|
|
if result == InputEventResult::GrabMouse {
|
|
item_index
|
|
} else {
|
|
VisitChildrenResult::CONTINUE
|
|
},
|
|
)
|
|
}
|
|
/*
|
|
/// The event must be in the component coordinate
|
|
/// Returns the new grabber.
|
|
pub fn process_grabbed_mouse_event(
|
|
component: ComponentRefPin,
|
|
item: core::pin::Pin<ItemRef>,
|
|
offset: Point,
|
|
event: MouseEvent,
|
|
old_grab: VisitChildrenResult,
|
|
) -> (InputEventResult, VisitChildrenResult) {
|
|
let mut event2 = event.clone();
|
|
event2.pos -= offset.to_vector();
|
|
|
|
let res = item.as_ref().input_event(event2);
|
|
match res {
|
|
InputEventResult::EventIgnored => {
|
|
// We need then to forward to another event
|
|
process_ungrabbed_mouse_event(component, event)
|
|
}
|
|
InputEventResult::GrabMouse => (res, old_grab),
|
|
InputEventResult::EventAccepted => (res, VisitChildrenResult::CONTINUE),
|
|
}
|
|
}*/
|
|
|
|
pub(crate) mod ffi {
|
|
use super::*;
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn sixtyfps_process_ungrabbed_mouse_event(
|
|
component: core::pin::Pin<crate::component::ComponentRef>,
|
|
event: MouseEvent,
|
|
new_mouse_grabber: &mut crate::item_tree::VisitChildrenResult,
|
|
) -> InputEventResult {
|
|
let (res, grab) = process_ungrabbed_mouse_event(component, event);
|
|
*new_mouse_grabber = grab;
|
|
res
|
|
}
|
|
/*
|
|
#[no_mangle]
|
|
pub extern "C" fn sixtyfps_process_grabbed_mouse_event(
|
|
component: ComponentRefPin,
|
|
item: core::pin::Pin<ItemRef>,
|
|
offset: Point,
|
|
event: MouseEvent,
|
|
old_grab: VisitChildrenResult,
|
|
) -> (InputEventResult, crate::item_tree::VisitChildrenResult) {
|
|
process_grabbed_mouse_event(component, item, offset, event, old_grab)
|
|
}*/
|
|
}
|