Implement display cutout support for android
This commit is contained in:
parent
c7e337f96f
commit
4ec4fda91b
@ -29,6 +29,7 @@ import android.os.Process;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayCutout;
|
||||
import android.view.Gravity;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.view.KeyEvent;
|
||||
@ -39,6 +40,7 @@ import android.view.ViewGroup.MarginLayoutParams;
|
||||
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
import android.widget.FrameLayout;
|
||||
@ -63,6 +65,12 @@ public class SuperTuxKartActivity extends SDLActivity
|
||||
private ImageView m_splash_screen;
|
||||
private STKEditText m_stk_edittext;
|
||||
private int m_bottom_y;
|
||||
private float m_top_padding;
|
||||
private float m_bottom_padding;
|
||||
private float m_left_padding;
|
||||
private float m_right_padding;
|
||||
// ------------------------------------------------------------------------
|
||||
private native static void handlePadding(boolean val);
|
||||
// ------------------------------------------------------------------------
|
||||
private native static void saveKeyboardHeight(int height);
|
||||
// ------------------------------------------------------------------------
|
||||
@ -179,6 +187,8 @@ public class SuperTuxKartActivity extends SDLActivity
|
||||
m_progress_bar = null;
|
||||
m_splash_screen = null;
|
||||
m_bottom_y = 0;
|
||||
m_top_padding = m_bottom_padding = m_left_padding = m_right_padding =
|
||||
0.0f;
|
||||
final View root = getWindow().getDecorView().findViewById(
|
||||
android.R.id.content);
|
||||
root.getViewTreeObserver().addOnGlobalLayoutListener(new
|
||||
@ -250,6 +260,11 @@ public class SuperTuxKartActivity extends SDLActivity
|
||||
}
|
||||
catch(Exception e) {}
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||
{
|
||||
getWindow().getAttributes().layoutInDisplayCutoutMode =
|
||||
LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
@Override
|
||||
@ -375,6 +390,14 @@ public class SuperTuxKartActivity extends SDLActivity
|
||||
Configuration.SCREENLAYOUT_SIZE_MASK;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
public float getTopPadding() { return m_top_padding; }
|
||||
// ------------------------------------------------------------------------
|
||||
public float getBottomPadding() { return m_bottom_padding; }
|
||||
// ------------------------------------------------------------------------
|
||||
public float getLeftPadding() { return m_left_padding; }
|
||||
// ------------------------------------------------------------------------
|
||||
public float getRightPadding() { return m_right_padding; }
|
||||
// ------------------------------------------------------------------------
|
||||
public void showExtractProgress(final int progress)
|
||||
{
|
||||
runOnUiThread(new Runnable()
|
||||
@ -447,4 +470,30 @@ public class SuperTuxKartActivity extends SDLActivity
|
||||
});
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
@Override
|
||||
public void onAttachedToWindow()
|
||||
{
|
||||
super.onAttachedToWindow();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||
{
|
||||
DisplayCutout dc = getWindow().getDecorView().getRootWindowInsets()
|
||||
.getDisplayCutout();
|
||||
if (dc != null)
|
||||
{
|
||||
m_top_padding = (float)dc.getBoundingRectTop().height();
|
||||
m_bottom_padding = (float)dc.getBoundingRectBottom().height();
|
||||
m_left_padding = (float)dc.getBoundingRectLeft().width();
|
||||
m_right_padding = (float)dc.getBoundingRectRight().width();
|
||||
}
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
@Override
|
||||
public void onMultiWindowModeChanged(boolean isInMultiWindowMode,
|
||||
Configuration newConfig)
|
||||
{
|
||||
handlePadding(isInMultiWindowMode);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ using namespace irr;
|
||||
// moving screen
|
||||
std::atomic<int> g_keyboard_height(0);
|
||||
std::atomic<int> g_moved_height(0);
|
||||
std::atomic<int> g_disable_padding(0);
|
||||
extern "C" int Android_getKeyboardHeight()
|
||||
{
|
||||
return g_keyboard_height.load();
|
||||
@ -28,6 +29,11 @@ extern "C" int Android_getMovedHeight()
|
||||
return g_moved_height.load();
|
||||
}
|
||||
|
||||
extern "C" int Android_disablePadding()
|
||||
{
|
||||
return g_disable_padding.load();
|
||||
}
|
||||
|
||||
#define MAKE_ANDROID_SAVE_KBD_HEIGHT_CALLBACK(x) JNIEXPORT void JNICALL Java_ ## x##_SuperTuxKartActivity_saveKeyboardHeight(JNIEnv* env, jclass cls, jint height)
|
||||
#define ANDROID_SAVE_KBD_HEIGHT_CALLBACK(PKG_NAME) MAKE_ANDROID_SAVE_KBD_HEIGHT_CALLBACK(PKG_NAME)
|
||||
|
||||
@ -46,6 +52,65 @@ ANDROID_SAVE_MOVED_HEIGHT_CALLBACK(ANDROID_PACKAGE_CALLBACK_NAME)
|
||||
g_moved_height.store((int)height);
|
||||
}
|
||||
|
||||
#define MAKE_ANDROID_HANDLE_PADDING_CALLBACK(x) JNIEXPORT void JNICALL Java_ ## x##_SuperTuxKartActivity_handlePadding(JNIEnv* env, jclass cls, jboolean val)
|
||||
#define ANDROID_HANDLE_PADDING_CALLBACK(PKG_NAME) MAKE_ANDROID_HANDLE_PADDING_CALLBACK(PKG_NAME)
|
||||
|
||||
extern "C"
|
||||
ANDROID_HANDLE_PADDING_CALLBACK(ANDROID_PACKAGE_CALLBACK_NAME)
|
||||
{
|
||||
g_disable_padding.store((int)val);
|
||||
}
|
||||
|
||||
extern "C" void Android_initDisplayCutout(float* top, float* bottom,
|
||||
float* left, float* right)
|
||||
{
|
||||
JNIEnv* env = NULL;
|
||||
jobject activity = NULL;
|
||||
jclass class_native_activity = NULL;
|
||||
jmethodID top_method = NULL;
|
||||
jmethodID bottom_method = NULL;
|
||||
jmethodID left_method = NULL;
|
||||
jmethodID right_method = NULL;
|
||||
|
||||
env = (JNIEnv*)SDL_AndroidGetJNIEnv();
|
||||
if (!env)
|
||||
goto exit;
|
||||
|
||||
activity = (jobject)SDL_AndroidGetActivity();
|
||||
if (!activity)
|
||||
goto exit;
|
||||
|
||||
class_native_activity = env->GetObjectClass(activity);
|
||||
if (class_native_activity == NULL)
|
||||
goto exit;
|
||||
|
||||
top_method = env->GetMethodID(class_native_activity, "getTopPadding", "()F");
|
||||
if (top_method == NULL)
|
||||
goto exit;
|
||||
*top = env->CallFloatMethod(activity, top_method);
|
||||
|
||||
bottom_method = env->GetMethodID(class_native_activity, "getBottomPadding", "()F");
|
||||
if (bottom_method == NULL)
|
||||
goto exit;
|
||||
*bottom = env->CallFloatMethod(activity, bottom_method);
|
||||
|
||||
left_method = env->GetMethodID(class_native_activity, "getLeftPadding", "()F");
|
||||
if (left_method == NULL)
|
||||
goto exit;
|
||||
*left = env->CallFloatMethod(activity, left_method);
|
||||
|
||||
right_method = env->GetMethodID(class_native_activity, "getRightPadding", "()F");
|
||||
if (right_method == NULL)
|
||||
goto exit;
|
||||
*right = env->CallFloatMethod(activity, right_method);
|
||||
|
||||
exit:
|
||||
if (!env)
|
||||
return;
|
||||
env->DeleteLocalRef(class_native_activity);
|
||||
env->DeleteLocalRef(activity);
|
||||
}
|
||||
|
||||
bool Android_isHardwareKeyboardConnected()
|
||||
{
|
||||
JNIEnv* env = (JNIEnv*)SDL_AndroidGetJNIEnv();
|
||||
|
@ -40,6 +40,8 @@ namespace irr
|
||||
|
||||
extern "C" void init_objc(SDL_SysWMinfo* info, float* top, float* bottom, float* left, float* right);
|
||||
extern "C" int handle_app_event(void* userdata, SDL_Event* event);
|
||||
extern "C" void Android_initDisplayCutout(float* top, float* bottom, float* left, float* right);
|
||||
extern "C" int Android_disablePadding();
|
||||
|
||||
namespace irr
|
||||
{
|
||||
@ -110,6 +112,9 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters& param)
|
||||
#endif
|
||||
#ifdef IOS_STK
|
||||
init_objc(&Info, &TopPadding, &BottomPadding, &LeftPadding, &RightPadding);
|
||||
#endif
|
||||
#ifdef ANDROID
|
||||
Android_initDisplayCutout(&TopPadding, &BottomPadding, &LeftPadding, &RightPadding);
|
||||
#endif
|
||||
core::stringc sdlversion = "SDL Version ";
|
||||
sdlversion += Info.version.major;
|
||||
@ -1404,6 +1409,59 @@ f32 CIrrDeviceSDL::getNativeScaleY() const
|
||||
return g_native_scale_y;
|
||||
}
|
||||
|
||||
|
||||
s32 CIrrDeviceSDL::getTopPadding()
|
||||
{
|
||||
#ifdef ANDROID
|
||||
if (Android_disablePadding() != 0)
|
||||
return 0;
|
||||
#endif
|
||||
return TopPadding * getNativeScaleY();
|
||||
}
|
||||
|
||||
|
||||
s32 CIrrDeviceSDL::getBottomPadding()
|
||||
{
|
||||
#ifdef ANDROID
|
||||
if (Android_disablePadding() != 0)
|
||||
return 0;
|
||||
#endif
|
||||
return BottomPadding * getNativeScaleY();
|
||||
}
|
||||
|
||||
|
||||
s32 CIrrDeviceSDL::getLeftPadding()
|
||||
{
|
||||
#ifdef ANDROID
|
||||
if (Android_disablePadding() != 0)
|
||||
return 0;
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
if (SDL_GetDisplayOrientation(0) == SDL_ORIENTATION_LANDSCAPE_FLIPPED)
|
||||
return RightPadding;
|
||||
#endif
|
||||
return LeftPadding;
|
||||
#else
|
||||
return LeftPadding * getNativeScaleX();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
s32 CIrrDeviceSDL::getRightPadding()
|
||||
{
|
||||
#ifdef ANDROID
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
if (Android_disablePadding() != 0)
|
||||
return 0;
|
||||
if (SDL_GetDisplayOrientation(0) == SDL_ORIENTATION_LANDSCAPE_FLIPPED)
|
||||
return LeftPadding;
|
||||
#endif
|
||||
return RightPadding;
|
||||
#else
|
||||
return RightPadding * getNativeScaleX();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
} // end namespace irr
|
||||
|
||||
#endif // _IRR_COMPILE_WITH_SDL_DEVICE_
|
||||
|
@ -116,25 +116,13 @@ namespace irr
|
||||
|
||||
const SDL_SysWMinfo& getWMInfo() const { return Info; }
|
||||
|
||||
virtual s32 getTopPadding()
|
||||
{
|
||||
return TopPadding * getNativeScaleY();
|
||||
}
|
||||
virtual s32 getTopPadding();
|
||||
|
||||
virtual s32 getBottomPadding()
|
||||
{
|
||||
return BottomPadding * getNativeScaleY();
|
||||
}
|
||||
virtual s32 getBottomPadding();
|
||||
|
||||
virtual s32 getLeftPadding()
|
||||
{
|
||||
return LeftPadding * getNativeScaleX();
|
||||
}
|
||||
virtual s32 getLeftPadding();
|
||||
|
||||
virtual s32 getRightPadding()
|
||||
{
|
||||
return RightPadding * getNativeScaleX();
|
||||
}
|
||||
virtual s32 getRightPadding();
|
||||
|
||||
virtual f32 getNativeScaleX() const;
|
||||
virtual f32 getNativeScaleY() const;
|
||||
|
@ -88,6 +88,13 @@
|
||||
|
||||
#include <irrlicht.h>
|
||||
|
||||
#if !defined(SERVER_ONLY) && defined(ANDROID)
|
||||
#include <SDL.h>
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
#define ENABLE_SCREEN_ORIENTATION_HANDLING 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_RECORDER
|
||||
#include <chrono>
|
||||
#include <openglrecorder.h>
|
||||
@ -157,6 +164,7 @@ const bool ALLOW_1280_X_720 = true;
|
||||
*/
|
||||
IrrDriver::IrrDriver()
|
||||
{
|
||||
m_screen_orientation = -1;
|
||||
m_render_nw_debug = false;
|
||||
m_resolution_changing = RES_CHANGE_NONE;
|
||||
|
||||
@ -773,7 +781,9 @@ void IrrDriver::initDevice()
|
||||
m_device->getCursorControl()->setVisible(true);
|
||||
#endif
|
||||
m_pointer_shown = true;
|
||||
|
||||
#ifdef ENABLE_SCREEN_ORIENTATION_HANDLING
|
||||
m_screen_orientation = (int)SDL_GetDisplayOrientation(0);
|
||||
#endif
|
||||
if (GUIEngine::isNoGraphics())
|
||||
return;
|
||||
} // initDevice
|
||||
@ -1986,13 +1996,21 @@ void IrrDriver::handleWindowResize()
|
||||
current_screen_size.Height = screen->getHeight();
|
||||
}
|
||||
|
||||
bool screen_orientation_changed = false;
|
||||
int new_orientation = -1;
|
||||
#ifdef ENABLE_SCREEN_ORIENTATION_HANDLING
|
||||
new_orientation = (int)SDL_GetDisplayOrientation(0);
|
||||
screen_orientation_changed = m_screen_orientation != new_orientation;
|
||||
#endif
|
||||
if (m_actual_screen_size != m_video_driver->getCurrentRenderTargetSize() ||
|
||||
current_screen_size != m_video_driver->getCurrentRenderTargetSize())
|
||||
current_screen_size != m_video_driver->getCurrentRenderTargetSize() ||
|
||||
screen_orientation_changed)
|
||||
{
|
||||
// Don't update when dialog is opened
|
||||
if (dialog_exists)
|
||||
return;
|
||||
|
||||
m_screen_orientation = new_orientation;
|
||||
m_actual_screen_size = m_video_driver->getCurrentRenderTargetSize();
|
||||
UserConfigParams::m_width = m_actual_screen_size.Width;
|
||||
UserConfigParams::m_height = m_actual_screen_size.Height;
|
||||
|
@ -141,6 +141,7 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
int m_screen_orientation;
|
||||
std::vector<VideoMode> m_modes;
|
||||
|
||||
void setupViewports();
|
||||
|
Loading…
x
Reference in New Issue
Block a user