705 lines
20 KiB
Haxe
705 lines
20 KiB
Haxe
package lime;
|
|
|
|
import lime.Lime;
|
|
import lime.RenderHandler;
|
|
import lime.helpers.Keys;
|
|
import lime.helpers.InputHelper;
|
|
|
|
class InputHandler {
|
|
|
|
public var lib : Lime;
|
|
|
|
//the active touches at any point
|
|
public var touches_active : Map<Int, Dynamic>;
|
|
|
|
//this is a code/scan specific key repeat map
|
|
public var keys_down : Map<Int, Bool>;
|
|
//this is the enum based flags for keypressed/keyreleased/keydown
|
|
public var key_value_down : Map<KeyValue, Bool>;
|
|
public var key_value_pressed : Map<KeyValue, Bool>;
|
|
public var key_value_released : Map<KeyValue, Bool>;
|
|
//previous move x/y
|
|
public var last_mouse_x : Int = 0;
|
|
public var last_mouse_y : Int = 0;
|
|
|
|
//input helper for diff platforms
|
|
public var helper : InputHelper;
|
|
|
|
public function new( _lib:Lime ) {
|
|
|
|
lib = _lib;
|
|
|
|
helper = new InputHelper( lib );
|
|
|
|
} //new
|
|
|
|
//Public facing API
|
|
|
|
//Down / Pressed / Released helpers
|
|
|
|
public function keypressed( _value:KeyValue ) {
|
|
return key_value_pressed.exists(_value);
|
|
} //keypressed
|
|
|
|
public function keyreleased( _value:KeyValue ) {
|
|
return key_value_released.exists(_value);
|
|
} //keyreleased
|
|
|
|
public function keydown( _value:KeyValue ) {
|
|
return key_value_down.exists(_value);
|
|
} //keydown
|
|
|
|
//Internal API
|
|
|
|
@:noCompletion public function startup() {
|
|
|
|
#if debug
|
|
lib._debug(':: lime :: \t InputHandler Initialized.');
|
|
#end //debug
|
|
|
|
touches_active = new Map<Int, Dynamic>();
|
|
keys_down = new Map();
|
|
|
|
key_value_pressed = new Map();
|
|
key_value_down = new Map();
|
|
key_value_released = new Map();
|
|
|
|
helper.startup();
|
|
|
|
} //startup
|
|
|
|
@:noCompletion public function shutdown() {
|
|
|
|
#if debug
|
|
lib._debug(':: lime :: \t InputHandler shut down.');
|
|
#end //debug
|
|
|
|
} //shutdown
|
|
|
|
@:noCompletion public function update() {
|
|
|
|
//update any helper stuff
|
|
helper.update();
|
|
|
|
//remove any stale key pressed value
|
|
//unless it wasn't alive for a full frame yet,
|
|
//then flag it so that it may be
|
|
for(_value in key_value_pressed.keys()){
|
|
|
|
var _flag : Bool = key_value_pressed.get(_value);
|
|
if(_flag){
|
|
key_value_pressed.remove(_value);
|
|
} else {
|
|
key_value_pressed.set(_value, true);
|
|
}
|
|
|
|
} //each pressed_value
|
|
|
|
//remove any stale key released value
|
|
//unless it wasn't alive for a full frame yet,
|
|
//then flag it so that it may be
|
|
for(_value in key_value_released.keys()){
|
|
|
|
var _flag : Bool = key_value_released.get(_value);
|
|
if(_flag){
|
|
key_value_released.remove(_value);
|
|
} else {
|
|
key_value_released.set(_value, true);
|
|
}
|
|
|
|
} //each pressed_value
|
|
|
|
} //update
|
|
|
|
//Keyboard
|
|
|
|
@:noCompletion public function lime_onchar(_event:Dynamic) {
|
|
|
|
if(lib.host.onchar != null) {
|
|
lib.host.onchar({
|
|
raw : _event,
|
|
code : _event.code,
|
|
char : _event.code,
|
|
value : _event.value,
|
|
flags : _event.flags,
|
|
key : lime.helpers.Keys.toKeyValue(_event)
|
|
});
|
|
}
|
|
|
|
_event.char = _event.code;
|
|
|
|
lime_onkeydown( _event );
|
|
|
|
} //lime_onchar
|
|
|
|
|
|
@:noCompletion public function lime_onkeydown(_event:Dynamic) {
|
|
|
|
if(lib.host.onkeydown != null && !keys_down.exists(_event.value)) {
|
|
|
|
var _keyvalue = lime.helpers.Keys.toKeyValue(_event);
|
|
|
|
keys_down.set(_event.value, true);
|
|
|
|
//flag the key as pressed, but unprocessed (false)
|
|
key_value_pressed.set(_keyvalue, false);
|
|
//flag it as down, because keyup removes it
|
|
key_value_down.set(_keyvalue, true);
|
|
|
|
//some characters can come directly, not via the onchar,
|
|
//but we want end user to only require one check,
|
|
//if(event.char != 0) { //printable key } else { //other keys }
|
|
if(_event.char == null) {
|
|
_event.char = 0;
|
|
}
|
|
|
|
lib.host.onkeydown({
|
|
raw : _event,
|
|
code : _event.code,
|
|
char : _event.char,
|
|
value : _event.value,
|
|
flags : _event.flags,
|
|
key : _keyvalue,
|
|
ctrl_down : (_event.flags & efCtrlDown > 0),
|
|
alt_down : (_event.flags & efAltDown > 0),
|
|
shift_down : (_event.flags & efShiftDown > 0),
|
|
meta_down : (_event.flags & efCommandDown > 0)
|
|
});
|
|
|
|
} //key is down and !repeated
|
|
|
|
} //lime_onkeydown
|
|
|
|
@:noCompletion public function lime_onkeyup(_event:Dynamic) {
|
|
|
|
var _keyvalue = lime.helpers.Keys.toKeyValue(_event);
|
|
|
|
//no longer flagged as down
|
|
keys_down.remove(_event.value);
|
|
|
|
//flag it as released but unprocessed
|
|
key_value_released.set(_keyvalue, false);
|
|
//remove the down flag
|
|
key_value_down.remove(_keyvalue);
|
|
|
|
//pass to the host
|
|
if(lib.host.onkeyup != null) {
|
|
|
|
lib.host.onkeyup({
|
|
raw : _event,
|
|
code : _event.code,
|
|
char : _event.char,
|
|
value : _event.value,
|
|
flags : _event.flags,
|
|
key : _keyvalue,
|
|
ctrl_down : (_event.flags & efCtrlDown > 0),
|
|
alt_down : (_event.flags & efAltDown > 0),
|
|
shift_down : (_event.flags & efShiftDown > 0),
|
|
meta_down : (_event.flags & efCommandDown > 0)
|
|
});
|
|
|
|
} //lib.host.onkeyup != null
|
|
|
|
} //lime_onkeyup
|
|
|
|
@:noCompletion public function lime_gotinputfocus(_event:Dynamic) {
|
|
|
|
//pass to the host
|
|
if(lib.host.ongotinputfocus != null) {
|
|
|
|
lib.host.ongotinputfocus({
|
|
raw : _event,
|
|
code : _event.code,
|
|
char : _event.char,
|
|
value : _event.value,
|
|
flags : _event.flags,
|
|
key : lime.helpers.Keys.toKeyValue(_event),
|
|
ctrl_down : (_event.flags & efCtrlDown > 0),
|
|
alt_down : (_event.flags & efAltDown > 0),
|
|
shift_down : (_event.flags & efShiftDown > 0),
|
|
meta_down : (_event.flags & efCommandDown > 0)
|
|
});
|
|
|
|
} //host.ongotinputfocus
|
|
|
|
} //lime_onkeyup
|
|
|
|
@:noCompletion public function lime_lostinputfocus(_event:Dynamic) {
|
|
|
|
//pass to the host
|
|
if(lib.host.onlostinputfocus != null) {
|
|
|
|
lib.host.onlostinputfocus({
|
|
raw : _event,
|
|
code : _event.code,
|
|
char : _event.char,
|
|
value : _event.value,
|
|
flags : _event.flags,
|
|
key : lime.helpers.Keys.toKeyValue(_event),
|
|
ctrl_down : (_event.flags & efCtrlDown > 0),
|
|
alt_down : (_event.flags & efAltDown > 0),
|
|
shift_down : (_event.flags & efShiftDown > 0),
|
|
meta_down : (_event.flags & efCommandDown > 0)
|
|
});
|
|
|
|
} //host.onlostinputfocus
|
|
|
|
} //lime_lostinputfocus
|
|
|
|
//Mouse
|
|
|
|
@:noCompletion public function mouse_button_from_id( id:Int ) : Dynamic {
|
|
|
|
switch(id) {
|
|
|
|
case 0 : return MouseButton.left;
|
|
case 1 : return MouseButton.middle;
|
|
case 2 : return MouseButton.right;
|
|
case 3 : return MouseButton.wheel_down;
|
|
case 4 : return MouseButton.wheel_up;
|
|
|
|
default : return id;
|
|
|
|
} //switch id
|
|
|
|
} //mouse_button_from_id
|
|
|
|
@:noCompletion public function lime_mousemove( _event:Dynamic, ?_pass_through:Bool=false ) : Void {
|
|
|
|
var deltaX = _event.x - last_mouse_x;
|
|
var deltaY = _event.y - last_mouse_y;
|
|
|
|
last_mouse_x = _event.x;
|
|
last_mouse_y = _event.y;
|
|
|
|
//locked cursor gives us the delta directly from sdl
|
|
#if lime_native
|
|
if(lib.window.cursor_locked) {
|
|
deltaX = _event.deltaX;
|
|
deltaY = _event.deltaY;
|
|
}
|
|
#end //lime_native
|
|
|
|
if(lib.host.onmousemove != null) {
|
|
|
|
var _mouse_event = _event;
|
|
|
|
if(!_pass_through) {
|
|
|
|
_mouse_event = {
|
|
raw : _event,
|
|
button : MouseButton.move,
|
|
state : MouseState.down,
|
|
x : _event.x,
|
|
y : _event.y,
|
|
deltaX : deltaX,
|
|
deltaY : deltaY,
|
|
flags : _event.flags,
|
|
ctrl_down : (_event.flags & efCtrlDown > 0),
|
|
alt_down : (_event.flags & efAltDown > 0),
|
|
shift_down : (_event.flags & efShiftDown > 0),
|
|
meta_down : (_event.flags & efCommandDown > 0)
|
|
};
|
|
|
|
} //_pass_through
|
|
|
|
lib.host.onmousemove( _mouse_event );
|
|
|
|
} //if host onmousemove
|
|
|
|
} //lime_mousemove
|
|
|
|
@:noCompletion public function lime_mousedown( _event:Dynamic, ?_pass_through:Bool=false ) : Void {
|
|
|
|
if(lib.host.onmousedown != null) {
|
|
|
|
var _mouse_event = _event;
|
|
|
|
if(!_pass_through) {
|
|
|
|
_mouse_event = {
|
|
raw : _event,
|
|
button : mouse_button_from_id(_event.value),
|
|
state : MouseState.down,
|
|
x : _event.x,
|
|
y : _event.y,
|
|
flags : _event.flags,
|
|
ctrl_down : (_event.flags & efCtrlDown > 0),
|
|
alt_down : (_event.flags & efAltDown > 0),
|
|
shift_down : (_event.flags & efShiftDown > 0),
|
|
meta_down : (_event.flags & efCommandDown > 0)
|
|
}; //
|
|
|
|
} //_pass_through
|
|
|
|
lib.host.onmousedown( _mouse_event );
|
|
|
|
} //if host onmousedown
|
|
|
|
} //lime_mousedown
|
|
|
|
@:noCompletion public function lime_mouseclick( _event:Dynamic, ?_pass_through:Bool=false ) : Void {
|
|
|
|
if(lib.host.onmouseclick != null) {
|
|
|
|
var _mouse_event = _event;
|
|
|
|
if(!_pass_through) {
|
|
|
|
_mouse_event = {
|
|
raw : _event,
|
|
button : _event.value,
|
|
state : MouseState.down,
|
|
x : _event.x,
|
|
y : _event.y,
|
|
flags : _event.flags,
|
|
ctrl_down : (_event.flags & efCtrlDown > 0),
|
|
alt_down : (_event.flags & efAltDown > 0),
|
|
shift_down : (_event.flags & efShiftDown > 0),
|
|
meta_down : (_event.flags & efCommandDown > 0)
|
|
};
|
|
|
|
} //_pass_through
|
|
|
|
lib.host.onmouseclick( _mouse_event );
|
|
|
|
} //if host onmouseclick
|
|
|
|
} //lime_mouseclick
|
|
|
|
@:noCompletion public function lime_mouseup( _event:Dynamic, ?_pass_through:Bool=false ) : Void {
|
|
|
|
if(lib.host.onmouseup != null) {
|
|
|
|
var _mouse_event = _event;
|
|
var _button = mouse_button_from_id(_event.value);
|
|
|
|
//on native platforms, the wheel can come from mouseup events
|
|
//so we watch for those and forward it to wheel instead
|
|
if( _button == MouseButton.wheel_down || _button == MouseButton.wheel_up ) {
|
|
|
|
return lime_mousewheel( _event, _pass_through);
|
|
|
|
} //wheel event
|
|
|
|
|
|
if(!_pass_through) {
|
|
|
|
_mouse_event = {
|
|
raw : _event,
|
|
button : _button,
|
|
state : MouseState.up,
|
|
x : _event.x,
|
|
y : _event.y,
|
|
flags : _event.flags,
|
|
ctrl_down : (_event.flags & efCtrlDown > 0),
|
|
alt_down : (_event.flags & efAltDown > 0),
|
|
shift_down : (_event.flags & efShiftDown > 0),
|
|
meta_down : (_event.flags & efCommandDown > 0)
|
|
};
|
|
|
|
} //pass through
|
|
|
|
|
|
lib.host.onmouseup( _mouse_event );
|
|
|
|
} //if host onmouseup
|
|
|
|
} //lime_mouseup
|
|
|
|
@:noCompletion public function lime_mousewheel( _event:Dynamic, ?_pass_through:Bool=false ) : Void {
|
|
|
|
if(lib.host.onmousewheel != null) {
|
|
|
|
var _mouse_event = _event;
|
|
|
|
if(!_pass_through) {
|
|
|
|
_mouse_event = {
|
|
raw : _event,
|
|
button : mouse_button_from_id(_event.value),
|
|
state : MouseState.wheel,
|
|
x : _event.x,
|
|
y : _event.y,
|
|
flags : _event.flags,
|
|
ctrl_down : (_event.flags & efCtrlDown > 0),
|
|
alt_down : (_event.flags & efAltDown > 0),
|
|
shift_down : (_event.flags & efShiftDown > 0),
|
|
meta_down : (_event.flags & efCommandDown > 0)
|
|
};
|
|
|
|
} //pass through
|
|
|
|
lib.host.onmousewheel( _mouse_event );
|
|
|
|
} //if host onmouseup
|
|
|
|
} //lime_mousewheel
|
|
|
|
//Touch
|
|
|
|
@:noCompletion public function lime_touchbegin(_event:Dynamic) : Void {
|
|
|
|
var touch_item = {
|
|
state : TouchState.begin,
|
|
flags : _event.flags,
|
|
ID : _event.value,
|
|
x : _event.x,
|
|
y : _event.y
|
|
};
|
|
|
|
//store the touch in the set
|
|
touches_active.set( touch_item.ID, touch_item );
|
|
|
|
//forward to the host
|
|
if(lib.host.ontouchbegin != null) {
|
|
lib.host.ontouchbegin( touch_item );
|
|
}
|
|
|
|
//forward the down event
|
|
if ((_event.flags & 0x8000) > 0) {
|
|
lime_mousedown(_event);
|
|
}
|
|
|
|
} //lime_touchbegin
|
|
|
|
@:noCompletion public function lime_touchmove(_event:Dynamic) : Void {
|
|
|
|
//Get the touch item from the set
|
|
var touch_item = touches_active.get( _event.value );
|
|
//Update the values
|
|
touch_item.x = _event.x;
|
|
touch_item.y = _event.y;
|
|
touch_item.state = TouchState.move;
|
|
touch_item.flags = _event.flags;
|
|
|
|
//Call the host function
|
|
if(lib.host.ontouchmove != null) {
|
|
lib.host.ontouchmove(touch_item);
|
|
}
|
|
|
|
} //lime_touchmove
|
|
|
|
@:noCompletion public function lime_touchend(_event:Dynamic) : Void {
|
|
|
|
//Get the touch item from the set
|
|
var touch_item = touches_active.get( _event.value );
|
|
//Update the values
|
|
touch_item.x = _event.x;
|
|
touch_item.y = _event.y;
|
|
touch_item.state = TouchState.end;
|
|
touch_item.flags = _event.flags;
|
|
|
|
if(lib.host.ontouchend != null) {
|
|
lib.host.ontouchend(touch_item);
|
|
}
|
|
|
|
//Forward the up event
|
|
if ((_event.flags & 0x8000) > 0) {
|
|
lime_mouseup(_event);
|
|
}
|
|
|
|
//remove it from the map
|
|
touches_active.remove(_event.value);
|
|
|
|
} //lime_touchend
|
|
|
|
@:noCompletion public function lime_touchtap(_event:Dynamic) : Void {
|
|
|
|
if(lib.host.ontouchtap != null) {
|
|
lib.host.ontouchtap(_event);
|
|
}
|
|
|
|
} //lime_touchtap
|
|
|
|
//Gamepad
|
|
|
|
@:noCompletion public function lime_gamepadaxis( _event:Dynamic, ?_pass_through:Bool=false ) : Void {
|
|
|
|
if(lib.host.ongamepadaxis != null) {
|
|
|
|
var _gamepad_event = _event;
|
|
|
|
if(!_pass_through) {
|
|
|
|
_gamepad_event = {
|
|
raw : _event,
|
|
axis : _event.code,
|
|
value : (_event.value / 32767),
|
|
gamepad : _event.id
|
|
}
|
|
|
|
} //pass through
|
|
|
|
lib.host.ongamepadaxis( _gamepad_event );
|
|
|
|
} //lib.host.ongamepadaxis != null
|
|
|
|
} //lime_gamepadaxis
|
|
|
|
@:noCompletion public function lime_gamepadbuttondown( _event:Dynamic, ?_pass_through:Bool=false ) : Void {
|
|
|
|
if(lib.host.ongamepadbuttondown != null) {
|
|
|
|
var _gamepad_event = _event;
|
|
|
|
if(!_pass_through) {
|
|
|
|
_gamepad_event = {
|
|
raw : _event,
|
|
state : ButtonState.down,
|
|
value : 0,
|
|
button : _event.code,
|
|
gamepad : _event.id
|
|
};
|
|
|
|
}
|
|
|
|
lib.host.ongamepadbuttondown( _gamepad_event );
|
|
|
|
}
|
|
|
|
} //lime_gamepadbuttondown
|
|
|
|
@:noCompletion public function lime_gamepadbuttonup( _event:Dynamic, ?_pass_through:Bool=false ) : Void {
|
|
|
|
if(lib.host.ongamepadbuttonup != null) {
|
|
|
|
var _gamepad_event = _event;
|
|
|
|
if(!_pass_through) {
|
|
|
|
_gamepad_event = {
|
|
raw : _event,
|
|
state : ButtonState.up,
|
|
value : 1,
|
|
button : _event.code,
|
|
gamepad : _event.id
|
|
};
|
|
|
|
}
|
|
|
|
lib.host.ongamepadbuttonup( _gamepad_event );
|
|
|
|
}
|
|
|
|
} //lime_gamepadbuttonup
|
|
|
|
@:noCompletion public function lime_gamepadball(_event:Dynamic) : Void {
|
|
if(lib.host.ongamepadball != null) {
|
|
lib.host.ongamepadball(_event);
|
|
}
|
|
} //lime_gamepadball
|
|
|
|
@:noCompletion public function lime_gamepadhat(_event:Dynamic) : Void {
|
|
if(lib.host.ongamepadhat != null) {
|
|
lib.host.ongamepadhat(_event);
|
|
}
|
|
} //lime_gamepadhat
|
|
|
|
public function lime_gamepaddeviceadded(_event:Dynamic) {
|
|
if(lib.host.ongamepaddeviceadded != null) {
|
|
lib.host.ongamepaddeviceadded(_event);
|
|
}
|
|
} //lime_gamepaddeviceadded
|
|
|
|
public function lime_gamepaddeviceremoved(_event:Dynamic) {
|
|
if(lib.host.ongamepaddeviceremoved != null) {
|
|
lib.host.ongamepaddeviceremoved(_event);
|
|
}
|
|
} //lime_gamepaddeviceremoved
|
|
|
|
private static var efLeftDown = 0x0001;
|
|
private static var efShiftDown = 0x0002;
|
|
private static var efCtrlDown = 0x0004;
|
|
private static var efAltDown = 0x0008;
|
|
private static var efCommandDown = 0x0010;
|
|
|
|
} //InputHandler
|
|
|
|
|
|
enum TouchState {
|
|
begin;
|
|
move;
|
|
end;
|
|
}
|
|
|
|
enum MouseState {
|
|
down;
|
|
move;
|
|
wheel;
|
|
up;
|
|
}
|
|
|
|
enum ButtonState {
|
|
down;
|
|
up;
|
|
}
|
|
|
|
enum MouseButton {
|
|
move;
|
|
left;
|
|
middle;
|
|
right;
|
|
wheel_up;
|
|
wheel_down;
|
|
}
|
|
|
|
typedef KeyEvent = {
|
|
var raw : Dynamic;
|
|
var code : Int;
|
|
var char : Int;
|
|
var value : Int;
|
|
var flags : Int;
|
|
var key : lime.helpers.Keys.KeyValue;
|
|
var shift_down : Bool;
|
|
var ctrl_down : Bool;
|
|
var alt_down : Bool;
|
|
var meta_down : Bool;
|
|
};
|
|
|
|
typedef TouchEvent = {
|
|
var state : TouchState;
|
|
var flags : Int;
|
|
var ID : Int;
|
|
var x : Float;
|
|
var y : Float;
|
|
var raw : Dynamic;
|
|
};
|
|
|
|
typedef MouseEvent = {
|
|
var raw : Dynamic;
|
|
var state : MouseState;
|
|
var flags : Int;
|
|
var button : MouseButton;
|
|
var x : Float;
|
|
var y : Float;
|
|
var deltaX : Float;
|
|
var deltaY : Float;
|
|
var shift_down : Bool;
|
|
var ctrl_down : Bool;
|
|
var alt_down : Bool;
|
|
var meta_down : Bool;
|
|
}
|
|
|
|
typedef GamepadEvent = {
|
|
var raw : Dynamic;
|
|
var gamepad : Int;
|
|
}
|
|
|
|
typedef GamepadButtonEvent = {
|
|
var raw : Dynamic;
|
|
var gamepad : Int;
|
|
var button : Int;
|
|
var value : Float;
|
|
var state : ButtonState;
|
|
}
|
|
|
|
typedef GamepadAxisEvent = {
|
|
var raw : Dynamic;
|
|
var gamepad : Int;
|
|
var axis : Int;
|
|
var value : Float;
|
|
}
|
|
|