#[allow(unused)] use super::{Event, EventState}; use super::{EventCx, GrabMode, IsUsed, MouseGrab, Pending, TouchGrab};
use crate::event::{CursorIcon, MouseButton, Used};
use crate::geom::{Coord, Offset};
use crate::{Action, WidgetId};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum PressSource {
Mouse(MouseButton, u32),
Touch(u64),
}
impl PressSource {
#[inline]
pub fn is_primary(self) -> bool {
match self {
PressSource::Mouse(button, _) => button == MouseButton::Left,
PressSource::Touch(_) => true,
}
}
#[inline]
pub fn is_secondary(self) -> bool {
matches!(self, PressSource::Mouse(MouseButton::Right, _))
}
#[inline]
pub fn is_tertiary(self) -> bool {
matches!(self, PressSource::Mouse(MouseButton::Middle, _))
}
#[inline]
pub fn is_touch(self) -> bool {
matches!(self, PressSource::Touch(_))
}
#[inline]
pub fn repetitions(self) -> u32 {
match self {
PressSource::Mouse(_, repetitions) => repetitions,
PressSource::Touch(_) => 1,
}
}
}
#[crate::autoimpl(Deref using self.source)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Press {
pub source: PressSource,
pub id: Option<WidgetId>,
pub coord: Coord,
}
impl Press {
#[inline]
pub fn grab(&self, id: WidgetId) -> GrabBuilder {
GrabBuilder {
id,
source: self.source,
coord: self.coord,
mode: GrabMode::Grab,
cursor: None,
}
}
}
#[must_use]
pub struct GrabBuilder {
id: WidgetId,
source: PressSource,
coord: Coord,
mode: GrabMode,
cursor: Option<CursorIcon>,
}
impl GrabBuilder {
#[inline]
pub fn with_mode(mut self, mode: GrabMode) -> Self {
self.mode = mode;
self
}
#[inline]
pub fn with_icon(self, icon: CursorIcon) -> Self {
self.with_opt_icon(Some(icon))
}
#[inline]
pub fn with_opt_icon(mut self, icon: Option<CursorIcon>) -> Self {
self.cursor = icon;
self
}
pub fn with_cx(self, cx: &mut EventCx) -> IsUsed {
let GrabBuilder {
id,
source,
coord,
mode,
cursor,
} = self;
log::trace!(target: "kas_core::event", "grab_press: start_id={id}, source={source:?}");
let mut pan_grab = (u16::MAX, 0);
match source {
PressSource::Mouse(button, repetitions) => {
if let Some((id, event)) = cx.remove_mouse_grab(false) {
cx.pending.push_back(Pending::Send(id, event));
}
if mode.is_pan() {
pan_grab = cx.set_pan_on(id.clone(), mode, false, coord);
}
cx.mouse_grab = Some(MouseGrab {
button,
repetitions,
start_id: id.clone(),
cur_id: Some(id.clone()),
depress: Some(id),
mode,
pan_grab,
coord,
delta: Offset::ZERO,
});
if let Some(icon) = cursor {
cx.shell.set_cursor_icon(icon);
}
}
PressSource::Touch(touch_id) => {
if cx.remove_touch(touch_id).is_some() {
#[cfg(debug_assertions)]
log::error!(target: "kas_core::event", "grab_press: touch_id conflict!");
}
if mode.is_pan() {
pan_grab = cx.set_pan_on(id.clone(), mode, true, coord);
}
cx.touch_grab.push(TouchGrab {
id: touch_id,
start_id: id.clone(),
depress: Some(id.clone()),
cur_id: Some(id),
last_move: coord,
coord,
mode,
pan_grab,
});
}
}
cx.send_action(Action::REDRAW);
Used
}
}