Display: add safeArea property
display.safeArea is a subset of display.bounds that accounts for notches, holes, or other display cutouts.
This commit is contained in:
@@ -315,6 +315,8 @@
|
||||
<file name="src/system/CFFI.cpp" />
|
||||
<file name="src/system/CFFIPointer.cpp" />
|
||||
<file name="src/system/ClipboardEvent.cpp" />
|
||||
<file name="src/system/Display.mm" if="mac || ios" />
|
||||
<file name="src/system/Display.cpp" unless="mac || ios" />
|
||||
<file name="src/system/DisplayMode.cpp" />
|
||||
<file name="src/system/JNI.cpp" if="android" />
|
||||
<file name="src/system/Locale.cpp" unless="mac || ios" />
|
||||
|
||||
21
project/include/system/Display.h
Normal file
21
project/include/system/Display.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef LIME_SYSTEM_DISPLAY_H
|
||||
#define LIME_SYSTEM_DISPLAY_H
|
||||
|
||||
#include <math/Rectangle.h>
|
||||
|
||||
namespace lime {
|
||||
|
||||
|
||||
class Display {
|
||||
|
||||
|
||||
public:
|
||||
|
||||
static void GetSafeAreaInsets (int displayIndex, Rectangle * rect);
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <graphics/PixelFormat.h>
|
||||
#include <math/Rectangle.h>
|
||||
#include <system/Clipboard.h>
|
||||
#include <system/Display.h>
|
||||
#include <system/DisplayMode.h>
|
||||
#include <system/JNI.h>
|
||||
#include <system/System.h>
|
||||
@@ -57,6 +58,7 @@ namespace lime {
|
||||
static int id_refreshRate;
|
||||
static int id_supportedModes;
|
||||
static int id_width;
|
||||
static int id_safeArea;
|
||||
static bool init = false;
|
||||
|
||||
|
||||
@@ -312,6 +314,7 @@ namespace lime {
|
||||
id_refreshRate = val_id ("refreshRate");
|
||||
id_supportedModes = val_id ("supportedModes");
|
||||
id_width = val_id ("width");
|
||||
id_safeArea = val_id ("safeArea");
|
||||
init = true;
|
||||
|
||||
}
|
||||
@@ -331,6 +334,14 @@ namespace lime {
|
||||
SDL_GetDisplayBounds (id, &bounds);
|
||||
alloc_field (display, id_bounds, Rectangle (bounds.x, bounds.y, bounds.w, bounds.h).Value ());
|
||||
|
||||
Rectangle safeAreaInsets;
|
||||
Display::GetSafeAreaInsets(id, &safeAreaInsets);
|
||||
alloc_field (display, id_safeArea,
|
||||
Rectangle (bounds.x + safeAreaInsets.x,
|
||||
bounds.y + safeAreaInsets.y,
|
||||
bounds.w - safeAreaInsets.x - safeAreaInsets.width,
|
||||
bounds.h - safeAreaInsets.y - safeAreaInsets.height).Value ());
|
||||
|
||||
float dpi = 72.0;
|
||||
#ifndef EMSCRIPTEN
|
||||
SDL_GetDisplayDPI (id, &dpi, NULL, NULL);
|
||||
@@ -421,6 +432,7 @@ namespace lime {
|
||||
const int id_refreshRate = hl_hash_utf8 ("refreshRate");
|
||||
const int id_supportedModes = hl_hash_utf8 ("supportedModes");
|
||||
const int id_width = hl_hash_utf8 ("width");
|
||||
const int id_safeArea = hl_hash_utf8 ("safeArea");
|
||||
const int id_x = hl_hash_utf8 ("x");
|
||||
const int id_y = hl_hash_utf8 ("y");
|
||||
|
||||
@@ -450,6 +462,16 @@ namespace lime {
|
||||
|
||||
hl_dyn_setp (display, id_bounds, &hlt_dynobj, _bounds);
|
||||
|
||||
Rectangle safeAreaInsets;
|
||||
Display::GetSafeAreaInsets(id, &safeAreaInsets);
|
||||
vdynamic* _safeArea = (vdynamic*)hl_alloc_dynobj ();
|
||||
hl_dyn_seti (_safeArea, id_x, &hlt_i32, bounds.x + safeAreaInsets.x);
|
||||
hl_dyn_seti (_safeArea, id_y, &hlt_i32, bounds.y + safeAreaInsets.y);
|
||||
hl_dyn_seti (_safeArea, id_width, &hlt_i32, bounds.w - safeAreaInsets.x - safeAreaInsets.width);
|
||||
hl_dyn_seti (_safeArea, id_height, &hlt_i32, bounds.h - safeAreaInsets.y - safeAreaInsets.height);
|
||||
|
||||
hl_dyn_setp (display, id_safeArea, &hlt_dynobj, _safeArea);
|
||||
|
||||
float dpi = 72.0;
|
||||
#ifndef EMSCRIPTEN
|
||||
SDL_GetDisplayDPI (id, &dpi, NULL, NULL);
|
||||
|
||||
13
project/src/system/Display.cpp
Normal file
13
project/src/system/Display.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include <system/Display.h>
|
||||
#include <math/Rectangle.h>
|
||||
|
||||
|
||||
namespace lime {
|
||||
|
||||
|
||||
void Display::GetSafeAreaInsets (int displayIndex, Rectangle * rect) {
|
||||
|
||||
rect->SetTo(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,35 +4,49 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
#endif
|
||||
|
||||
#include <system/Locale.h>
|
||||
#include <system/Display.h>
|
||||
#include <math/Rectangle.h>
|
||||
|
||||
|
||||
namespace lime {
|
||||
|
||||
|
||||
float Display::GetDPI () {
|
||||
void Display::GetSafeAreaInsets (int displayIndex, Rectangle * rect) {
|
||||
|
||||
#ifndef OBJC_ARC
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
#endif
|
||||
#ifdef HX_MACOS
|
||||
|
||||
NSString* locale = [[NSLocale currentLocale] localeIdentifier];
|
||||
std::string* result = 0;
|
||||
if (@available(macOS 12, *)) {
|
||||
|
||||
if (locale) {
|
||||
|
||||
const char* ptr = [locale UTF8String];
|
||||
result = new std::string (ptr);
|
||||
NSScreen * screen = [[NSScreen screens] objectAtIndex: displayIndex];
|
||||
NSEdgeInsets safeAreaInsets = [screen safeAreaInsets];
|
||||
rect->SetTo(safeAreaInsets.left,
|
||||
safeAreaInsets.top,
|
||||
safeAreaInsets.right,
|
||||
safeAreaInsets.bottom);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
#ifndef OBJC_ARC
|
||||
[pool drain];
|
||||
#endif
|
||||
|
||||
return result;
|
||||
#ifdef IPHONE
|
||||
|
||||
if (@available(iOS 11, *)) {
|
||||
|
||||
UIWindow * window = [[UIApplication sharedApplication] keyWindow];
|
||||
UIEdgeInsets safeAreaInsets = [window safeAreaInsets];
|
||||
rect->SetTo(safeAreaInsets.left,
|
||||
safeAreaInsets.top,
|
||||
safeAreaInsets.right,
|
||||
safeAreaInsets.bottom);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
rect->SetTo(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -40,5 +40,12 @@ class Display
|
||||
**/
|
||||
public var supportedModes(default, null):Array<DisplayMode>;
|
||||
|
||||
/**
|
||||
The area within the display's `bounds` where it is safe to render
|
||||
content without being obscured by notches, holes, or other display
|
||||
cutouts.
|
||||
**/
|
||||
public var safeArea(default, null):Rectangle;
|
||||
|
||||
@:noCompletion private function new() {}
|
||||
}
|
||||
|
||||
@@ -248,6 +248,22 @@ class System
|
||||
display.bounds = new Rectangle(displayInfo.bounds.x, displayInfo.bounds.y, displayInfo.bounds.width, displayInfo.bounds.height);
|
||||
display.orientation = displayInfo.orientation;
|
||||
|
||||
#if android
|
||||
var getDisplaySafeArea = JNI.createStaticMethod("org/haxe/lime/GameActivity", "getDisplaySafeAreaInsets", "()[I");
|
||||
var result = getDisplaySafeArea();
|
||||
display.safeArea = new Rectangle(
|
||||
display.bounds.x + result[0],
|
||||
display.bounds.y + result[1],
|
||||
display.bounds.width - result[0] - result[2],
|
||||
display.bounds.height - result[1] - result[3]);
|
||||
#else
|
||||
display.safeArea = new Rectangle(
|
||||
displayInfo.safeArea.x,
|
||||
displayInfo.safeArea.y,
|
||||
displayInfo.safeArea.width,
|
||||
displayInfo.safeArea.height);
|
||||
#end
|
||||
|
||||
#if ios
|
||||
var tablet = NativeCFFI.lime_system_get_ios_tablet();
|
||||
var scale = Application.current.window.scale;
|
||||
|
||||
@@ -11,12 +11,14 @@ import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.view.DisplayCutout;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.OrientationEventListener;
|
||||
import android.view.View;
|
||||
import android.view.WindowInsets;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.Manifest;
|
||||
import org.haxe.extension.Extension;
|
||||
@@ -33,6 +35,7 @@ public class GameActivity extends SDLActivity {
|
||||
private static AssetManager assetManager;
|
||||
private static List<Extension> extensions;
|
||||
private static DisplayMetrics metrics;
|
||||
private static DisplayCutout displayCutout;
|
||||
private static Vibrator vibrator;
|
||||
private static OrientationEventListener orientationListener;
|
||||
private static HaxeObject deviceOrientationListener;
|
||||
@@ -62,6 +65,37 @@ public class GameActivity extends SDLActivity {
|
||||
|
||||
}
|
||||
|
||||
public static int[] getDisplaySafeAreaInsets () {
|
||||
|
||||
if (displayCutout == null) {
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
|
||||
WindowInsets windowInsets = ((GameActivity)Extension.mainContext).getWindow().getDecorView().getRootWindowInsets();
|
||||
|
||||
if (windowInsets != null) {
|
||||
|
||||
displayCutout = windowInsets.getDisplayCutout();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int[] result = {0, 0, 0, 0};
|
||||
|
||||
if (displayCutout != null) {
|
||||
|
||||
result[0] = displayCutout.getSafeInsetLeft();
|
||||
result[1] = displayCutout.getSafeInsetTop();
|
||||
result[2] = displayCutout.getSafeInsetRight();
|
||||
result[3] = displayCutout.getSafeInsetBottom();
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected String[] getLibraries () {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user