# Pointer and hardware key events
module input_events
-import mnit_input
-import android
+import mnit::input
+import android::game
in "C header" `{
#include <android/log.h>
}
`}
-extern class NativeAndroidMotionEvent `{AInputEvent *`}
+private extern class NativeAndroidMotionEvent `{AInputEvent *`}
- private fun pointers_count: Int `{
- return AMotionEvent_getPointerCount(recv);
+ fun pointers_count: Int `{
+ return AMotionEvent_getPointerCount(self);
`}
- private fun just_went_down: Bool `{
- return (AMotionEvent_getAction(recv) & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_DOWN;
+ fun edge: Int `{
+ return AMotionEvent_getEdgeFlags(self);
`}
- private fun edge: Int `{
- return AMotionEvent_getEdgeFlags(recv);
- `}
-
- private fun index_down_pointer: Int `{
- int a = AMotionEvent_getAction(recv);
+ # Get the non-primary pointer id that just went down (returns -1 or > 0)
+ fun index_down_pointer: Int `{
+ int a = AMotionEvent_getAction(self);
if ((a & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_POINTER_DOWN)
return (a & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
else return -1;
`}
- private fun action: AMotionEventAction `{ return AMotionEvent_getAction(recv); `}
+ fun action: AMotionEventAction `{ return AMotionEvent_getAction(self); `}
+
+ fun native_down_time: Int `{ return AMotionEvent_getDownTime(self); `}
end
-extern class AMotionEventAction `{ int32_t `}
- protected fun action: Int `{ return recv & AMOTION_EVENT_ACTION_MASK; `}
+private extern class AMotionEventAction `{ int32_t `}
+ fun action: Int `{ return self & AMOTION_EVENT_ACTION_MASK; `}
+
+ # Pointer index concerned by this action
+ #
+ # Require: `is_pointer_down or is_pointer_up`
+ fun pointer_index: Int `{
+ return (self & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+ `}
+
fun is_down: Bool do return action == 0
fun is_up: Bool do return action == 1
fun is_move: Bool do return action == 2
fun is_pointer_up: Bool do return action == 6
end
+# An input event on Android
interface AndroidInputEvent
super InputEvent
end
+# A motion event concerning a single or more `pointers`
class AndroidMotionEvent
super AndroidInputEvent
super MotionEvent
- private init(ie: NativeAndroidMotionEvent) do native = ie
private var native: NativeAndroidMotionEvent
- private var pointers_cache: nullable Array[AndroidPointerEvent] = null
- fun pointers: Array[AndroidPointerEvent]
- do
- if pointers_cache != null then
- return pointers_cache.as(not null)
- else
- var pointers = new Array[AndroidPointerEvent]
- var pointers_count = native.pointers_count
- for i in [0 .. pointers_count [do
- var pointer_event = new AndroidPointerEvent(self, i)
- pointers.add(pointer_event)
- end
- pointers_cache = pointers
- return pointers
+ # Pointers (or fingers) composing this motion event
+ var pointers: Array[AndroidPointerEvent] is lazy do
+ return [for i in native.pointers_count.times do new AndroidPointerEvent(self, i)]
+ end
+
+ # The pointer (or finger) causing this event
+ var acting_pointer: AndroidPointerEvent is lazy do
+ var action = native.action
+ var index = 0
+
+ if action.is_pointer_down or action.is_pointer_up then
+ index = native.action.pointer_index
end
+
+ return new AndroidPointerEvent(self, index)
end
- redef fun just_went_down: Bool do return native.just_went_down
- fun edge: Int do return native.edge
+ redef fun just_went_down do return native.action.is_down or native.action.is_pointer_down
+
+ # Was the top edge of the screen intersected by this event?
+ fun touch_to_edge: Bool do return native.edge == 1
+
+ # Was the bottom edge of the screen intersected by this event?
+ fun touch_bottom_edge: Bool do return native.edge == 2
+
+ # Was the left edge of the screen intersected by this event?
+ fun touch_left_edge: Bool do return native.edge == 4
+
+ # Was the right edge of the screen intersected by this event?
+ fun touch_right_edge: Bool do return native.edge == 8
redef fun down_pointer: nullable AndroidPointerEvent
do
+ if just_went_down then
+ # The primary pointer went down
+ return pointers[0]
+ end
+
var i = native.index_down_pointer
if i > 0 then
+ # A secondary pointer went down
return pointers[i]
else
return null
end
end
+
+ # Time when the user originally pressed down to start a stream of position events
+ #
+ # The return value is in the `java.lang.System.nanoTime()` time base.
+ fun down_time: Int do return native.native_down_time
end
+# A pointer event
class AndroidPointerEvent
super PointerEvent
super AndroidInputEvent
- protected var motion_event: AndroidMotionEvent
- protected var pointer_id: Int
+ private var motion_event: AndroidMotionEvent
- redef fun x: Float do return native_x(motion_event.native, pointer_id)
+ private var pointer_index: Int
- private fun native_x(motion_event: NativeAndroidMotionEvent, pointer_id: Int): Float `{
- return AMotionEvent_getX(motion_event, pointer_id);
+ redef fun x do return native_x(motion_event.native, pointer_index)
+
+ private fun native_x(motion_event: NativeAndroidMotionEvent, pointer_index: Int): Float `{
+ return AMotionEvent_getX(motion_event, pointer_index);
`}
- redef fun y: Float do return native_y(motion_event.native, pointer_id)
+ redef fun y do return native_y(motion_event.native, pointer_index)
- private fun native_y(motion_event: NativeAndroidMotionEvent, pointer_id: Int): Float `{
- return AMotionEvent_getY(motion_event, pointer_id);
+ private fun native_y(motion_event: NativeAndroidMotionEvent, pointer_index: Int): Float `{
+ return AMotionEvent_getY(motion_event, pointer_index);
`}
- fun pressure: Float do return native_pressure(motion_event.native, pointer_id)
+ # Pressure applied by this pointer
+ fun pressure: Float do return native_pressure(motion_event.native, pointer_index)
- private fun native_pressure(motion_event: NativeAndroidMotionEvent, pointer_id: Int): Float `{
- return AMotionEvent_getPressure(motion_event, pointer_id);
+ private fun native_pressure(motion_event: NativeAndroidMotionEvent, pointer_index: Int): Float `{
+ return AMotionEvent_getPressure(motion_event, pointer_index);
`}
redef fun pressed
do
var action = motion_event.native.action
- return action.is_down or action.is_move
+ return action.is_down or action.is_move or action.is_pointer_down
end
- redef fun depressed do return not pressed
+ redef fun is_move do return motion_event.acting_pointer == self and
+ motion_event.native.action.is_move
+
+ # Does this pointer just began touching the screen?
+ fun just_went_down: Bool do return motion_event.acting_pointer == self and
+ motion_event.just_went_down
+
+ # Unique id of this pointer since the beginning of the gesture
+ redef fun pointer_id do return native_pointer_id(motion_event.native, pointer_index)
+
+ private fun native_pointer_id(motion_event: NativeAndroidMotionEvent, pointer_index: Int): Int `{
+ return AMotionEvent_getPointerId(motion_event, pointer_index);
+ `}
end
+# An hardware key event
extern class AndroidKeyEvent `{AInputEvent *`}
super KeyEvent
super AndroidInputEvent
- fun action: Int `{
- return AKeyEvent_getAction(recv);
- `}
- redef fun is_down: Bool do return action == 0
- redef fun is_up: Bool do return action == 1
+ private fun action: Int `{ return AKeyEvent_getAction(self); `}
- fun key_code: Int `{ return AKeyEvent_getKeyCode(recv); `}
+ redef fun is_down do return action == 0
+ redef fun is_up do return action == 1
- redef fun to_c `{
- int code = AKeyEvent_getKeyCode(recv);
+ # Hardware code of the key raising this event
+ fun key_code: Int `{ return AKeyEvent_getKeyCode(self); `}
+
+ redef fun to_c
+ do
+ var i = native_to_c
+ if i == 0 then return null
+ return i.code_point
+ end
+
+ private fun native_to_c: Int `{
+ int code = AKeyEvent_getKeyCode(self);
if (code >= AKEYCODE_0 && code <= AKEYCODE_9)
return '0'+code-AKEYCODE_0;
if (code >= AKEYCODE_A && code <= AKEYCODE_Z)
return 0;
`}
+ redef fun name do return key_code.to_s
+
+ # Was this event raised by the back key?
fun is_back_key: Bool do return key_code == 4
+
+ # Was this event raised by the menu key?
fun is_menu_key: Bool do return key_code == 82
+
+ # Was this event raised by the search key?
fun is_search_key: Bool do return key_code == 84
+ # Was this event raised by the volume up key?
fun is_volume_up: Bool do return key_code == 24
+
+ # Was this event raised by the volume down key?
fun is_volume_down: Bool do return key_code == 25
end