mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Handle inset adjustements on the C++ side, handle them better in the UI.
This commit is contained in:
+36
-4
@@ -141,15 +141,46 @@ Bounds UIContext::GetScissorBounds() {
|
||||
return bounds_;
|
||||
}
|
||||
|
||||
Bounds UIContext::GetLayoutBounds(bool ignoreBottomInset) const {
|
||||
Bounds bounds = GetBounds();
|
||||
|
||||
Bounds UIContext::GetLayoutBounds(ViewLayoutMode layoutMode, bool immersiveMode) const {
|
||||
float left = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_LEFT);
|
||||
float right = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_RIGHT);
|
||||
float top = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_TOP);
|
||||
float bottom = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_BOTTOM);
|
||||
if (ignoreBottomInset) {
|
||||
|
||||
switch (layoutMode) {
|
||||
case ViewLayoutMode::ApplyInsets:
|
||||
// Nothing to do
|
||||
break;
|
||||
case ViewLayoutMode::IgnoreInsets:
|
||||
left = 0.0f;
|
||||
top = 0.0f;
|
||||
right = 0.0f;
|
||||
bottom = 0.0f;
|
||||
break;
|
||||
case ViewLayoutMode::IgnoreBottomInset:
|
||||
bottom = 0.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
if (immersiveMode) {
|
||||
if (left > 0 && right > 0) {
|
||||
// Navigation bar is available, so insets leave space for it
|
||||
// even if it's hidden.
|
||||
int smallestNonZero = std::min(right, left);
|
||||
left = smallestNonZero;
|
||||
right = smallestNonZero;
|
||||
} else {
|
||||
int sideWidth = std::max(left, right);
|
||||
left = sideWidth;
|
||||
right = sideWidth;
|
||||
}
|
||||
} else {
|
||||
if ((left > 0) != (right > 0)) {
|
||||
// Only one side has a cutout (surely the camera, which is usually smaller than the nav bar), so use the larger of the two for both sides.
|
||||
int sideWidth = std::max(left, right);
|
||||
left = sideWidth;
|
||||
right = sideWidth;
|
||||
}
|
||||
}
|
||||
|
||||
// Note that we ignore bottom here, to let lists etc. extend to the bottom of the screen.
|
||||
@@ -157,6 +188,7 @@ Bounds UIContext::GetLayoutBounds(bool ignoreBottomInset) const {
|
||||
// touch things below the safe inset.
|
||||
|
||||
// Adjust left edge to compensate for cutouts (notches) if any.
|
||||
Bounds bounds = GetBounds();
|
||||
bounds.x += left;
|
||||
bounds.w -= (left + right);
|
||||
bounds.y += top;
|
||||
|
||||
+3
-1
@@ -56,6 +56,8 @@ struct AtlasData {
|
||||
|
||||
typedef std::function<AtlasData(Draw::DrawContext *, AtlasChoice, float dpiScale, bool invalidate)> UIAtlasProviderFunc;
|
||||
|
||||
enum class ViewLayoutMode;
|
||||
|
||||
class UIContext {
|
||||
public:
|
||||
UIContext();
|
||||
@@ -113,7 +115,7 @@ public:
|
||||
// in dps, like dp_xres and dp_yres
|
||||
void SetBounds(const Bounds &b) { bounds_ = b; }
|
||||
const Bounds &GetBounds() const { return bounds_; }
|
||||
Bounds GetLayoutBounds(bool ignoreBottomInset) const;
|
||||
Bounds GetLayoutBounds(ViewLayoutMode layoutMode, bool immersiveMode) const;
|
||||
Draw::DrawContext *GetDrawContext() const { return draw_; }
|
||||
const UI::Theme &GetTheme() const {
|
||||
return *theme;
|
||||
|
||||
+21
-11
@@ -17,21 +17,31 @@
|
||||
|
||||
namespace UI {
|
||||
|
||||
static void TextToImage(std::string_view buttonText, ImageID *image) {
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
if (buttonText == di->T("Delete") || buttonText == di->T("Move to trash")) {
|
||||
*image = ImageID("I_TRASHCAN");
|
||||
} else if (buttonText == di->T("Back")) {
|
||||
*image = ImageID("I_NAVIGATE_BACK");
|
||||
} else if (buttonText == di->T("Add")) {
|
||||
*image = ImageID("I_PLUS");
|
||||
} else if (buttonText == di->T("OK")) {
|
||||
*image = ImageID("I_CHECKMARK");
|
||||
} else if (buttonText == di->T("Cancel")) {
|
||||
*image = ImageID("I_NAVIGATE_BACK");
|
||||
} else if (buttonText == di->T("Exit")) {
|
||||
*image = ImageID("I_EXIT");
|
||||
}
|
||||
}
|
||||
|
||||
PopupScreen::PopupScreen(std::string_view title, std::string_view button1, std::string_view button2)
|
||||
: title_(title), button1_(button1), button2_(button2) {
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
// Auto-assign images. A bit hack to have this here.
|
||||
if (button1 == di->T("Delete") || button1 == di->T("Move to trash")) {
|
||||
button1Image_ = ImageID("I_TRASHCAN");
|
||||
} else if (button1 == di->T("Back")) {
|
||||
button1Image_ = ImageID("I_NAVIGATE_BACK");
|
||||
} else if (button1 == di->T("Add")) {
|
||||
button1Image_ = ImageID("I_PLUS");
|
||||
} else if (button1 == di->T("OK")) {
|
||||
button1Image_ = ImageID("I_CHECKMARK");
|
||||
if (!button1.empty()) {
|
||||
TextToImage(button1, &button1Image_);
|
||||
}
|
||||
if (button2 == di->T("Cancel")) {
|
||||
button2Image_ = ImageID("I_NAVIGATE_BACK");
|
||||
if (!button2.empty()) {
|
||||
TextToImage(button2, &button2Image_);
|
||||
}
|
||||
|
||||
alpha_ = 0.0f; // inherited
|
||||
|
||||
+2
-2
@@ -131,8 +131,8 @@ bool IsFocusMovementEnabled() {
|
||||
return focusMovementEnabled;
|
||||
}
|
||||
|
||||
void LayoutViewHierarchy(const UIContext &dc, const UI::Margins &rootMargins, ViewGroup *root, bool ignoreInsets, bool ignoreBottomInset) {
|
||||
Bounds rootBounds = ignoreInsets ? dc.GetBounds() : dc.GetLayoutBounds(ignoreBottomInset);
|
||||
void LayoutViewHierarchy(const UIContext &dc, const UI::Margins &rootMargins, ViewGroup *root, ViewLayoutMode layoutMode, bool immersiveMode) {
|
||||
Bounds rootBounds = dc.GetLayoutBounds(layoutMode, immersiveMode);
|
||||
|
||||
MeasureSpec horiz(EXACTLY, rootBounds.w - (rootMargins.left + rootMargins.right));
|
||||
MeasureSpec vert(EXACTLY, rootBounds.h - (rootMargins.top + rootMargins.bottom));
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ DialogResult DispatchEvents();
|
||||
|
||||
class ViewGroup;
|
||||
|
||||
void LayoutViewHierarchy(const UIContext &dc, const UI::Margins &rootMargins, UI::ViewGroup *root, bool ignoreInsets, bool ignoreBottomInset);
|
||||
void LayoutViewHierarchy(const UIContext &dc, const UI::Margins &rootMargins, UI::ViewGroup *root, ViewLayoutMode layoutMode, bool immersiveMode);
|
||||
DialogResult UpdateViewHierarchy(ViewGroup *root);
|
||||
|
||||
enum class KeyEventResult {
|
||||
|
||||
@@ -70,6 +70,12 @@ enum class ScreenRenderRole {
|
||||
};
|
||||
ENUM_CLASS_BITOPS(ScreenRenderRole);
|
||||
|
||||
enum class ViewLayoutMode {
|
||||
ApplyInsets = 0, // For gameplay, option #1
|
||||
IgnoreInsets, // For gameplay, option #2
|
||||
IgnoreBottomInset,
|
||||
};
|
||||
|
||||
class Screen {
|
||||
public:
|
||||
Screen() = default;
|
||||
|
||||
@@ -294,8 +294,8 @@ void ScrollView::Draw(UIContext &dc) {
|
||||
dc.DrawRectDropShadow(shadowBounds, radius, fade);
|
||||
}
|
||||
|
||||
// Same at the bottom.
|
||||
const float y2 = dc.GetLayoutBounds(false).y2();
|
||||
// Same at the bottom. (we check against the common UI layout mode)
|
||||
const float y2 = dc.GetLayoutBounds(ViewLayoutMode::IgnoreBottomInset, false).y2();
|
||||
if (shadows_ && bounds_.y2() < y2 && orientation_ == ORIENT_VERTICAL) {
|
||||
float radius = 20.0f;
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ void UIScreen::DoRecreateViews() {
|
||||
|
||||
// Update layout and refocus so things scroll into view.
|
||||
// This is for resizing down, when focused on something now offscreen.
|
||||
UI::LayoutViewHierarchy(*screenManager()->getUIContext(), RootMargins(), root_, ignoreInsets_, ignoreBottomInset_);
|
||||
UI::LayoutViewHierarchy(*screenManager()->getUIContext(), RootMargins(), root_, LayoutMode(), UseImmersiveMode());
|
||||
UI::View *focused = UI::GetFocusedView();
|
||||
if (focused) {
|
||||
root_->SubviewFocused(focused);
|
||||
@@ -201,7 +201,7 @@ void UIScreen::deviceRestored(Draw::DrawContext *draw) {
|
||||
}
|
||||
|
||||
Bounds UIScreen::GetLayoutBounds(UIContext &dc) const {
|
||||
return dc.GetLayoutBounds(ignoreBottomInset_);
|
||||
return dc.GetLayoutBounds(LayoutMode(), UseImmersiveMode());
|
||||
}
|
||||
|
||||
ScreenRenderFlags UIScreen::render(ScreenRenderMode mode) {
|
||||
@@ -209,7 +209,7 @@ ScreenRenderFlags UIScreen::render(ScreenRenderMode mode) {
|
||||
|
||||
UIContext &uiContext = *screenManager()->getUIContext();
|
||||
if (root_) {
|
||||
UI::LayoutViewHierarchy(uiContext, RootMargins(), root_, ignoreInsets_, ignoreBottomInset_);
|
||||
UI::LayoutViewHierarchy(uiContext, RootMargins(), root_, LayoutMode(), UseImmersiveMode());
|
||||
}
|
||||
|
||||
uiContext.PushTransform({translation_, scale_, alpha_});
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
using namespace Lin;
|
||||
|
||||
enum class ViewLayoutMode;
|
||||
|
||||
class I18NCategory;
|
||||
namespace Draw {
|
||||
class DrawContext;
|
||||
@@ -67,13 +69,13 @@ protected:
|
||||
void RecreateViews() override { recreateViews_ = true; }
|
||||
DeviceOrientation GetDeviceOrientation() const;
|
||||
bool IsOnTop() const;
|
||||
virtual ViewLayoutMode LayoutMode() const { return ViewLayoutMode::ApplyInsets; }
|
||||
virtual bool UseImmersiveMode() const { return false; }
|
||||
|
||||
UI::ViewGroup *root_ = nullptr;
|
||||
Vec3 translation_ = Vec3(0.0f);
|
||||
Vec3 scale_ = Vec3(1.0f);
|
||||
float alpha_ = 1.0f;
|
||||
bool ignoreInsets_ = false;
|
||||
bool ignoreBottomInset_ = false;
|
||||
bool ignoreInput_ = false;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -54,7 +54,7 @@ void SetOverrideScreenFrame(const Bounds *bounds) {
|
||||
}
|
||||
}
|
||||
|
||||
FRect GetScreenFrame(bool ignoreInsets, float pixelWidth, float pixelHeight) {
|
||||
FRect GetScreenFrame(bool ignoreScreenInsets, float pixelWidth, float pixelHeight) {
|
||||
FRect rc = FRect{
|
||||
0.0f,
|
||||
0.0f,
|
||||
@@ -62,21 +62,7 @@ FRect GetScreenFrame(bool ignoreInsets, float pixelWidth, float pixelHeight) {
|
||||
pixelHeight,
|
||||
};
|
||||
|
||||
const bool applyInset = !ignoreInsets;
|
||||
|
||||
if (applyInset) {
|
||||
// Remove the DPI scale to get back to pixels.
|
||||
float left = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_LEFT) / g_display.dpi_scale_x;
|
||||
float right = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_RIGHT) / g_display.dpi_scale_x;
|
||||
float top = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_TOP) / g_display.dpi_scale_y;
|
||||
float bottom = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_BOTTOM) / g_display.dpi_scale_y;
|
||||
|
||||
// Adjust left edge to compensate for cutouts (notches) if any.
|
||||
rc.x += left;
|
||||
rc.w -= (left + right);
|
||||
rc.y += top;
|
||||
rc.h -= (top + bottom);
|
||||
}
|
||||
const bool applyInset = !ignoreScreenInsets;
|
||||
|
||||
if (g_overrideScreenBounds) {
|
||||
// Set rectangle to match central node. Here we ignore bIgnoreScreenInsets.
|
||||
@@ -84,6 +70,23 @@ FRect GetScreenFrame(bool ignoreInsets, float pixelWidth, float pixelHeight) {
|
||||
rc.y = g_screenBounds.y;
|
||||
rc.w = g_screenBounds.w;
|
||||
rc.h = g_screenBounds.h;
|
||||
} else if (applyInset) {
|
||||
// Remove the DPI scale to get back to pixels.
|
||||
float left = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_LEFT) / g_display.dpi_scale_x;
|
||||
float right = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_RIGHT) / g_display.dpi_scale_x;
|
||||
float top = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_TOP) / g_display.dpi_scale_y;
|
||||
float bottom = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_BOTTOM) / g_display.dpi_scale_y;
|
||||
|
||||
// NOTE: Similarly to what we do in UI, we disregard any bottom inset when in landscape mode.
|
||||
if (g_display.GetDeviceOrientation() == DeviceOrientation::Landscape) {
|
||||
bottom = 0.0f;
|
||||
}
|
||||
|
||||
// Adjust left edge to compensate for cutouts (notches) if any.
|
||||
rc.x += left;
|
||||
rc.w -= (left + right);
|
||||
rc.y += top;
|
||||
rc.h -= (top + bottom);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "UI/BaseScreens.h"
|
||||
#include "Core/Config.h"
|
||||
|
||||
ViewLayoutMode UIBaseScreen::LayoutMode() const {
|
||||
return ViewLayoutMode::IgnoreBottomInset;
|
||||
}
|
||||
|
||||
bool UIBaseScreen::UseImmersiveMode() const {
|
||||
DisplayLayoutConfig &config = g_Config.GetDisplayLayoutConfig(GetDeviceOrientation());
|
||||
bool portrait = GetDeviceOrientation() == DeviceOrientation::Portrait;
|
||||
if (!portrait && config.bImmersiveMode) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ViewLayoutMode UIBaseDialogScreen::LayoutMode() const {
|
||||
return ViewLayoutMode::IgnoreBottomInset;
|
||||
}
|
||||
|
||||
bool UIBaseDialogScreen::UseImmersiveMode() const {
|
||||
DisplayLayoutConfig &config = g_Config.GetDisplayLayoutConfig(GetDeviceOrientation());
|
||||
bool portrait = GetDeviceOrientation() == DeviceOrientation::Portrait;
|
||||
if (!portrait && config.bImmersiveMode) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
class UIBaseScreen : public UIScreen {
|
||||
public:
|
||||
UIBaseScreen() : UIScreen() {}
|
||||
ViewLayoutMode LayoutMode() const override;
|
||||
bool UseImmersiveMode() const override;
|
||||
protected:
|
||||
void sendMessage(UIMessage message, const char *value) override;
|
||||
};
|
||||
@@ -17,6 +19,9 @@ public:
|
||||
UIBaseDialogScreen() : UIDialogScreen(), gamePath_() {}
|
||||
explicit UIBaseDialogScreen(const Path &gamePath) : UIDialogScreen(), gamePath_(gamePath) {}
|
||||
protected:
|
||||
ViewLayoutMode LayoutMode() const override;
|
||||
bool UseImmersiveMode() const override;
|
||||
|
||||
void sendMessage(UIMessage message, const char *value) override;
|
||||
void AddStandardBack(UI::ViewGroup *parent);
|
||||
Path gamePath_;
|
||||
|
||||
@@ -1025,7 +1025,7 @@ void VisualMappingScreen::MapNext(bool successive) {
|
||||
HandleKeyMapping(mapping);
|
||||
}, I18NCat::KEYMAPPING);
|
||||
|
||||
Bounds bounds = screenManager()->getUIContext()->GetLayoutBounds(false);
|
||||
Bounds bounds = screenManager()->getUIContext()->GetLayoutBounds(LayoutMode(), false);
|
||||
dialog->SetPopupOffset(psp_->GetPopupOffset() * bounds.h);
|
||||
dialog->SetDelay(successive ? 0.5f : 0.1f);
|
||||
screenManager()->push(dialog);
|
||||
|
||||
@@ -142,7 +142,7 @@ void CustomButtonMappingScreen::CreateDialogViews(UI::ViewGroup *parent) {
|
||||
array[i] = (0x01 == ((g_Config.CustomButton[id_].key >> i) & 0x01));
|
||||
|
||||
// TODO: Less hacky layout work
|
||||
const Bounds layoutBounds = screenManager()->getUIContext()->GetLayoutBounds(false);
|
||||
const Bounds layoutBounds = GetLayoutBounds(*screenManager()->getUIContext());
|
||||
leftColumn->Add(new ButtonPreview(g_Config.iTouchButtonStyle == 0 ? customKeyShapes[cfg->shape].i : customKeyShapes[cfg->shape].l,
|
||||
customKeyImages[cfg->image].i, customKeyImages[cfg->image].r, customKeyShapes[cfg->shape].f, customKeyShapes[cfg->shape].r, layoutBounds.x + 62, layoutBounds.y + 102));
|
||||
|
||||
|
||||
+4
-3
@@ -220,13 +220,14 @@ void DrawFramebufferList(UIContext *ctx, GPUDebugInterface *gpu, const Bounds &b
|
||||
}
|
||||
|
||||
void DrawControlMapperOverlay(UIContext *ctx, const Bounds &bounds, const ControlMapper &controlMapper) {
|
||||
DrawControlDebug(ctx, controlMapper, ctx->GetLayoutBounds(false));
|
||||
DrawControlDebug(ctx, controlMapper, ctx->GetLayoutBounds(ViewLayoutMode::ApplyInsets, false));
|
||||
}
|
||||
|
||||
void DrawDebugOverlay(UIContext *ctx, const Bounds &bounds, DebugOverlay overlay) {
|
||||
bool inGame = GetUIState() == UISTATE_INGAME;
|
||||
|
||||
const Bounds layoutBounds = ctx->GetLayoutBounds(false);
|
||||
const Bounds layoutBounds = ctx->GetLayoutBounds(ViewLayoutMode::ApplyInsets, false);
|
||||
|
||||
switch (overlay) {
|
||||
case DebugOverlay::DEBUG_STATS:
|
||||
if (inGame)
|
||||
@@ -256,7 +257,7 @@ void DrawDebugOverlay(UIContext *ctx, const Bounds &bounds, DebugOverlay overlay
|
||||
#endif
|
||||
case DebugOverlay::FRAMEBUFFER_LIST:
|
||||
if (inGame)
|
||||
DrawFramebufferList(ctx, gpu, bounds);
|
||||
DrawFramebufferList(ctx, gpu, layoutBounds);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -179,6 +179,10 @@ public:
|
||||
const char *tag() const override { return "TouchTest"; }
|
||||
|
||||
protected:
|
||||
ViewLayoutMode LayoutMode() const override {
|
||||
return ViewLayoutMode::ApplyInsets;
|
||||
}
|
||||
|
||||
struct TrackedTouch {
|
||||
int id;
|
||||
float x;
|
||||
|
||||
@@ -282,11 +282,15 @@ void DisplayLayoutScreen::CreateViews() {
|
||||
supportsInsets = true;
|
||||
#endif
|
||||
// Hide insets option if no insets, or OS too old.
|
||||
float insetLeft = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_LEFT);
|
||||
float insetRight = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_RIGHT);
|
||||
float insetTop = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_TOP);
|
||||
float insetBottom = System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_BOTTOM);
|
||||
if (supportsInsets && (
|
||||
System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_LEFT) != 0.0f ||
|
||||
System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_TOP) != 0.0f ||
|
||||
System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_RIGHT) != 0.0f ||
|
||||
System_GetPropertyFloat(SYSPROP_DISPLAY_SAFE_INSET_BOTTOM) != 0.0f)) {
|
||||
insetLeft != 0.0f ||
|
||||
insetTop != 0.0f ||
|
||||
insetRight != 0.0f ||
|
||||
insetBottom != 0.0f) && (insetLeft != insetTop || insetRight != insetBottom)) {
|
||||
rightColumn->Add(new CheckBox(&config.bIgnoreScreenInsets, gr->T("Ignore camera notch when centering")));
|
||||
}
|
||||
|
||||
|
||||
+6
-1
@@ -1268,6 +1268,7 @@ void EmuScreen::CreateViews() {
|
||||
TouchControlConfig &touch = g_Config.GetTouchControlsConfig(deviceOrientation);
|
||||
|
||||
const Bounds &bounds = GetLayoutBounds(*screenManager()->getUIContext());
|
||||
|
||||
InitPadLayout(&touch, deviceOrientation, bounds.w, bounds.h);
|
||||
|
||||
root_ = CreatePadLayout(touch, bounds.w, bounds.h, &pauseTrigger_, &g_controlMapper);
|
||||
@@ -1429,6 +1430,10 @@ void EmuScreen::OnChat(UI::EventParams ¶ms) {
|
||||
// To avoid including proAdhoc.h, which includes a lot of stuff.
|
||||
int GetChatMessageCount();
|
||||
|
||||
ViewLayoutMode EmuScreen::LayoutMode() const {
|
||||
return ViewLayoutMode::ApplyInsets;
|
||||
}
|
||||
|
||||
void EmuScreen::update() {
|
||||
using namespace UI;
|
||||
|
||||
@@ -1963,7 +1968,7 @@ void EmuScreen::renderUI() {
|
||||
ctx->Begin();
|
||||
|
||||
if (root_) {
|
||||
UI::LayoutViewHierarchy(*ctx, RootMargins(), root_, false, false);
|
||||
UI::LayoutViewHierarchy(*ctx, RootMargins(), root_, LayoutMode(), UseImmersiveMode());
|
||||
root_->Draw(*ctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ protected:
|
||||
void OnVKeyAnalog(VirtKey virtualKeyCode, float value) override;
|
||||
void UpdatePSPButtons(uint32_t buttonMask, uint32_t changedMask) override;
|
||||
void SetPSPAnalog(int rotation, int stick, float x, float y) override;
|
||||
ViewLayoutMode LayoutMode() const override;
|
||||
|
||||
private:
|
||||
void CreateViews() override;
|
||||
|
||||
@@ -235,7 +235,6 @@ static_assert(Draw::SEM_TEXCOORD0 == 3, "Semantic shader hardcoded in glsl above
|
||||
|
||||
GPUDriverTestScreen::GPUDriverTestScreen() {
|
||||
using namespace Draw;
|
||||
ignoreBottomInset_ = false;
|
||||
}
|
||||
|
||||
GPUDriverTestScreen::~GPUDriverTestScreen() {
|
||||
|
||||
@@ -1217,7 +1217,6 @@ void GameSettingsScreen::CreateSystemSettings(UI::ViewGroup *systemSettings) {
|
||||
// Hide Immersive Mode on pre-kitkat Android
|
||||
if (System_GetPropertyInt(SYSPROP_SYSTEMVERSION) >= 19) {
|
||||
DisplayLayoutConfig &config = g_Config.GetDisplayLayoutConfig(GetDeviceOrientation());
|
||||
// Let's reuse the Fullscreen translation string from desktop.
|
||||
systemSettings->Add(new CheckBox(&config.bImmersiveMode, sy->T("Hide navigation bar")))->OnClick.Handle(this, &GameSettingsScreen::OnImmersiveModeChange);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1150,7 +1150,6 @@ void GameBrowser::OnHomebrewStore(UI::EventParams &e) {
|
||||
|
||||
MainScreen::MainScreen() {
|
||||
g_BackgroundAudio.SetGame(Path());
|
||||
ignoreBottomInset_ = true;
|
||||
}
|
||||
|
||||
MainScreen::~MainScreen() {
|
||||
|
||||
@@ -137,6 +137,8 @@ public:
|
||||
bool key(const KeyInput &touch) override;
|
||||
|
||||
protected:
|
||||
ViewLayoutMode LayoutMode() const override { return ViewLayoutMode::IgnoreBottomInset; }
|
||||
|
||||
void CreateViews() override;
|
||||
void CreateRecentTab();
|
||||
GameBrowser *CreateBrowserTab(const Path &path, std::string_view title, std::string_view howToTitle, std::string_view howToUri, BrowseFlags browseFlags, bool *bGridView, float *scrollPos);
|
||||
|
||||
@@ -506,8 +506,6 @@ std::string_view CreditsScreen::GetTitle() const {
|
||||
void CreditsScreen::CreateDialogViews(UI::ViewGroup *parent) {
|
||||
using namespace UI;
|
||||
|
||||
ignoreBottomInset_ = false;
|
||||
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
auto cr = GetI18NCategory(I18NCat::PSPCREDITS);
|
||||
auto mm = GetI18NCategory(I18NCat::MAINMENU);
|
||||
|
||||
@@ -109,6 +109,10 @@ public:
|
||||
|
||||
const char *tag() const override { return "Logo"; }
|
||||
|
||||
protected:
|
||||
ViewLayoutMode LayoutMode() const override { return ViewLayoutMode::ApplyInsets; }
|
||||
bool UseImmersiveMode() const override { return true; }
|
||||
|
||||
private:
|
||||
void Next();
|
||||
int frames_ = 0;
|
||||
@@ -123,6 +127,7 @@ public:
|
||||
void update() override;
|
||||
|
||||
protected:
|
||||
ViewLayoutMode LayoutMode() const override { return ViewLayoutMode::ApplyInsets; }
|
||||
std::string_view GetTitle() const override;
|
||||
|
||||
void CreateDialogViews(UI::ViewGroup *parent) override;
|
||||
|
||||
@@ -425,6 +425,11 @@ void OSDOverlayScreen::update() {
|
||||
DoRecreateViews();
|
||||
}
|
||||
|
||||
ViewLayoutMode OSDOverlayScreen::LayoutMode() const {
|
||||
// Need the full insets to avoid notifications appearing out of any bounds.
|
||||
return ViewLayoutMode::ApplyInsets;
|
||||
}
|
||||
|
||||
void NoticeView::GetContentDimensionsBySpec(const UIContext &dc, UI::MeasureSpec horiz, UI::MeasureSpec vert, float &w, float &h) const {
|
||||
float layoutWidth = layoutParams_->width;
|
||||
if (layoutWidth < 0) {
|
||||
|
||||
@@ -36,9 +36,6 @@ private:
|
||||
|
||||
class OSDOverlayScreen : public UIScreen {
|
||||
public:
|
||||
OSDOverlayScreen() {
|
||||
ignoreInsets_ = false;
|
||||
}
|
||||
const char *tag() const override { return "OSDOverlayScreen"; }
|
||||
|
||||
bool UnsyncTouch(const TouchInput &touch) override;
|
||||
@@ -47,6 +44,8 @@ public:
|
||||
void DrawForeground(UIContext &ui) override;
|
||||
void update() override;
|
||||
|
||||
protected:
|
||||
ViewLayoutMode LayoutMode() const override;
|
||||
private:
|
||||
OnScreenMessagesView *osmView_ = nullptr;
|
||||
};
|
||||
|
||||
@@ -4,12 +4,13 @@
|
||||
#include "Common/UI/PopupScreens.h"
|
||||
#include "UI/MiscViews.h"
|
||||
|
||||
ViewLayoutMode UISimpleBaseDialogScreen::LayoutMode() const {
|
||||
return (flags_ & SimpleDialogFlags::ContentsCanScroll) ? ViewLayoutMode::IgnoreBottomInset : ViewLayoutMode::ApplyInsets;
|
||||
}
|
||||
|
||||
void UISimpleBaseDialogScreen::CreateViews() {
|
||||
using namespace UI;
|
||||
|
||||
const bool canScroll = flags_ & SimpleDialogFlags::ContentsCanScroll;
|
||||
ignoreBottomInset_ = canScroll;
|
||||
|
||||
const bool portrait = GetDeviceOrientation() == DeviceOrientation::Portrait;
|
||||
|
||||
root_ = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT));
|
||||
@@ -29,7 +30,7 @@ void UISimpleBaseDialogScreen::CreateViews() {
|
||||
});
|
||||
}
|
||||
|
||||
if (canScroll) {
|
||||
if (flags_ & SimpleDialogFlags::ContentsCanScroll) {
|
||||
ScrollView *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT, 1.0f));
|
||||
LinearLayout *contents = new LinearLayoutList(ORIENT_VERTICAL, new LinearLayoutParams(Margins(0, 0, 8, 0)));
|
||||
contents->SetSpacing(0);
|
||||
@@ -41,6 +42,19 @@ void UISimpleBaseDialogScreen::CreateViews() {
|
||||
}
|
||||
}
|
||||
|
||||
ViewLayoutMode UITwoPaneBaseDialogScreen::LayoutMode() const {
|
||||
const bool portrait = GetDeviceOrientation() == DeviceOrientation::Portrait;
|
||||
if (portrait) {
|
||||
if (flags_ & TwoPaneFlags::SettingsCanScroll) {
|
||||
return ViewLayoutMode::IgnoreBottomInset;
|
||||
} else {
|
||||
return ViewLayoutMode::ApplyInsets;
|
||||
}
|
||||
} else {
|
||||
return ViewLayoutMode::ApplyInsets;
|
||||
}
|
||||
}
|
||||
|
||||
void UITwoPaneBaseDialogScreen::CreateViews() {
|
||||
using namespace UI;
|
||||
|
||||
@@ -72,9 +86,6 @@ void UITwoPaneBaseDialogScreen::CreateViews() {
|
||||
|
||||
if (portrait) {
|
||||
// Portrait layout is just a vertical stack.
|
||||
if (flags_ & TwoPaneFlags::SettingsCanScroll) {
|
||||
ignoreBottomInset_ = true;
|
||||
}
|
||||
LinearLayout *root = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT));
|
||||
|
||||
TopBarFlags topBarFlags = TopBarFlags::Portrait;
|
||||
@@ -114,7 +125,6 @@ void UITwoPaneBaseDialogScreen::CreateViews() {
|
||||
}
|
||||
root_ = root;
|
||||
} else {
|
||||
ignoreBottomInset_ = false;
|
||||
LinearLayout *root = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT));
|
||||
std::string title(GetTitle());
|
||||
TopBarFlags topBarFlags = portrait ? TopBarFlags::Portrait : TopBarFlags::Default;
|
||||
|
||||
@@ -26,6 +26,9 @@ public:
|
||||
virtual void CreateContextMenu(UI::ViewGroup *parent) {} // only called if CustomContextMenu is set in flags.
|
||||
virtual std::string_view GetTitle() const { return ""; }
|
||||
|
||||
protected:
|
||||
ViewLayoutMode LayoutMode() const override;
|
||||
|
||||
private:
|
||||
void CreateViews() override;
|
||||
SimpleDialogFlags flags_;
|
||||
@@ -61,6 +64,9 @@ public:
|
||||
virtual std::string_view GetTitle() const { return ""; }
|
||||
virtual float SettingsWidth() const { return 350.0f; }
|
||||
|
||||
protected:
|
||||
ViewLayoutMode LayoutMode() const override;
|
||||
|
||||
private:
|
||||
void CreateViews() override;
|
||||
TwoPaneFlags flags_ = TwoPaneFlags::Default;
|
||||
|
||||
@@ -30,9 +30,7 @@ ENUM_CLASS_BITOPS(TabFlags);
|
||||
|
||||
class UITabbedBaseDialogScreen : public UIBaseDialogScreen {
|
||||
public:
|
||||
UITabbedBaseDialogScreen(const Path &gamePath, TabDialogFlags flags = TabDialogFlags::Default) : UIBaseDialogScreen(gamePath), flags_(flags) {
|
||||
ignoreBottomInset_ = true;
|
||||
}
|
||||
UITabbedBaseDialogScreen(const Path &gamePath, TabDialogFlags flags = TabDialogFlags::Default) : UIBaseDialogScreen(gamePath), flags_(flags) {}
|
||||
|
||||
void AddTab(const char *tag, std::string_view title, ImageID imageId, std::function<void(UI::LinearLayout *)> createCallback, TabFlags flags = TabFlags::Default);
|
||||
void AddTab(const char *tag, std::string_view title, std::function<void(UI::LinearLayout *)> createCallback, TabFlags flags = TabFlags::Default) {
|
||||
|
||||
@@ -406,11 +406,27 @@ float System_GetPropertyFloat(SystemProperty prop) {
|
||||
return ScreenRefreshRateHz();
|
||||
case SYSPROP_DISPLAY_DPI:
|
||||
return ScreenDPI();
|
||||
#if 0
|
||||
// Simulate something like Android landscape mode for testing
|
||||
case SYSPROP_DISPLAY_SAFE_INSET_LEFT:
|
||||
return 45.0f;
|
||||
case SYSPROP_DISPLAY_SAFE_INSET_RIGHT:
|
||||
return 100.0f;
|
||||
case SYSPROP_DISPLAY_SAFE_INSET_TOP:
|
||||
return 0.0f;
|
||||
case SYSPROP_DISPLAY_SAFE_INSET_BOTTOM:
|
||||
return 80.0f;
|
||||
#else
|
||||
case SYSPROP_DISPLAY_SAFE_INSET_LEFT:
|
||||
return 0.0f;
|
||||
case SYSPROP_DISPLAY_SAFE_INSET_RIGHT:
|
||||
return 0.0f;
|
||||
case SYSPROP_DISPLAY_SAFE_INSET_TOP:
|
||||
return 0.0f;
|
||||
case SYSPROP_DISPLAY_SAFE_INSET_BOTTOM:
|
||||
return 0.0f;
|
||||
|
||||
#endif
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -919,19 +919,6 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList
|
||||
int right = insets.right;
|
||||
int top = insets.top;
|
||||
int bottom = insets.bottom;
|
||||
|
||||
// Log.w(TAG, "updateInsets: " + left + ", " + right + ", " + top + ", " + bottom);
|
||||
|
||||
// Hack to make things symmetrical in landscape. Needed on Poco F1, for example.
|
||||
if (orientation == Configuration.ORIENTATION_LANDSCAPE && useImmersive()) {
|
||||
if (left > 0 && right > 0) {
|
||||
int smallestNonZero = Math.min(right, left);
|
||||
// Log.i(TAG, "Both left and right insets but not equal: " + left + " != " + right + " : Equalizing to " + smallest);
|
||||
left = smallestNonZero;
|
||||
right = smallestNonZero;
|
||||
}
|
||||
}
|
||||
|
||||
NativeApp.sendMessageFromJava("safe_insets", left + ":" + right + ":" + top + ":" + bottom);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user