Closed ogoffart closed 11 months ago
What needs to be done is decide on the API. Then the implementation should be quite easy by calling the relevant callback in the TouchArea item
@ogoffart , I've created naive implementation of events aggregator in my pet project.
In brief. (upd: I'm describing this to tell you my user case. ) Aggregation is stored in a structure with pressed keys, mouse position and accumulated events. Accumulated events are key/mouse clicks (up to tripple), wheel movement (vertical/hoizontal) accumulations, mouse movement. I assume only one mouse button and only one keyboard button can be clicked. (Might someone want to do multiple clicks with many keys?)
When aggregated state is read (Ex. pushed to events queue) all accumulated events are reset.
Since I "reinvented the wheel" this can be quite naive and have some flaws.
Ex. windows has it's own system functions to test mouse double clicks and current verion does all this bookkeeping. But those system events still can be stored in aggregated state.
You may have a look if you want to https://github.com/DaMilyutin/system_events/blob/main/include/system_events.h
upd: It is in playground state. So there are some debugs and logging.
@DaMilyutin Internally, we already represent the wheel event internally: The internal MouseEvent has a Wheel event https://github.com/slint-ui/slint/blob/e557ba5eedf289ad30d6c5587cfce1dc60fe997d/internal/core/input.rs#L46
What we don't do, is forward it to the .slint code. This should happens here:
https://github.com/slint-ui/slint/blob/e557ba5eedf289ad30d6c5587cfce1dc60fe997d/internal/core/items.rs#L575
For the other events, we forward to one of the TouchArea's callback (pointer-event
, moved
, clicked
, ...) but not for the Wheel.
We could add some entries in the Slint's pointer-event enum to indicate a wheel. Or we could create a new callback only for the wheel event.
@ogoffart, thank you for clarification. Inner representation looks like what I want to have. I wish I could have full controll of all inputs if needed. Or some shortcuts. Or maybe if I just could forward all state to my C++ code.
In my plans for plotting application I'm going to have following use case. I'd like to process both mouse events with modifiers pressed. For example ctrl links axes in x, alt in y, both in xy, etc.
Given that we would want to know the keyboard state, i'm thinking we should extend the PointerEvent structure.
https://github.com/slint-ui/slint/blob/master/docs/langref/src/builtin_structs.md#pointerevent
(pseudo-slint-code based on https://github.com/slint-ui/slint/blob/41157b9984bb205c4703dd43e05b7656c6662015/internal/compiler/builtins.slint#L87)
export struct PointerEvent {
button: PointerEventButton,
kind: PointerEventKind,
+ // When kind == wheel, this is the amount of logical pixel to scroll in the vertical or horizontal direction
+ delta-x: length,
+ delta-y: length,
+ // The modifiers currently pressed
+ modifiers: KeyboardModifiers
}
enum PointerEventKind {
cancel,
down,
up,
+ wheel,
}
Does that new API make sense?
Possible alternative:
delta: Point
wheel-delta-x
, -y
(or wheel-delta
)?@ogoffart,
+ delta-x: length,
+ delta-y: length,
Seems better to me. Because there is less cases for kind
.
Actually, you can even keep kind
without wheel
because nonzero delta-x
, delta-y
will signalize wheel movement.
For me wheel movement event can be seen in same fashion as mouse movement event.
I'm curiuos, is it possible to join events from keyboard and mouse in one callback?
Like ex. keypressed('V') and mousemove(dx, dy) => do something
I think extending a pointer event to support wheel events feels wrong to me. Those are rather different kinds of user actions IMO. I’d prefer a separate event / callback.
Regarding the modifiers: instead of adding this to every single event I’d prefer if API wise this was a global property. In practice it is, in practice there is only one keyboard active for an application.
I had a small chat with @simon and we decided on this API:
struct PointerScrollEvent { delta-x: length, delta-y: length, modifiers: KeyboardModifiers }
// in TouchArea
callback scroll-event(PointerScrollEvent) -> EventResult;
(I added the EventResult
return type because if we don't interpret it, we still want to let flickable scroll)
TouchArea should support wheel event.
Options:
add a new
callback wheel-event(Orientation, delta)
(what type should the delta be?)add things in the current pointer-event.
PointerEventKind.vertical-wheel
/horizontal-wheel
or should it be in PointerEventButton ?PointerEvent.wheel-delta
?