UI fixes, add SimpleTextView (easier to reason about)

This commit is contained in:
Henrik Rydgård committed 2025-11-09 08:52:20 +01:00
1 parent d34da520be
commit 980ddb152b
11 files changed
+81 -44

No files matched your search

+20 -6
View File
@@ -1036,6 +1036,26 @@ void ImageView::Draw(UIContext &dc) {
const float bulletOffset = 25;
void SimpleTextView::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
dc.MeasureText(ComputeStyle(dc), 1.0f, 1.0f, text_, &w, &h, 0);
}
void SimpleTextView::Draw(UIContext &dc) {
uint32_t textColor = dc.GetTheme().itemStyle.fgColor;
dc.SetFontStyle(ComputeStyle(dc));
dc.DrawText(text_, bounds_.x, bounds_.y, textColor, 0);
}
FontStyle SimpleTextView::ComputeStyle(const UIContext &dc) const {
if (small_) {
return dc.GetTheme().uiFontSmall;
} else if (big_) {
return dc.GetTheme().uiFontBig;
} else {
return dc.GetTheme().uiFont;
}
}
void TextView::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const {
Bounds bounds(0, 0, layoutParams_->width, layoutParams_->height);
if (bounds.w < 0) {
@@ -1063,12 +1083,6 @@ void TextView::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz
if (bullet_) {
w += bulletOffset;
}
if (horiz.type == AT_MOST && bounds.w > measuredW) {
w = bounds.w;
}
if (vert.type == AT_MOST && bounds.h > measuredH) {
h = bounds.h;
}
}
void TextView::Draw(UIContext &dc) {
+22 -2
View File
@@ -132,7 +132,7 @@ static constexpr Size FILL_PARENT = -2.0f;
static constexpr Size ITEM_HEIGHT = 64.f;
// Gravity
enum Gravity {
enum class Gravity {
G_LEFT = 0,
G_RIGHT = 1,
G_HCENTER = 2,
@@ -153,6 +153,7 @@ enum Gravity {
G_VERTMASK = 3 << 2,
};
ENUM_CLASS_BITOPS(Gravity);
enum Borders {
BORDER_NONE = 0,
@@ -974,6 +975,25 @@ private:
float size_;
};
// Single-line text only.
class SimpleTextView : public InertView {
public:
SimpleTextView(std::string_view text, LayoutParams *layoutParams = 0)
: InertView(layoutParams), text_(text) {
}
void SetSmall(bool small) { small_ = small; }
void SetBig(bool big) { big_ = big; }
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
void Draw(UIContext &dc) override;
private:
FontStyle ComputeStyle(const UIContext &dc) const;
std::string text_;
bool small_ = false;
bool big_ = false;
};
class TextView : public InertView {
public:
TextView(std::string_view text, LayoutParams *layoutParams = 0)
@@ -1005,7 +1025,7 @@ private:
int textAlign_;
uint32_t textColor_;
bool hasTextColor_ = false;
bool small_;
bool small_ = false;
bool big_ = false;
bool shadow_ = false;
bool focusable_ = false;
+11 -11
View File
@@ -24,20 +24,20 @@
namespace UI {
void ApplyGravity(const Bounds &outer, const Margins &margins, float w, float h, int gravity, Bounds &inner) {
void ApplyGravity(const Bounds &outer, const Margins &margins, float w, float h, Gravity gravity, Bounds &inner) {
inner.w = w;
inner.h = h;
switch (gravity & G_HORIZMASK) {
case G_LEFT: inner.x = outer.x + margins.left; break;
case G_RIGHT: inner.x = outer.x + outer.w - w - margins.right; break;
case G_HCENTER: inner.x = outer.x + (outer.w - w) * 0.5f; break;
switch ((Gravity)((int)gravity & (int)Gravity::G_HORIZMASK)) {
case Gravity::G_LEFT: inner.x = outer.x + margins.left; break;
case Gravity::G_RIGHT: inner.x = outer.x + outer.w - w - margins.right; break;
case Gravity::G_HCENTER: inner.x = outer.x + (outer.w - w) * 0.5f; break;
}
switch (gravity & G_VERTMASK) {
case G_TOP: inner.y = outer.y + margins.top; break;
case G_BOTTOM: inner.y = outer.y + outer.h - h - margins.bottom; break;
case G_VCENTER: inner.y = outer.y + (outer.h - h) * 0.5f; break;
switch ((Gravity)((int)gravity & (int)Gravity::G_VERTMASK)) {
case Gravity::G_TOP: inner.y = outer.y + margins.top; break;
case Gravity::G_BOTTOM: inner.y = outer.y + outer.h - h - margins.bottom; break;
case Gravity::G_VCENTER: inner.y = outer.y + (outer.h - h) * 0.5f; break;
}
}
@@ -701,7 +701,7 @@ void LinearLayout::Layout() {
const LinearLayoutParams *linLayoutParams = views_[i]->GetLayoutParams()->As<LinearLayoutParams>();
Gravity gravity = G_TOPLEFT;
Gravity gravity = Gravity::G_TOPLEFT;
Margins margins = defaultMargins_;
if (linLayoutParams) {
if (linLayoutParams->HasMargins())
@@ -925,7 +925,7 @@ void GridLayout::Layout() {
const GridLayoutParams *lp = views_[i]->GetLayoutParams()->As<GridLayoutParams>();
Bounds itemBounds, innerBounds;
Gravity grav = lp ? lp->gravity : G_CENTER;
Gravity grav = lp ? lp->gravity : Gravity::G_CENTER;
itemBounds.x = bounds_.x + x;
itemBounds.y = bounds_.y + y;
+10 -8
View File
@@ -149,21 +149,23 @@ private:
class LinearLayoutParams : public LayoutParams {
public:
LinearLayoutParams()
: LayoutParams(LP_LINEAR), weight(0.0f), gravity(G_TOPLEFT), hasMargins_(false) {}
explicit LinearLayoutParams(float wgt, Gravity grav = G_TOPLEFT)
: LayoutParams(LP_LINEAR), weight(0.0f), gravity(Gravity::G_TOPLEFT), hasMargins_(false) {}
explicit LinearLayoutParams(float wgt, Gravity grav = Gravity::G_TOPLEFT)
: LayoutParams(LP_LINEAR), weight(wgt), gravity(grav), hasMargins_(false) {}
LinearLayoutParams(float wgt, const Margins &mgn)
: LayoutParams(LP_LINEAR), weight(wgt), gravity(G_TOPLEFT), margins(mgn), hasMargins_(true) {}
LinearLayoutParams(Size w, Size h, float wgt = 0.0f, Gravity grav = G_TOPLEFT)
: LayoutParams(LP_LINEAR), weight(wgt), gravity(Gravity::G_TOPLEFT), margins(mgn), hasMargins_(true) {}
LinearLayoutParams(float wgt, Gravity grav, const Margins &mgn)
: LayoutParams(LP_LINEAR), weight(wgt), gravity(grav), margins(mgn), hasMargins_(true) {}
LinearLayoutParams(Size w, Size h, float wgt = 0.0f, Gravity grav = Gravity::G_TOPLEFT)
: LayoutParams(w, h, LP_LINEAR), weight(wgt), gravity(grav), margins(0), hasMargins_(false) {}
LinearLayoutParams(Size w, Size h, float wgt, Gravity grav, const Margins &mgn)
: LayoutParams(w, h, LP_LINEAR), weight(wgt), gravity(grav), margins(mgn), hasMargins_(true) {}
LinearLayoutParams(Size w, Size h, const Margins &mgn)
: LayoutParams(w, h, LP_LINEAR), weight(0.0f), gravity(G_TOPLEFT), margins(mgn), hasMargins_(true) {}
: LayoutParams(w, h, LP_LINEAR), weight(0.0f), gravity(Gravity::G_TOPLEFT), margins(mgn), hasMargins_(true) {}
LinearLayoutParams(Size w, Size h, float wgt, const Margins &mgn)
: LayoutParams(w, h, LP_LINEAR), weight(wgt), gravity(G_TOPLEFT), margins(mgn), hasMargins_(true) {}
: LayoutParams(w, h, LP_LINEAR), weight(wgt), gravity(Gravity::G_TOPLEFT), margins(mgn), hasMargins_(true) {}
LinearLayoutParams(const Margins &mgn)
: LayoutParams(WRAP_CONTENT, WRAP_CONTENT, LP_LINEAR), weight(0.0f), gravity(G_TOPLEFT), margins(mgn), hasMargins_(true) {}
: LayoutParams(WRAP_CONTENT, WRAP_CONTENT, LP_LINEAR), weight(0.0f), gravity(Gravity::G_TOPLEFT), margins(mgn), hasMargins_(true) {}
float weight;
Gravity gravity;
@@ -226,7 +228,7 @@ struct GridLayoutSettings {
class GridLayoutParams : public LayoutParams {
public:
GridLayoutParams()
: LayoutParams(LP_GRID), gravity(G_CENTER) {}
: LayoutParams(LP_GRID), gravity(Gravity::G_CENTER) {}
explicit GridLayoutParams(Gravity grav)
: LayoutParams(LP_GRID), gravity(grav) {
}
+2 -2
View File
@@ -218,11 +218,11 @@ void GameScreen::CreateViews() {
std::string crc = StringFromFormat("%08X", crcVal);
// CRC button makes sense.
TextView *tvCRC = crcHoriz->Add(new TextView(ReplaceAll(rp->T("FeedbackCRCValue", "Disc CRC: %1"), "%1", crc), ALIGN_LEFT, true, new LinearLayoutParams(0.0, G_VCENTER)));
TextView *tvCRC = crcHoriz->Add(new TextView(ReplaceAll(rp->T("FeedbackCRCValue", "Disc CRC: %1"), "%1", crc), ALIGN_LEFT, true, new LinearLayoutParams(0.0, Gravity::G_VCENTER)));
tvCRC->SetShadow(true);
if (System_GetPropertyBool(SYSPROP_HAS_TEXT_CLIPBOARD)) {
Button *tvCRCCopy = crcHoriz->Add(new Button(di->T("Copy to clipboard"), new LinearLayoutParams(0.0, G_VCENTER)));
Button *tvCRCCopy = crcHoriz->Add(new Button(di->T("Copy to clipboard"), new LinearLayoutParams(0.0, Gravity::G_VCENTER)));
tvCRCCopy->OnClick.Add([this](UI::EventParams &) {
u32 crc = Reporting::RetrieveCRC(gamePath_);
char buffer[16];
+4 -4
View File
@@ -1865,7 +1865,7 @@ void HostnameSelectScreen::CreatePopupContents(UI::ViewGroup *parent) {
parent->Add(buttonsRow1);
parent->Add(buttonsRow2);
buttonsRow1->Add(new Spacer(new LinearLayoutParams(1.0, G_LEFT)));
buttonsRow1->Add(new Spacer(new LinearLayoutParams(1.0, Gravity::G_LEFT)));
for (char c = '0'; c <= '9'; ++c) {
char label[] = { c, '\0' };
auto button = buttonsRow1->Add(new Button(label));
@@ -1873,16 +1873,16 @@ void HostnameSelectScreen::CreatePopupContents(UI::ViewGroup *parent) {
button->SetTag(label);
}
buttonsRow1->Add(new Button("."))->OnClick.Handle(this, &HostnameSelectScreen::OnPointClick);
buttonsRow1->Add(new Spacer(new LinearLayoutParams(1.0, G_RIGHT)));
buttonsRow1->Add(new Spacer(new LinearLayoutParams(1.0, Gravity::G_RIGHT)));
buttonsRow2->Add(new Spacer(new LinearLayoutParams(1.0, G_LEFT)));
buttonsRow2->Add(new Spacer(new LinearLayoutParams(1.0, Gravity::G_LEFT)));
if (System_GetPropertyBool(SYSPROP_HAS_TEXT_INPUT_DIALOG)) {
buttonsRow2->Add(new Button(di->T("Edit")))->OnClick.Handle(this, &HostnameSelectScreen::OnEditClick);
}
buttonsRow2->Add(new Button(di->T("Delete")))->OnClick.Handle(this, &HostnameSelectScreen::OnDeleteClick);
buttonsRow2->Add(new Button(di->T("Delete all")))->OnClick.Handle(this, &HostnameSelectScreen::OnDeleteAllClick);
buttonsRow2->Add(new Button(di->T("Toggle List")))->OnClick.Handle(this, &HostnameSelectScreen::OnShowIPListClick);
buttonsRow2->Add(new Spacer(new LinearLayoutParams(1.0, G_RIGHT)));
buttonsRow2->Add(new Spacer(new LinearLayoutParams(1.0, Gravity::G_RIGHT)));
std::vector<std::string> listIP;
if (listItems_) {
+1 -1
View File
@@ -30,7 +30,7 @@ void IAPScreen::CreateViews() {
ViewGroup *appTitle = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
appTitle->Add(new ShinyIcon(ImageID("I_ICON_GOLD"), new LinearLayoutParams(64, 64)));
appTitle->Add(new TextView("PPSSPP Gold", new LinearLayoutParams(1.0f, G_VCENTER)));
appTitle->Add(new TextView("PPSSPP Gold", new LinearLayoutParams(1.0f, Gravity::G_VCENTER)));
leftColumnItems->Add(appTitle);
if (!bought) {
+5 -4
View File
@@ -60,7 +60,7 @@ TopBar::TopBar(const UIContext &ctx, bool usePortraitLayout, std::string_view ti
}
if (!title.empty()) {
TextView *titleView = Add(new TextView(title, ALIGN_VCENTER | FLAG_WRAP_TEXT, false, new LinearLayoutParams(1.0f, G_VCENTER)));
TextView *titleView = Add(new TextView(title, ALIGN_VCENTER | FLAG_WRAP_TEXT, false, new LinearLayoutParams(1.0f, Gravity::G_VCENTER)));
titleView->SetTextColor(ctx.GetTheme().itemDownStyle.fgColor);
titleView->SetBig(true);
// If using HCENTER, to balance the centering, add a spacer on the right.
@@ -182,7 +182,7 @@ private:
PaneTitleBar::PaneTitleBar(const Path &gamePath, std::string_view title, const std::string_view settingsCategory, UI::LayoutParams *layoutParams) : UI::LinearLayout(ORIENT_HORIZONTAL, layoutParams), gamePath_(gamePath) {
using namespace UI;
Add(new Spacer(10.0f, new LinearLayoutParams()));
SetSpacing(10.0f);
if (!layoutParams) {
layoutParams_->width = UI::FILL_PARENT;
layoutParams_->height = ITEM_HEIGHT;
@@ -191,12 +191,13 @@ PaneTitleBar::PaneTitleBar(const Path &gamePath, std::string_view title, const s
auto dlg = GetI18NCategory(I18NCat::DIALOG);
if (!title.empty()) {
TextView *titleView = Add(new TextView(title, ALIGN_VCENTER | FLAG_WRAP_TEXT, false, new LinearLayoutParams(1.0f, G_VCENTER, Margins(10, 0, 0, 0))));
SimpleTextView *titleView = Add(new SimpleTextView(title, new LinearLayoutParams(0.0f, Gravity::G_VCENTER, Margins(10, 0, 20, 0))));
titleView->SetBig(true);
// If using HCENTER, to balance the centering, add a spacer on the right.
// Add(new Spacer(50.0f));
}
Add(new Spacer(10.0f, new LinearLayoutParams(1.0f)));
// Now add the game icon.
if (!gamePath.empty() && g_Config.IsGameSpecific()) {
Add(new SimpleGameIconView(gamePath_, new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT)));
+3 -3
View File
@@ -242,20 +242,20 @@ SaveSlotView::SaveSlotView(const Path &gameFilename, int slot, bool vertical, UI
lines->Add(buttons);
saveStateButton_ = buttons->Add(new Button(pa->T("Save State"), new LinearLayoutParams(0.0, G_VCENTER)));
saveStateButton_ = buttons->Add(new Button(pa->T("Save State"), new LinearLayoutParams(0.0, Gravity::G_VCENTER)));
saveStateButton_->OnClick.Handle(this, &SaveSlotView::OnSaveState);
fv->OnClick.Handle(this, &SaveSlotView::OnScreenshotClick);
if (SaveState::HasSaveInSlot(gamePath_, slot)) {
if (!Achievements::HardcoreModeActive()) {
loadStateButton_ = buttons->Add(new Button(pa->T("Load State"), new LinearLayoutParams(0.0, G_VCENTER)));
loadStateButton_ = buttons->Add(new Button(pa->T("Load State"), new LinearLayoutParams(0.0, Gravity::G_VCENTER)));
loadStateButton_->OnClick.Handle(this, &SaveSlotView::OnLoadState);
}
std::string dateStr = SaveState::GetSlotDateAsString(gamePath_, slot_);
if (!dateStr.empty()) {
TextView *dateView = new TextView(dateStr, new LinearLayoutParams(0.0, G_VCENTER));
TextView *dateView = new TextView(dateStr, new LinearLayoutParams(0.0, Gravity::G_VCENTER));
if (vertical) {
dateView->SetSmall(true);
}
+2 -2
View File
@@ -334,8 +334,8 @@ void ProductView::CreateViews() {
if (!entry_.license.empty()) {
LinearLayout *horiz = Add(new LinearLayout(ORIENT_HORIZONTAL));
horiz->Add(new TextView(StringFromFormat("%s: %s", st->T_cstr("License"), entry_.license.c_str()), new LinearLayoutParams(0.0, G_VCENTER)));
horiz->Add(new Button(di->T("More info"), new LinearLayoutParams(0.0, G_VCENTER)))->OnClick.Add([this](UI::EventParams) {
horiz->Add(new TextView(StringFromFormat("%s: %s", st->T_cstr("License"), entry_.license.c_str()), new LinearLayoutParams(0.0, Gravity::G_VCENTER)));
horiz->Add(new Button(di->T("More info"), new LinearLayoutParams(0.0, Gravity::G_VCENTER)))->OnClick.Add([this](UI::EventParams) {
std::string url = StringFromFormat("https://www.ppsspp.org/docs/reference/homebrew-store-distribution/#%s", entry_.file.c_str());
System_LaunchUrl(LaunchUrlType::BROWSER_URL, url.c_str());
});
+1 -1
View File
@@ -85,7 +85,7 @@ std::string_view TiltAnalogSettingsScreen::GetTitle() const {
void TiltAnalogSettingsScreen::CreateContentViews(UI::LinearLayout *parent) {
using namespace UI;
CreateCalibrationView(parent, new LinearLayoutParams(300.0f, 300.0f, 1.0f, G_CENTER));
CreateCalibrationView(parent, new LinearLayoutParams(300.0f, 300.0f, 1.0f, Gravity::G_CENTER));
}
void TiltAnalogSettingsScreen::CreateSettingsViews(UI::LinearLayout *settings) {