mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 09:39:33 +01:00
12 files changed
+64
-31
No files matched your search
@@ -200,6 +200,11 @@ enum SystemProperty {
|
||||
// How far down the screen the side insets are needed (they're for something in a top corner), or -1.
|
||||
SYSPROP_DISPLAY_SIDE_INSETS_BOTTOM,
|
||||
SYSPROP_DISPLAY_HAS_CAMERA_CUTOUT,
|
||||
// The navigation bar's insets, also while it's hidden (a swipe from the edge brings it back).
|
||||
SYSPROP_DISPLAY_NAVBAR_INSET_LEFT,
|
||||
SYSPROP_DISPLAY_NAVBAR_INSET_RIGHT,
|
||||
SYSPROP_DISPLAY_NAVBAR_INSET_TOP,
|
||||
SYSPROP_DISPLAY_NAVBAR_INSET_BOTTOM,
|
||||
|
||||
SYSPROP_DEVICE_TYPE,
|
||||
SYSPROP_APP_GOLD, // To avoid having #ifdef GOLD other than in main.cpp and similar.
|
||||
|
||||
+13
-1
@@ -146,7 +146,7 @@ Bounds UIContext::GetScissorBounds() {
|
||||
return bounds_;
|
||||
}
|
||||
|
||||
Bounds UIContext::GetLayoutBounds(ViewLayoutMode layoutMode, bool immersiveMode) const {
|
||||
Bounds UIContext::GetLayoutBounds(ViewLayoutMode layoutMode, bool immersiveMode, bool reserveHiddenNavBar) 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);
|
||||
@@ -205,6 +205,18 @@ Bounds UIContext::GetLayoutBounds(ViewLayoutMode layoutMode, bool immersiveMode)
|
||||
}
|
||||
}
|
||||
|
||||
if (reserveHiddenNavBar && layoutMode != ViewLayoutMode::IgnoreInsets) {
|
||||
// Platforms without a navigation bar return -1, which leaves the insets alone.
|
||||
if (layoutMode != ViewLayoutMode::IgnoreSideInsets) {
|
||||
left = std::max(left, System_GetPropertyFloat(SYSPROP_DISPLAY_NAVBAR_INSET_LEFT));
|
||||
right = std::max(right, System_GetPropertyFloat(SYSPROP_DISPLAY_NAVBAR_INSET_RIGHT));
|
||||
}
|
||||
top = std::max(top, System_GetPropertyFloat(SYSPROP_DISPLAY_NAVBAR_INSET_TOP));
|
||||
if (layoutMode != ViewLayoutMode::IgnoreBottomInset) {
|
||||
bottom = std::max(bottom, System_GetPropertyFloat(SYSPROP_DISPLAY_NAVBAR_INSET_BOTTOM));
|
||||
}
|
||||
}
|
||||
|
||||
// Note that we ignore bottom here, to let lists etc. extend to the bottom of the screen.
|
||||
// However, we will add the same space to the bottom of scrolled lists, so that you don't have to
|
||||
// touch things below the safe inset.
|
||||
|
||||
+2
-1
@@ -118,7 +118,8 @@ public:
|
||||
// in dps, like dp_xres and dp_yres
|
||||
void SetBounds(const Bounds &b) { bounds_ = b; }
|
||||
const Bounds &GetBounds() const { return bounds_; }
|
||||
Bounds GetLayoutBounds(ViewLayoutMode layoutMode, bool immersiveMode) const;
|
||||
// reserveHiddenNavBar keeps out of where the navigation bar comes back on a swipe, even while it's hidden.
|
||||
Bounds GetLayoutBounds(ViewLayoutMode layoutMode, bool immersiveMode, bool reserveHiddenNavBar = false) const;
|
||||
Draw::DrawContext *GetDrawContext() const { return draw_; }
|
||||
const UI::Theme &GetTheme() const {
|
||||
return *theme;
|
||||
|
||||
@@ -238,7 +238,6 @@ void PopupScreen::CreateViews() {
|
||||
box_->Add(buttonRow);
|
||||
}
|
||||
|
||||
box_->SetRoundCorners(RoundCorners::All);
|
||||
// Rounds the top of the header and the bottom of the last view, to match the box.
|
||||
box_->SetRoundCorners(RoundCorners::All);
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ void UIScreen::deviceRestored(Draw::DrawContext *draw) {
|
||||
}
|
||||
|
||||
Bounds UIScreen::GetLayoutBounds(UIContext &dc) const {
|
||||
return dc.GetLayoutBounds(LayoutMode(), UseImmersiveMode());
|
||||
return dc.GetLayoutBounds(LayoutMode(), UseImmersiveMode(), ReserveHiddenNavBar());
|
||||
}
|
||||
|
||||
// On TVs and big monitors, controls out at the edges are hard to see and far apart. Grows with the
|
||||
@@ -151,7 +151,7 @@ static float LargeScreenInset() {
|
||||
|
||||
Bounds UIScreen::GetContentBounds(const UIContext &dc) const {
|
||||
const UI::Margins margins = RootMargins();
|
||||
Bounds bounds = dc.GetLayoutBounds(LayoutMode(), UseImmersiveMode());
|
||||
Bounds bounds = dc.GetLayoutBounds(LayoutMode(), UseImmersiveMode(), ReserveHiddenNavBar());
|
||||
bounds.x += margins.left;
|
||||
bounds.y += margins.top;
|
||||
bounds.w -= margins.horiz();
|
||||
|
||||
@@ -69,6 +69,8 @@ protected:
|
||||
bool IsOnTop() const;
|
||||
virtual ViewLayoutMode LayoutMode() const { return ViewLayoutMode::ApplyInsets; }
|
||||
virtual bool UseImmersiveMode() const { return false; }
|
||||
// For screens with buttons near the edges: a swipe can bring back a hidden navigation bar over them.
|
||||
virtual bool ReserveHiddenNavBar() const { return false; }
|
||||
|
||||
UI::ViewGroup *root_ = nullptr;
|
||||
Vec3 translation_ = Vec3(0.0f);
|
||||
|
||||
@@ -853,6 +853,7 @@ void LinearLayout::Layout() {
|
||||
// Applies rounding to the corners of the child views, based on their position in the layout and the orientation. Masked by the outerCorners.
|
||||
// Ignores invisible views.
|
||||
void LinearLayout::SetRoundCorners(RoundCorners outerCorners) {
|
||||
roundCorners_ = outerCorners;
|
||||
// Easy case first: There's spacing, just apply round corners to all subviews.
|
||||
if (spacing_ > 0.0f) {
|
||||
for (View *view : views_) {
|
||||
|
||||
+16
-22
@@ -217,12 +217,12 @@ private:
|
||||
};
|
||||
|
||||
AdhocServerCompactInfo::AdhocServerCompactInfo(const AdhocServerListEntry &entry, UI::LayoutParams *layoutParams)
|
||||
: UI::LinearLayout(ORIENT_HORIZONTAL, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::WRAP_CONTENT, UI::Margins(5.0f, 0.0f))), entry_(entry) {
|
||||
: UI::LinearLayout(ORIENT_HORIZONTAL, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::WRAP_CONTENT)), entry_(entry) {
|
||||
using namespace UI;
|
||||
|
||||
SetSpacing(5.0f);
|
||||
|
||||
LinearLayout *lines = Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(Margins(5, 5))));
|
||||
LinearLayout *lines = Add(new LinearLayout(ORIENT_VERTICAL));
|
||||
lines->SetSpacing(0.0f);
|
||||
TextView *name = lines->Add(new TextView(entry.name));
|
||||
|
||||
@@ -234,10 +234,10 @@ AdhocServerCompactInfo::AdhocServerCompactInfo(const AdhocServerListEntry &entry
|
||||
|
||||
lines->Add(new TextView(secondLine))->SetTextSize(TextSize::Small)->SetWordWrap();
|
||||
|
||||
Add(new Spacer(0.0f, new LinearLayoutParams(1.0f, Margins(0.0f, 5.0f))));
|
||||
Add(new Spacer(0.0f, new LinearLayoutParams(1.0f)));
|
||||
|
||||
if (entry.mode == AdhocDataMode::AemuPostoffice) {
|
||||
TextView *relay = Add(new TextView(n->T("Relay"), new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT, Gravity::G_VCENTER, Margins(10.0))));
|
||||
TextView *relay = Add(new TextView(n->T("Relay"), new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT, Gravity::G_VCENTER, Margins(0.0))));
|
||||
}
|
||||
|
||||
Add(new Choice(ImageID("I_FILE_COPY"), new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT)))->OnClick.Add([host = entry_.host](UI::EventParams &) {
|
||||
@@ -245,12 +245,6 @@ AdhocServerCompactInfo::AdhocServerCompactInfo(const AdhocServerListEntry &entry
|
||||
});
|
||||
}
|
||||
|
||||
void AdhocServerCompactInfo::Draw(UIContext &dc) {
|
||||
UI::LinearLayout::Draw(dc);
|
||||
// Underline
|
||||
dc.Draw()->DrawImageCenterTexel(dc.GetTheme().whiteImage, bounds_.x, bounds_.y2() - 2, bounds_.x2(), bounds_.y2(), dc.GetTheme().popupTitleStyle.fgColor);
|
||||
}
|
||||
|
||||
static UI::View *CreateInfoItemWithButton(std::string_view text, ImageID buttonImage, std::function<void(UI::EventParams &)> onClick) {
|
||||
using namespace UI;
|
||||
LinearLayout *line = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, Margins(12, 0)));
|
||||
@@ -372,22 +366,18 @@ void AdhocServerInfoScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
auto ni = GetI18NCategory(I18NCat::NETWORKING);
|
||||
|
||||
Margins contentMargins(12, 0);
|
||||
|
||||
parent->Add(new AdhocServerCompactInfo(entry_, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, contentMargins)));
|
||||
parent->Add(new Spacer(5.0f));
|
||||
parent->Add(new AdhocServerCompactInfo(entry_, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
|
||||
ScrollView *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 1.0f));
|
||||
LinearLayout *content = new LinearLayout(ORIENT_VERTICAL);
|
||||
content->SetSpacing(6.0f);
|
||||
content->SetSpacing(8.0f);
|
||||
if (!entry_.ip.empty()) {
|
||||
content->Add(new InfoItem(entry_.ip, ""));
|
||||
}
|
||||
TextView *desc = content->Add(new TextView(entry_.description, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, contentMargins)));
|
||||
desc->SetTextSize(TextSize::Small);
|
||||
desc->SetWordWrap();
|
||||
InfoItem *desc = content->Add(new InfoItem(entry_.description, "", new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
desc->SetRoundCorners();
|
||||
|
||||
LinearLayout *buttonStrip = content->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, contentMargins)));
|
||||
LinearLayout *buttonStrip = content->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
buttonStrip->SetSpacing(8);
|
||||
if (!entry_.web.empty() || !entry_.discord.empty()) {
|
||||
if (!entry_.web.empty()) {
|
||||
@@ -412,6 +402,8 @@ void AdhocServerInfoScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
CreateAdhocServerGameList(content, games_, statusRequest_.get() ? true : false);
|
||||
}
|
||||
|
||||
buttonStrip->SetRoundCorners();
|
||||
|
||||
scroll->Add(content);
|
||||
parent->Add(scroll);
|
||||
}
|
||||
@@ -500,16 +492,17 @@ private:
|
||||
};
|
||||
|
||||
AdhocServerRow::AdhocServerRow(std::string *editValue, const AdhocServerListEntry &entry, bool showDeleteButton, ScreenManager *screenManager, UI::LayoutParams *layoutParams)
|
||||
: UI::LinearLayout(ORIENT_HORIZONTAL, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::WRAP_CONTENT, UI::Margins(5.0f, 0.0f))), value_(editValue), entry_(entry) {
|
||||
: UI::LinearLayout(ORIENT_HORIZONTAL, new UI::LinearLayoutParams(UI::FILL_PARENT, UI::WRAP_CONTENT)), value_(editValue), entry_(entry) {
|
||||
using namespace UI;
|
||||
|
||||
SetSpacing(5.0f);
|
||||
SetPadding(Margins(10.0f, 2.0f, 0.0f, 2.0f));
|
||||
// Show as radio button to make it really clear that selection actually is the choice.
|
||||
int number = 0;
|
||||
Add(new ImageView([editValue, host = entry.host]() { return host == *editValue ? ImageID("I_RADIO_SELECTED") : ImageID("I_RADIO_EMPTY"); },
|
||||
new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT, Gravity::G_VCENTER, Margins(5, 0, 0, 0))));
|
||||
new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT, Gravity::G_VCENTER, Margins(0.0f, 0.0f, 6.0f, 0.0f))));
|
||||
|
||||
LinearLayout *lines = Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(Margins(5, 5))));
|
||||
LinearLayout *lines = Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(Margins(0.0f, 5))));
|
||||
lines->SetSpacing(0.0f);
|
||||
ClickableTextView *name = lines->Add(new ClickableTextView(entry.name));
|
||||
name->SetFocusable(true);
|
||||
@@ -547,6 +540,7 @@ AdhocServerRow::AdhocServerRow(std::string *editValue, const AdhocServerListEntr
|
||||
e.v = this;
|
||||
screenManager->push(new AdhocServerInfoScreen(copy));
|
||||
});
|
||||
infoButton->SetRoundCorners();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ struct AdhocGame {
|
||||
class AdhocServerCompactInfo : public UI::LinearLayout {
|
||||
public:
|
||||
AdhocServerCompactInfo(const AdhocServerListEntry &entry, UI::LayoutParams *layoutParams = nullptr);
|
||||
void Draw(UIContext &dc) override;
|
||||
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override {
|
||||
w = 500; h = 100;
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ protected:
|
||||
ViewLayoutMode LayoutMode() const override {
|
||||
return ViewLayoutMode::ApplyInsets;
|
||||
}
|
||||
bool ReserveHiddenNavBar() const override { return true; }
|
||||
void OnVKey(VirtKey virtualKeyCode, bool down) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -173,6 +173,10 @@ static float g_safeInsetLeft = 0.0;
|
||||
static float g_safeInsetRight = 0.0;
|
||||
static float g_safeInsetTop = 0.0;
|
||||
static float g_safeInsetBottom = 0.0;
|
||||
static float g_navBarInsetLeft = 0.0;
|
||||
static float g_navBarInsetRight = 0.0;
|
||||
static float g_navBarInsetTop = 0.0;
|
||||
static float g_navBarInsetBottom = 0.0;
|
||||
static bool g_hasCameraCutout = false;
|
||||
static bool g_hasAccelerometer = false;
|
||||
static bool g_hasGyro = false;
|
||||
@@ -400,6 +404,14 @@ float System_GetPropertyFloat(SystemProperty prop) {
|
||||
return g_safeInsetTop * display_scale_y * g_display.dpi_scale_y;
|
||||
case SYSPROP_DISPLAY_SAFE_INSET_BOTTOM:
|
||||
return g_safeInsetBottom * display_scale_y * g_display.dpi_scale_y;
|
||||
case SYSPROP_DISPLAY_NAVBAR_INSET_LEFT:
|
||||
return g_navBarInsetLeft * display_scale_x * g_display.dpi_scale_x;
|
||||
case SYSPROP_DISPLAY_NAVBAR_INSET_RIGHT:
|
||||
return g_navBarInsetRight * display_scale_x * g_display.dpi_scale_x;
|
||||
case SYSPROP_DISPLAY_NAVBAR_INSET_TOP:
|
||||
return g_navBarInsetTop * display_scale_y * g_display.dpi_scale_y;
|
||||
case SYSPROP_DISPLAY_NAVBAR_INSET_BOTTOM:
|
||||
return g_navBarInsetBottom * display_scale_y * g_display.dpi_scale_y;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@@ -1466,13 +1478,17 @@ extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_sendMessageFromJava(JNI
|
||||
} else if (msg == "safe_insets") {
|
||||
// INFO_LOG(Log::System, "Got insets: %s", prm.c_str());
|
||||
// We don't bother with supporting exact rectangular regions. Safe insets are good enough.
|
||||
int left, right, top, bottom, cutout;
|
||||
if (5 == sscanf(prm.c_str(), "%d:%d:%d:%d:%d", &left, &right, &top, &bottom, &cutout)) {
|
||||
int left, right, top, bottom, cutout, navLeft, navRight, navTop, navBottom;
|
||||
if (9 == sscanf(prm.c_str(), "%d:%d:%d:%d:%d:%d:%d:%d:%d", &left, &right, &top, &bottom, &cutout, &navLeft, &navRight, &navTop, &navBottom)) {
|
||||
g_safeInsetLeft = (float)left;
|
||||
g_safeInsetRight = (float)right;
|
||||
g_safeInsetTop = (float)top;
|
||||
g_safeInsetBottom = (float)bottom;
|
||||
g_hasCameraCutout = cutout != 0;
|
||||
g_navBarInsetLeft = (float)navLeft;
|
||||
g_navBarInsetRight = (float)navRight;
|
||||
g_navBarInsetTop = (float)navTop;
|
||||
g_navBarInsetBottom = (float)navBottom;
|
||||
}
|
||||
} else if (msg == "sensors") {
|
||||
int accelerometer, gyro;
|
||||
|
||||
@@ -975,7 +975,10 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList
|
||||
int right = insets.right;
|
||||
int top = insets.top;
|
||||
int bottom = insets.bottom;
|
||||
NativeApp.sendMessageFromJava("safe_insets", left + ":" + right + ":" + top + ":" + bottom + ":" + (hasCameraCutout ? 1 : 0));
|
||||
// Where the navigation bar is when shown, which it is for a while after a swipe from the edge even when hidden.
|
||||
Insets navBar = insetCompat.getInsetsIgnoringVisibility(WindowInsetsCompat.Type.navigationBars());
|
||||
NativeApp.sendMessageFromJava("safe_insets", left + ":" + right + ":" + top + ":" + bottom + ":" + (hasCameraCutout ? 1 : 0)
|
||||
+ ":" + navBar.left + ":" + navBar.right + ":" + navBar.top + ":" + navBar.bottom);
|
||||
}
|
||||
|
||||
public void notifySurface(Surface surface) {
|
||||
|
||||
Reference in new issue
Block a user