add offset / scrolling + clipboard support
This commit is contained in:
@@ -29,6 +29,7 @@ pub enum Sense {
|
||||
HoverStart,
|
||||
Hovering,
|
||||
HoverEnd,
|
||||
Scroll,
|
||||
}
|
||||
|
||||
pub struct Senses(Vec<Sense>);
|
||||
@@ -47,6 +48,7 @@ pub struct CursorState {
|
||||
pub pos: Vec2,
|
||||
pub exists: bool,
|
||||
pub buttons: CursorButtons,
|
||||
pub scroll_delta: Vec2,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
@@ -72,6 +74,13 @@ impl CursorButtons {
|
||||
}
|
||||
}
|
||||
|
||||
impl CursorState {
|
||||
pub fn end_frame(&mut self) {
|
||||
self.buttons.end_frame();
|
||||
self.scroll_delta = Vec2::ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq)]
|
||||
pub enum ActivationState {
|
||||
Start,
|
||||
@@ -81,29 +90,27 @@ pub enum ActivationState {
|
||||
Off,
|
||||
}
|
||||
|
||||
pub struct Sensor<Ctx> {
|
||||
pub struct Sensor<Ctx, Data> {
|
||||
pub senses: Senses,
|
||||
pub f: Rc<dyn SenseFn<Ctx>>,
|
||||
pub f: Rc<dyn EventFn<Ctx, Data>>,
|
||||
}
|
||||
|
||||
pub type SensorMap<Ctx> = HashMap<Id, SensorGroup<Ctx>>;
|
||||
pub type SensorMap<Ctx, Data> = HashMap<Id, SensorGroup<Ctx, Data>>;
|
||||
pub type SenseShape = UiRegion;
|
||||
pub struct SensorGroup<Ctx> {
|
||||
pub struct SensorGroup<Ctx, Data> {
|
||||
pub hover: ActivationState,
|
||||
pub sensors: Vec<Sensor<Ctx>>,
|
||||
pub sensors: Vec<Sensor<Ctx, Data>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SenseData {
|
||||
pub struct CursorData {
|
||||
pub cursor: Vec2,
|
||||
pub size: Vec2,
|
||||
pub scroll_delta: Vec2,
|
||||
}
|
||||
|
||||
pub trait SenseFn<Ctx>: Fn(&mut Ctx, SenseData) + 'static {}
|
||||
impl<F: Fn(&mut Ctx, SenseData) + 'static, Ctx> SenseFn<Ctx> for F {}
|
||||
|
||||
pub struct SensorModule<Ctx> {
|
||||
map: SensorMap<Ctx>,
|
||||
map: SensorMap<Ctx, CursorData>,
|
||||
active: HashMap<usize, HashMap<Id, SenseShape>>,
|
||||
}
|
||||
|
||||
@@ -125,6 +132,9 @@ impl<Ctx: 'static> UiModule for SensorModule<Ctx> {
|
||||
|
||||
fn on_remove(&mut self, id: &Id) {
|
||||
self.map.remove(id);
|
||||
for layer in self.active.values_mut() {
|
||||
layer.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
fn on_move(&mut self, inst: &WidgetInstance) {
|
||||
@@ -165,7 +175,7 @@ impl<Ctx: UiCtx + 'static> SensorModule<Ctx> {
|
||||
let Some(list) = module.active.get_mut(&i) else {
|
||||
continue;
|
||||
};
|
||||
let mut ran = false;
|
||||
let mut sensed = false;
|
||||
for (id, shape) in list.iter() {
|
||||
let group = module.map.get_mut(id).unwrap();
|
||||
let region = shape.to_screen(window_size);
|
||||
@@ -174,19 +184,20 @@ impl<Ctx: UiCtx + 'static> SensorModule<Ctx> {
|
||||
if group.hover == ActivationState::Off {
|
||||
continue;
|
||||
}
|
||||
sensed = true;
|
||||
|
||||
for sensor in &mut group.sensors {
|
||||
if should_run(&sensor.senses, &cursor.buttons, group.hover) {
|
||||
ran = true;
|
||||
let sctx = SenseData {
|
||||
if should_run(&sensor.senses, cursor, group.hover) {
|
||||
let data = CursorData {
|
||||
cursor: cursor.pos - region.top_left,
|
||||
size: region.bot_right - region.top_left,
|
||||
scroll_delta: cursor.scroll_delta,
|
||||
};
|
||||
(sensor.f)(ctx, sctx);
|
||||
(sensor.f)(ctx, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ran {
|
||||
if sensed {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -198,15 +209,16 @@ impl<Ctx: UiCtx + 'static> SensorModule<Ctx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn should_run(senses: &Senses, cursor: &CursorButtons, hover: ActivationState) -> bool {
|
||||
pub fn should_run(senses: &Senses, cursor: &CursorState, hover: ActivationState) -> bool {
|
||||
for sense in senses.iter() {
|
||||
if match sense {
|
||||
Sense::PressStart(button) => cursor.select(button).is_start(),
|
||||
Sense::Pressing(button) => cursor.select(button).is_on(),
|
||||
Sense::PressEnd(button) => cursor.select(button).is_end(),
|
||||
Sense::PressStart(button) => cursor.buttons.select(button).is_start(),
|
||||
Sense::Pressing(button) => cursor.buttons.select(button).is_on(),
|
||||
Sense::PressEnd(button) => cursor.buttons.select(button).is_end(),
|
||||
Sense::HoverStart => hover.is_start(),
|
||||
Sense::Hovering => hover.is_on(),
|
||||
Sense::HoverEnd => hover.is_end(),
|
||||
Sense::Scroll => cursor.scroll_delta != Vec2::ZERO,
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
@@ -259,12 +271,12 @@ impl ActivationState {
|
||||
|
||||
impl Event for Senses {
|
||||
type Module<Ctx: 'static> = SensorModule<Ctx>;
|
||||
type Data = SenseData;
|
||||
type Data = CursorData;
|
||||
}
|
||||
|
||||
impl Event for Sense {
|
||||
type Module<Ctx: 'static> = SensorModule<Ctx>;
|
||||
type Data = SenseData;
|
||||
type Data = CursorData;
|
||||
}
|
||||
|
||||
impl<E: Event<Data = <Senses as Event>::Data> + Into<Senses>, Ctx: 'static> EventModule<E, Ctx>
|
||||
@@ -292,7 +304,7 @@ impl<E: Event<Data = <Senses as Event>::Data> + Into<Senses>, Ctx: 'static> Even
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
Some(move |ctx: &mut Ctx, data: SenseData| {
|
||||
Some(move |ctx: &mut Ctx, data: CursorData| {
|
||||
for f in &fs {
|
||||
f(ctx, data.clone());
|
||||
}
|
||||
@@ -303,7 +315,7 @@ impl<E: Event<Data = <Senses as Event>::Data> + Into<Senses>, Ctx: 'static> Even
|
||||
}
|
||||
}
|
||||
|
||||
impl<Ctx> Default for SensorGroup<Ctx> {
|
||||
impl<Ctx, Data> Default for SensorGroup<Ctx, Data> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
hover: Default::default(),
|
||||
|
||||
Reference in New Issue
Block a user