2021-09-07 17:36:50 +03:00
|
|
|
|
package rui
|
|
|
|
|
|
2024-09-12 14:05:11 +03:00
|
|
|
|
// Constants for [View] specific pointer events properties
|
2021-09-07 17:36:50 +03:00
|
|
|
|
const (
|
|
|
|
|
// PointerDown is the constant for "pointer-down" property tag.
|
2024-09-18 13:50:06 +03:00
|
|
|
|
//
|
|
|
|
|
// Used by `View`.
|
2024-11-13 12:56:39 +03:00
|
|
|
|
// Fired when a pointer becomes active. For mouse, it is fired when the device transitions from no buttons depressed to at
|
|
|
|
|
// least one button depressed. For touch, it is fired when physical contact is made with the digitizer. For pen, it is
|
2024-09-18 13:50:06 +03:00
|
|
|
|
// fired when the stylus makes physical contact with the digitizer.
|
|
|
|
|
//
|
|
|
|
|
// General listener format:
|
|
|
|
|
// `func(view rui.View, event rui.PointerEvent)`.
|
|
|
|
|
//
|
|
|
|
|
// where:
|
|
|
|
|
// view - Interface of a view which generated this event,
|
|
|
|
|
// event - Pointer event.
|
|
|
|
|
//
|
|
|
|
|
// Allowed listener formats:
|
|
|
|
|
// `func(event rui.PointerEvent)`,
|
|
|
|
|
// `func(view rui.View)`,
|
|
|
|
|
// `func()`.
|
2024-11-13 12:56:39 +03:00
|
|
|
|
PointerDown PropertyName = "pointer-down"
|
2021-09-07 17:36:50 +03:00
|
|
|
|
|
|
|
|
|
// PointerUp is the constant for "pointer-up" property tag.
|
2024-09-18 13:50:06 +03:00
|
|
|
|
//
|
|
|
|
|
// Used by `View`.
|
|
|
|
|
// Is fired when a pointer is no longer active.
|
|
|
|
|
//
|
|
|
|
|
// General listener format:
|
|
|
|
|
// `func(view rui.View, event rui.PointerEvent)`.
|
|
|
|
|
//
|
|
|
|
|
// where:
|
|
|
|
|
// view - Interface of a view which generated this event,
|
|
|
|
|
// event - Pointer event.
|
|
|
|
|
//
|
|
|
|
|
// Allowed listener formats:
|
|
|
|
|
// `func(event rui.PointerEvent)`,
|
|
|
|
|
// `func(view rui.View)`,
|
|
|
|
|
// `func()`.
|
2024-11-13 12:56:39 +03:00
|
|
|
|
PointerUp PropertyName = "pointer-up"
|
2021-09-07 17:36:50 +03:00
|
|
|
|
|
|
|
|
|
// PointerMove is the constant for "pointer-move" property tag.
|
2024-09-18 13:50:06 +03:00
|
|
|
|
//
|
|
|
|
|
// Used by `View`.
|
|
|
|
|
// Is fired when a pointer changes coordinates.
|
|
|
|
|
//
|
|
|
|
|
// General listener format:
|
|
|
|
|
// `func(view rui.View, event rui.PointerEvent)`.
|
|
|
|
|
//
|
|
|
|
|
// where:
|
|
|
|
|
// view - Interface of a view which generated this event,
|
|
|
|
|
// event - Pointer event.
|
|
|
|
|
//
|
|
|
|
|
// Allowed listener formats:
|
|
|
|
|
// `func(event rui.PointerEvent)`,
|
|
|
|
|
// `func(view rui.View)`,
|
|
|
|
|
// `func()`.
|
2024-11-13 12:56:39 +03:00
|
|
|
|
PointerMove PropertyName = "pointer-move"
|
2021-09-07 17:36:50 +03:00
|
|
|
|
|
|
|
|
|
// PointerCancel is the constant for "pointer-cancel" property tag.
|
2024-09-18 13:50:06 +03:00
|
|
|
|
//
|
|
|
|
|
// Used by `View`.
|
|
|
|
|
// Is fired if the pointer will no longer be able to generate events (for example the related device is deactivated).
|
|
|
|
|
//
|
|
|
|
|
// General listener format:
|
|
|
|
|
// `func(view rui.View, event rui.PointerEvent)`.
|
|
|
|
|
//
|
|
|
|
|
// where:
|
|
|
|
|
// view - Interface of a view which generated this event,
|
|
|
|
|
// event - Pointer event.
|
|
|
|
|
//
|
|
|
|
|
// Allowed listener formats:
|
|
|
|
|
// `func(event rui.PointerEvent)`,
|
|
|
|
|
// `func(view rui.View)`,
|
|
|
|
|
// `func()`.
|
2024-11-13 12:56:39 +03:00
|
|
|
|
PointerCancel PropertyName = "pointer-cancel"
|
2021-09-07 17:36:50 +03:00
|
|
|
|
|
|
|
|
|
// PointerOut is the constant for "pointer-out" property tag.
|
2024-09-18 13:50:06 +03:00
|
|
|
|
//
|
|
|
|
|
// Used by `View`.
|
2024-11-13 12:56:39 +03:00
|
|
|
|
// Is fired for several reasons including: pointing device is moved out of the hit test boundaries of an element; firing
|
|
|
|
|
// the "pointer-up" event for a device that does not support hover (see "pointer-up"); after firing the "pointer-cancel"
|
2024-09-18 13:50:06 +03:00
|
|
|
|
// event (see "pointer-cancel"); when a pen stylus leaves the hover range detectable by the digitizer.
|
|
|
|
|
//
|
|
|
|
|
// General listener format:
|
|
|
|
|
// `func(view rui.View, event rui.PointerEvent)`.
|
|
|
|
|
//
|
|
|
|
|
// where:
|
|
|
|
|
// view - Interface of a view which generated this event,
|
|
|
|
|
// event - Pointer event.
|
|
|
|
|
//
|
|
|
|
|
// Allowed listener formats:
|
|
|
|
|
// `func(event rui.PointerEvent)`,
|
|
|
|
|
// `func(view rui.View)`,
|
|
|
|
|
// `func()`.
|
2024-11-13 12:56:39 +03:00
|
|
|
|
PointerOut PropertyName = "pointer-out"
|
2021-09-07 17:36:50 +03:00
|
|
|
|
|
|
|
|
|
// PointerOver is the constant for "pointer-over" property tag.
|
2024-09-18 13:50:06 +03:00
|
|
|
|
//
|
|
|
|
|
// Used by `View`.
|
|
|
|
|
// Is fired when a pointing device is moved into an view's hit test boundaries.
|
|
|
|
|
//
|
|
|
|
|
// General listener format:
|
|
|
|
|
// `func(view rui.View, event rui.PointerEvent)`.
|
|
|
|
|
//
|
|
|
|
|
// where:
|
|
|
|
|
// view - Interface of a view which generated this event,
|
|
|
|
|
// event - Pointer event.
|
|
|
|
|
//
|
|
|
|
|
// Allowed listener formats:
|
|
|
|
|
// `func(event rui.PointerEvent)`,
|
|
|
|
|
// `func(view rui.View)`,
|
|
|
|
|
// `func()`.
|
2024-11-13 12:56:39 +03:00
|
|
|
|
PointerOver PropertyName = "pointer-over"
|
2021-09-07 17:36:50 +03:00
|
|
|
|
)
|
|
|
|
|
|
2024-09-12 14:05:11 +03:00
|
|
|
|
// PointerEvent represent a stylus events. Also inherit [MouseEvent] attributes
|
2021-09-07 17:36:50 +03:00
|
|
|
|
type PointerEvent struct {
|
|
|
|
|
MouseEvent
|
|
|
|
|
|
|
|
|
|
// PointerID is a unique identifier for the pointer causing the event.
|
|
|
|
|
PointerID int
|
|
|
|
|
|
|
|
|
|
// Width is the width (magnitude on the X axis), in pixels, of the contact geometry of the pointer.
|
|
|
|
|
Width float64
|
|
|
|
|
// Height is the height (magnitude on the Y axis), in pixels, of the contact geometry of the pointer.
|
|
|
|
|
Height float64
|
|
|
|
|
|
|
|
|
|
// Pressure is the normalized pressure of the pointer input in the range 0 to 1, where 0 and 1 represent
|
|
|
|
|
// the minimum and maximum pressure the hardware is capable of detecting, respectively.
|
|
|
|
|
Pressure float64
|
|
|
|
|
|
|
|
|
|
// TangentialPressure is the normalized tangential pressure of the pointer input (also known
|
|
|
|
|
// as barrel pressure or cylinder stress) in the range -1 to 1, where 0 is the neutral position of the control.
|
|
|
|
|
TangentialPressure float64
|
|
|
|
|
|
|
|
|
|
// TiltX is the plane angle (in degrees, in the range of -90 to 90) between the Y–Z plane
|
|
|
|
|
// and the plane containing both the pointer (e.g. pen stylus) axis and the Y axis.
|
|
|
|
|
TiltX float64
|
|
|
|
|
|
|
|
|
|
// TiltY is the plane angle (in degrees, in the range of -90 to 90) between the X–Z plane
|
|
|
|
|
// and the plane containing both the pointer (e.g. pen stylus) axis and the X axis.
|
|
|
|
|
TiltY float64
|
|
|
|
|
|
|
|
|
|
// Twist is the clockwise rotation of the pointer (e.g. pen stylus) around its major axis in degrees,
|
|
|
|
|
// with a value in the range 0 to 359.
|
|
|
|
|
Twist float64
|
|
|
|
|
|
|
|
|
|
// PointerType indicates the device type that caused the event ("mouse", "pen", "touch", etc.)
|
|
|
|
|
PointerType string
|
|
|
|
|
|
|
|
|
|
// IsPrimary indicates if the pointer represents the primary pointer of this pointer type.
|
|
|
|
|
IsPrimary bool
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-13 12:56:39 +03:00
|
|
|
|
/*
|
|
|
|
|
func setPointerListener(properties Properties, tag PropertyName, value any) bool {
|
2024-11-18 17:20:25 +03:00
|
|
|
|
if listeners, ok := valueToOneArgEventListeners[View, PointerEvent](value); ok {
|
2024-11-13 12:56:39 +03:00
|
|
|
|
if len(listeners) == 0 {
|
|
|
|
|
properties.setRaw(tag, nil)
|
|
|
|
|
} else {
|
|
|
|
|
properties.setRaw(tag, listeners)
|
2021-09-07 17:36:50 +03:00
|
|
|
|
}
|
2024-11-13 12:56:39 +03:00
|
|
|
|
return true
|
2021-09-07 17:36:50 +03:00
|
|
|
|
}
|
2024-11-13 12:56:39 +03:00
|
|
|
|
notCompatibleType(tag, value)
|
|
|
|
|
return false
|
2021-09-07 17:36:50 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-13 12:56:39 +03:00
|
|
|
|
func (view *viewData) removePointerListener(tag PropertyName) {
|
2021-09-07 17:36:50 +03:00
|
|
|
|
delete(view.properties, tag)
|
|
|
|
|
if view.created {
|
2024-11-13 12:56:39 +03:00
|
|
|
|
if js, ok := eventJsFunc[tag]; ok {
|
2022-10-30 17:22:33 +03:00
|
|
|
|
view.session.removeProperty(view.htmlID(), js.jsEvent)
|
2021-09-07 17:36:50 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func pointerEventsHtml(view View, buffer *strings.Builder) {
|
2024-11-13 12:56:39 +03:00
|
|
|
|
for _, tag := range []PropertyName{PointerDown, PointerUp, PointerMove, PointerOut, PointerOver, PointerCancel} {
|
2021-09-07 17:36:50 +03:00
|
|
|
|
if value := view.getRaw(tag); value != nil {
|
2024-11-13 12:56:39 +03:00
|
|
|
|
if js, ok := eventJsFunc[tag]; ok {
|
|
|
|
|
if listeners, ok := value.([]func(View, PointerEvent)); ok && len(listeners) > 0 {
|
|
|
|
|
buffer.WriteString(js.jsEvent)
|
|
|
|
|
buffer.WriteString(`="`)
|
|
|
|
|
buffer.WriteString(js.jsFunc)
|
|
|
|
|
buffer.WriteString(`(this, event)" `)
|
|
|
|
|
}
|
2021-09-07 17:36:50 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-11-13 12:56:39 +03:00
|
|
|
|
*/
|
2021-09-07 17:36:50 +03:00
|
|
|
|
|
|
|
|
|
func (event *PointerEvent) init(data DataObject) {
|
|
|
|
|
event.MouseEvent.init(data)
|
|
|
|
|
|
2021-11-04 14:59:25 +03:00
|
|
|
|
event.PointerID, _ = dataIntProperty(data, "pointerId")
|
2021-09-07 17:36:50 +03:00
|
|
|
|
event.Width = dataFloatProperty(data, "width")
|
|
|
|
|
event.Height = dataFloatProperty(data, "height")
|
|
|
|
|
event.Pressure = dataFloatProperty(data, "pressure")
|
|
|
|
|
event.TangentialPressure = dataFloatProperty(data, "tangentialPressure")
|
|
|
|
|
event.TiltX = dataFloatProperty(data, "tiltX")
|
|
|
|
|
event.TiltY = dataFloatProperty(data, "tiltY")
|
|
|
|
|
event.Twist = dataFloatProperty(data, "twist")
|
|
|
|
|
value, _ := data.PropertyValue("pointerType")
|
|
|
|
|
event.PointerType = value
|
|
|
|
|
event.IsPrimary = dataBoolProperty(data, "isPrimary")
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-13 12:56:39 +03:00
|
|
|
|
func handlePointerEvents(view View, tag PropertyName, data DataObject) {
|
2024-11-18 17:20:25 +03:00
|
|
|
|
listeners := getOneArgEventListeners[View, PointerEvent](view, nil, tag)
|
2021-09-07 17:36:50 +03:00
|
|
|
|
if len(listeners) == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var event PointerEvent
|
|
|
|
|
event.init(data)
|
|
|
|
|
|
|
|
|
|
for _, listener := range listeners {
|
|
|
|
|
listener(view, event)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetPointerDownListeners returns the "pointer-down" listener list. If there are no listeners then the empty list is returned.
|
2022-08-31 22:17:46 +03:00
|
|
|
|
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
|
|
|
|
|
func GetPointerDownListeners(view View, subviewID ...string) []func(View, PointerEvent) {
|
2024-11-18 17:20:25 +03:00
|
|
|
|
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerDown)
|
2021-09-07 17:36:50 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetPointerUpListeners returns the "pointer-up" listener list. If there are no listeners then the empty list is returned.
|
2022-08-31 22:17:46 +03:00
|
|
|
|
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
|
|
|
|
|
func GetPointerUpListeners(view View, subviewID ...string) []func(View, PointerEvent) {
|
2024-11-18 17:20:25 +03:00
|
|
|
|
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerUp)
|
2021-09-07 17:36:50 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetPointerMoveListeners returns the "pointer-move" listener list. If there are no listeners then the empty list is returned.
|
2022-08-31 22:17:46 +03:00
|
|
|
|
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
|
|
|
|
|
func GetPointerMoveListeners(view View, subviewID ...string) []func(View, PointerEvent) {
|
2024-11-18 17:20:25 +03:00
|
|
|
|
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerMove)
|
2021-09-07 17:36:50 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetPointerCancelListeners returns the "pointer-cancel" listener list. If there are no listeners then the empty list is returned.
|
2022-08-31 22:17:46 +03:00
|
|
|
|
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
|
|
|
|
|
func GetPointerCancelListeners(view View, subviewID ...string) []func(View, PointerEvent) {
|
2024-11-18 17:20:25 +03:00
|
|
|
|
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerCancel)
|
2021-09-07 17:36:50 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetPointerOverListeners returns the "pointer-over" listener list. If there are no listeners then the empty list is returned.
|
2022-08-31 22:17:46 +03:00
|
|
|
|
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
|
|
|
|
|
func GetPointerOverListeners(view View, subviewID ...string) []func(View, PointerEvent) {
|
2024-11-18 17:20:25 +03:00
|
|
|
|
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerOver)
|
2021-09-07 17:36:50 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetPointerOutListeners returns the "pointer-out" listener list. If there are no listeners then the empty list is returned.
|
2022-08-31 22:17:46 +03:00
|
|
|
|
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
|
|
|
|
|
func GetPointerOutListeners(view View, subviewID ...string) []func(View, PointerEvent) {
|
2024-11-18 17:20:25 +03:00
|
|
|
|
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerOut)
|
2021-09-07 17:36:50 +03:00
|
|
|
|
}
|