Application: onDisplayOrientation and onDeviceOrientation events for iOS and Android

Device orientation is the orientation of the phone/tablet.

Display orientation is the orientation of what is rendered on the display.

By default, they should usually be the same. If orientation is locked, device orientation will update, but display orientation usually won't.
This commit is contained in:
Josh Tynjala
2024-11-08 16:16:59 -08:00
parent 2da06fa2af
commit 8f0b8f356e
17 changed files with 549 additions and 6 deletions

View File

@@ -13,6 +13,7 @@ import lime.system.Clipboard;
import lime.system.Display;
import lime.system.DisplayMode;
import lime.system.JNI;
import lime.system.Orientation;
import lime.system.Sensor;
import lime.system.SensorType;
import lime.system.System;
@@ -50,6 +51,7 @@ class NativeApplication
private var gamepadEventInfo = new GamepadEventInfo();
private var joystickEventInfo = new JoystickEventInfo();
private var keyEventInfo = new KeyEventInfo();
private var orientationEventInfo = new OrientationEventInfo();
private var mouseEventInfo = new MouseEventInfo();
private var renderEventInfo = new RenderEventInfo(RENDER);
private var sensorEventInfo = new SensorEventInfo();
@@ -60,6 +62,10 @@ class NativeApplication
public var handle:Dynamic;
#if android
private var deviceOrientationListener:OrientationChangeListener;
#end
private var pauseTimer:Int;
private var parent:Application;
private var toggleFullscreen:Bool;
@@ -83,6 +89,13 @@ class NativeApplication
Sensor.registerSensor(SensorType.ACCELEROMETER, 0);
#end
#if android
var setDeviceOrientationListener = JNI.createStaticMethod("org/haxe/lime/GameActivity", "setDeviceOrientationListener",
"(Lorg/haxe/lime/HaxeObject;)V");
deviceOrientationListener = new OrientationChangeListener(handleJNIOrientationEvent);
setDeviceOrientationListener(deviceOrientationListener);
#end
#if (!macro && lime_cffi)
handle = NativeCFFI.lime_application_create();
#end
@@ -118,6 +131,9 @@ class NativeApplication
NativeCFFI.lime_text_event_manager_register(handleTextEvent, textEventInfo);
NativeCFFI.lime_touch_event_manager_register(handleTouchEvent, touchEventInfo);
NativeCFFI.lime_window_event_manager_register(handleWindowEvent, windowEventInfo);
#if (ios || android)
NativeCFFI.lime_orientation_event_manager_register(handleOrientationEvent, orientationEventInfo);
#end
#if (ios || android || tvos)
NativeCFFI.lime_sensor_event_manager_register(handleSensorEvent, sensorEventInfo);
#end
@@ -353,6 +369,27 @@ class NativeApplication
}
}
private function handleOrientationEvent():Void
{
var orientation:Orientation = cast orientationEventInfo.orientation;
var display = orientationEventInfo.display;
switch (orientationEventInfo.type)
{
case DISPLAY_ORIENTATION_CHANGE:
parent.onDisplayOrientationChange.dispatch(display, orientation);
case DEVICE_ORIENTATION_CHANGE:
parent.onDeviceOrientationChange.dispatch(orientation);
}
}
#if android
private function handleJNIOrientationEvent(newOrientation:Int):Void
{
var orientation:Orientation = cast newOrientation;
parent.onDeviceOrientationChange.dispatch(orientation);
}
#end
private function handleRenderEvent():Void
{
// TODO: Allow windows to render independently
@@ -430,8 +467,7 @@ class NativeApplication
window.onTextInput.dispatch(CFFI.stringValue(textEventInfo.text));
case TEXT_EDIT:
window.onTextEdit.dispatch(CFFI.stringValue(textEventInfo.text), textEventInfo.start,
textEventInfo.length);
window.onTextEdit.dispatch(CFFI.stringValue(textEventInfo.text), textEventInfo.start, textEventInfo.length);
default:
}
@@ -757,12 +793,12 @@ class NativeApplication
@:keep /*private*/ class KeyEventInfo
{
public var keyCode: Float;
public var keyCode:Float;
public var modifier:Int;
public var type:KeyEventType;
public var windowID:Int;
public function new(type:KeyEventType = null, windowID:Int = 0, keyCode: Float = 0, modifier:Int = 0)
public function new(type:KeyEventType = null, windowID:Int = 0, keyCode:Float = 0, modifier:Int = 0)
{
this.type = type;
this.windowID = windowID;
@@ -793,7 +829,8 @@ class NativeApplication
public var y:Float;
public var clickCount:Int;
public function new(type:MouseEventType = null, windowID:Int = 0, x:Float = 0, y:Float = 0, button:Int = 0, movementX:Float = 0, movementY:Float = 0, clickCount:Int = 0)
public function new(type:MouseEventType = null, windowID:Int = 0, x:Float = 0, y:Float = 0, button:Int = 0, movementX:Float = 0, movementY:Float = 0,
clickCount:Int = 0)
{
this.type = type;
this.windowID = 0;
@@ -978,3 +1015,46 @@ class NativeApplication
var WINDOW_SHOW = 13;
var WINDOW_HIDE = 14;
}
@:keep /*private*/ class OrientationEventInfo
{
public var orientation:Int;
public var display:Int;
public var type:OrientationEventType;
public function new(type:OrientationEventType = null, orientation:Int = 0, display:Int = -1)
{
this.type = type;
this.orientation = orientation;
this.display = display;
}
public function clone():OrientationEventInfo
{
return new OrientationEventInfo(type, orientation, display);
}
}
#if (haxe_ver >= 4.0) private enum #else @:enum private #end abstract OrientationEventType(Int)
{
var DISPLAY_ORIENTATION_CHANGE = 0;
var DEVICE_ORIENTATION_CHANGE = 1;
}
#if android
private class OrientationChangeListener implements JNISafety
{
private var callback:Int->Void;
public function new(callback:Int->Void)
{
this.callback = callback;
}
@:runOnMainThread
public function onOrientationChanged(orientation:Int):Void
{
callback(orientation);
}
}
#end

View File

@@ -233,6 +233,8 @@ class NativeCFFI
@:cffi private static function lime_neko_execute(module:String):Void;
@:cffi private static function lime_orientation_event_manager_register(callback:Dynamic, eventObject:Dynamic):Void;
@:cffi private static function lime_png_decode_bytes(data:Dynamic, decodeData:Bool, buffer:Dynamic):Dynamic;
@:cffi private static function lime_png_decode_file(path:String, decodeData:Bool, buffer:Dynamic):Dynamic;
@@ -257,6 +259,8 @@ class NativeCFFI
@:cffi private static function lime_system_get_num_displays():Int;
@:cffi private static function lime_system_get_device_orientation():Int;
@:cffi private static function lime_system_get_platform_label():Dynamic;
@:cffi private static function lime_system_get_platform_name():Dynamic;
@@ -512,6 +516,8 @@ class NativeCFFI
private static var lime_mouse_event_manager_register = new cpp.Callable<cpp.Object->cpp.Object->cpp.Void>(cpp.Prime._loadPrime("lime",
"lime_mouse_event_manager_register", "oov", false));
private static var lime_neko_execute = new cpp.Callable<String->cpp.Void>(cpp.Prime._loadPrime("lime", "lime_neko_execute", "sv", false));
private static var lime_orientation_event_manager_register = new cpp.Callable<cpp.Object->cpp.Object->cpp.Void>(cpp.Prime._loadPrime("lime",
"lime_orientation_event_manager_register", "oov", false));
private static var lime_png_decode_bytes = new cpp.Callable<cpp.Object->Bool->cpp.Object->cpp.Object>(cpp.Prime._loadPrime("lime",
"lime_png_decode_bytes", "oboo", false));
private static var lime_png_decode_file = new cpp.Callable<String->Bool->cpp.Object->cpp.Object>(cpp.Prime._loadPrime("lime", "lime_png_decode_file",
@@ -533,6 +539,7 @@ class NativeCFFI
private static var lime_system_get_display = new cpp.Callable<Int->cpp.Object>(cpp.Prime._loadPrime("lime", "lime_system_get_display", "io", false));
private static var lime_system_get_ios_tablet = new cpp.Callable<Void->Bool>(cpp.Prime._loadPrime("lime", "lime_system_get_ios_tablet", "b", false));
private static var lime_system_get_num_displays = new cpp.Callable<Void->Int>(cpp.Prime._loadPrime("lime", "lime_system_get_num_displays", "i", false));
private static var lime_system_get_device_orientation = new cpp.Callable<Void->Int>(cpp.Prime._loadPrime("lime", "lime_system_get_device_orientation", "i", false));
private static var lime_system_get_platform_label = new cpp.Callable<Void->cpp.Object>(cpp.Prime._loadPrime("lime", "lime_system_get_platform_label", "o",
false));
private static var lime_system_get_platform_name = new cpp.Callable<Void->cpp.Object>(cpp.Prime._loadPrime("lime", "lime_system_get_platform_name", "o",
@@ -712,6 +719,7 @@ class NativeCFFI
private static var lime_lzma_decompress = CFFI.load("lime", "lime_lzma_decompress", 2);
private static var lime_mouse_event_manager_register = CFFI.load("lime", "lime_mouse_event_manager_register", 2);
private static var lime_neko_execute = CFFI.load("lime", "lime_neko_execute", 1);
private static var lime_orientation_event_manager_register = CFFI.load("lime", "lime_orientation_event_manager_register", 2);
private static var lime_png_decode_bytes = CFFI.load("lime", "lime_png_decode_bytes", 3);
private static var lime_png_decode_file = CFFI.load("lime", "lime_png_decode_file", 3);
private static var lime_render_event_manager_register = CFFI.load("lime", "lime_render_event_manager_register", 2);
@@ -724,6 +732,7 @@ class NativeCFFI
private static var lime_system_get_display = CFFI.load("lime", "lime_system_get_display", 1);
private static var lime_system_get_ios_tablet = CFFI.load("lime", "lime_system_get_ios_tablet", 0);
private static var lime_system_get_num_displays = CFFI.load("lime", "lime_system_get_num_displays", 0);
private static var lime_system_get_device_orientation = CFFI.load("lime", "lime_system_get_device_orientation", 0);
private static var lime_system_get_platform_label = CFFI.load("lime", "lime_system_get_platform_label", 0);
private static var lime_system_get_platform_name = CFFI.load("lime", "lime_system_get_platform_name", 0);
private static var lime_system_get_platform_version = CFFI.load("lime", "lime_system_get_platform_version", 0);
@@ -1148,6 +1157,10 @@ class NativeCFFI
eventObject:MouseEventInfo):Void {}
// @:cffi private static function lime_neko_execute (module:String):Void;
@:hlNative("lime", "hl_orientation_event_manager_register") private static function lime_orientation_event_manager_register(callback:Void->Void,
eventObject:OrientationEventInfo):Void {}
@:hlNative("lime", "hl_png_decode_bytes") private static function lime_png_decode_bytes(data:Bytes, decodeData:Bool, buffer:ImageBuffer):ImageBuffer
{
return null;
@@ -1204,6 +1217,11 @@ class NativeCFFI
return 0;
}
@:hlNative("lime", "hl_system_get_device_orientation") private static function lime_system_get_device_orientation():Int
{
return 0;
}
@:hlNative("lime", "hl_system_get_platform_label") private static function lime_system_get_platform_label():hl.Bytes
{
return null;

View File

@@ -2,6 +2,7 @@ package lime.app;
import lime.graphics.RenderContext;
import lime.system.System;
import lime.system.Orientation;
import lime.ui.Gamepad;
import lime.ui.GamepadAxis;
import lime.ui.GamepadButton;
@@ -15,6 +16,7 @@ import lime.ui.Touch;
import lime.ui.Window;
import lime.ui.WindowAttributes;
import lime.utils.Preloader;
import lime._internal.backend.native.NativeCFFI;
/**
The Application class forms the foundation for most Lime projects.
@@ -22,11 +24,12 @@ import lime.utils.Preloader;
to override "on" functions in the class in order to handle standard events
that are relevant.
**/
@:access(lime.ui.Window)
#if !lime_debug
@:fileXml('tags="haxe,release"')
@:noDebug
#end
@:access(lime.ui.Window)
@:access(lime._internal.backend.native.NativeCFFI)
class Application extends Module
{
/**
@@ -34,6 +37,11 @@ class Application extends Module
**/
public static var current(default, null):Application;
/**
The device's orientation.
**/
public var deviceOrientation(get, never):Orientation;
/**
Meta-data values for the application, such as a version or a package name
**/
@@ -54,6 +62,19 @@ class Application extends Module
**/
public var onCreateWindow = new Event<Window->Void>();
/**
Dispatched when the orientation of the display has changed.
**/
public var onDisplayOrientationChange = new Event<Int->Orientation->Void>();
/**
Dispatched when the orientation of the device has changed. Typically,
the display and device orientation values are the same. However, if the
display orientation is locked to portrait or landscape, the display and
device orientations may be different.
**/
public var onDeviceOrientationChange = new Event<Orientation->Void>();
/**
The Preloader for the current Application
**/
@@ -632,6 +653,15 @@ class Application extends Module
{
return __windows;
}
@:noCompletion private function get_deviceOrientation():Orientation
{
#if (lime_cffi && !macro)
return cast NativeCFFI.lime_system_get_device_orientation();
#else
return UNKNOWN;
#end
}
}
#if air

View File

@@ -25,6 +25,11 @@ class Display
*/
public var dpi(default, null):Float;
/**
* Orientation of the display
*/
public var orientation(default, null):Int;
/**
* The name of the device, such as "Samsung SyncMaster P2350", "iPhone 6", "Oculus Rift DK2", etc.
**/

View File

@@ -0,0 +1,10 @@
package lime.system;
#if (haxe_ver >= 4.0) enum #else @:enum #end abstract Orientation(Int)
{
var UNKNOWN = 0;
var LANDSCAPE = 1;
var LANDSCAPE_FLIPPED = 2;
var PORTRAIT = 3;
var PORTRAIT_FLIPPED = 4;
}

View File

@@ -246,6 +246,7 @@ class System
display.id = id;
display.name = CFFI.stringValue(displayInfo.name);
display.bounds = new Rectangle(displayInfo.bounds.x, displayInfo.bounds.y, displayInfo.bounds.width, displayInfo.bounds.height);
display.orientation = displayInfo.orientation;
#if ios
var tablet = NativeCFFI.lime_system_get_ios_tablet();