Merge pull request #19984 from hrydgard/theme-fixes

Theme system fixes and additions
This commit is contained in:
Henrik Rydgård 2025-02-14 16:28:23 -06:00 committed by GitHub
commit b8e668114d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 125 additions and 58 deletions

View file

@ -44,19 +44,21 @@ uint32_t colorBlend(uint32_t rgb1, uint32_t rgb2, float alpha) {
}
uint32_t alphaMul(uint32_t color, float alphaMul) {
uint32_t rgb = color & 0xFFFFFF;
const uint32_t rgb = color & 0xFFFFFF;
int32_t alpha = color >> 24;
alpha = (int32_t)(alpha * alphaMul);
if (alpha < 0) alpha = 0;
if (alpha > 255) alpha = 255;
return (alpha << 24) | (rgb & 0xFFFFFF);
if (alpha < 0)
alpha = 0;
if (alpha > 255)
alpha = 255;
return (alpha << 24) | rgb;
}
uint32_t rgba(float r, float g, float b, float alpha) {
uint32_t color = (int)(alpha*255)<<24;
color |= (int)(b*255)<<16;
color |= (int)(g*255)<<8;
color |= (int)(r*255);
uint32_t color = (int)(alpha * 255.0f) << 24;
color |= (int)(b * 255.0f) << 16;
color |= (int)(g * 255.0f) << 8;
color |= (int)(r * 255.0f);
return color;
}

View file

@ -250,7 +250,7 @@ void ScrollView::Draw(UIContext &dc) {
if (bob.show) {
Bounds bobBounds(bounds_.x2() - bob.thickness, bounds_.y + bob.offset, bob.thickness, bob.size);
dc.FillRect(Drawable(0x80FFFFFF), bobBounds);
dc.FillRect(Drawable(dc.GetTheme().scrollbarColor), bobBounds);
}
}

View file

@ -557,10 +557,6 @@ std::string Choice::DescribeText() const {
InfoItem::InfoItem(std::string_view text, std::string_view rightText, LayoutParams *layoutParams)
: Item(layoutParams), text_(text), rightText_(rightText) {
// We set the colors later once we have a UIContext.
bgColor_ = AddTween(new CallbackColorTween(0.1f));
bgColor_->Persist();
fgColor_ = AddTween(new CallbackColorTween(0.1f));
fgColor_->Persist();
}
void InfoItem::Draw(UIContext &dc) {
@ -568,20 +564,6 @@ void InfoItem::Draw(UIContext &dc) {
UI::Style style = HasFocus() ? dc.theme->itemFocusedStyle : dc.theme->infoStyle;
if (choiceStyle_) {
style = HasFocus() ? dc.theme->itemFocusedStyle : dc.theme->itemStyle;
}
if (style.background.type == DRAW_SOLID_COLOR) {
// For a smoother fade, using the same color with 0 alpha.
if ((style.background.color & 0xFF000000) == 0)
style.background.color = dc.theme->itemFocusedStyle.background.color & 0x00FFFFFF;
bgColor_->Divert(style.background.color & 0x7fffffff);
style.background.color = bgColor_->CurrentValue();
}
fgColor_->Divert(style.fgColor);
style.fgColor = fgColor_->CurrentValue();
dc.FillRect(style.background, bounds_);
int paddingX = 12;
@ -612,6 +594,7 @@ void ItemHeader::Draw(UIContext &dc) {
dc.SetFontStyle(large_ ? dc.theme->uiFont : dc.theme->uiFontSmall);
const UI::Style &style = popupStyle_ ? dc.theme->popupStyle : dc.theme->headerStyle;
dc.FillRect(style.background, bounds_);
dc.DrawText(text_, bounds_.x + 4, bounds_.centerY(), style.fgColor, ALIGN_LEFT | ALIGN_VCENTER);
dc.Draw()->DrawImageCenterTexel(dc.theme->whiteImage, bounds_.x, bounds_.y2()-2, bounds_.x2(), bounds_.y2(), style.fgColor);
}
@ -641,7 +624,7 @@ CollapsibleHeader::CollapsibleHeader(bool *toggle, std::string_view text, Layout
}
void CollapsibleHeader::Draw(UIContext &dc) {
Style style = dc.theme->itemStyle;
Style style = dc.theme->collapsibleHeaderStyle;
if (HasFocus()) style = dc.theme->itemFocusedStyle;
if (down_) style = dc.theme->itemDownStyle;
if (!IsEnabled()) style = dc.theme->itemDisabledStyle;
@ -727,8 +710,12 @@ void PopupHeader::Draw(UIContext &dc) {
dc.PushScissor(tb);
}
dc.DrawText(text_, bounds_.x + tx, bounds_.centerY(), dc.theme->itemStyle.fgColor, ALIGN_LEFT | ALIGN_VCENTER);
dc.Draw()->DrawImageCenterTexel(dc.theme->whiteImage, bounds_.x, bounds_.y2()-2, bounds_.x2(), bounds_.y2(), dc.theme->itemStyle.fgColor);
// Header background
dc.FillRect(dc.theme->popupHeaderStyle.background, bounds_);
// Header title text
dc.DrawText(text_, bounds_.x + tx, bounds_.centerY(), dc.theme->popupHeaderStyle.fgColor, ALIGN_LEFT | ALIGN_VCENTER);
// Underline
dc.Draw()->DrawImageCenterTexel(dc.theme->whiteImage, bounds_.x, bounds_.y2()-2, bounds_.x2(), bounds_.y2(), dc.theme->popupHeaderStyle.fgColor);
if (availableWidth < tw) {
dc.PopScissor();

View file

@ -88,7 +88,6 @@ struct FontStyle {
int flags = 0;
};
// To use with an UI atlas.
struct Theme {
FontStyle uiFont;
@ -108,10 +107,15 @@ struct Theme {
Style headerStyle;
Style infoStyle;
Style collapsibleHeaderStyle;
Style popupStyle;
Style popupHeaderStyle;
Style tooltipStyle;
uint32_t backgroundColor;
uint32_t scrollbarColor;
};
// The four cardinal directions should be enough, plus Prev/Next in "element order".
@ -801,14 +805,8 @@ public:
void SetRightText(std::string_view text) {
rightText_ = text;
}
void SetChoiceStyle(bool choiceStyle) {
choiceStyle_ = choiceStyle;
}
private:
CallbackColorTween *bgColor_ = nullptr;
CallbackColorTween *fgColor_ = nullptr;
std::string text_;
std::string rightText_;

View file

@ -1215,7 +1215,6 @@ void GameSettingsScreen::CreateSystemSettings(UI::ViewGroup *systemSettings) {
// Probably it's just the root. So let's add PSP to make it clear.
usbPath = "/PSP";
}
systemSettings->Add(new InfoItem(sy->T("USB"), usbPath))->SetChoiceStyle(true);
}
}
#elif defined(_WIN32)

View file

@ -1096,13 +1096,14 @@ void SettingInfoMessage::Draw(UIContext &dc) {
alpha = MAX_ALPHA - MAX_ALPHA * (float)((sinceShow - timeToShow) / FADE_TIME);
}
if (alpha >= 0.1f) {
UI::Style style = dc.theme->popupStyle;
style.background.color = colorAlpha(style.background.color, alpha - 0.1f);
dc.FillRect(style.background, bounds_);
UI::Style style = dc.theme->tooltipStyle;
if (alpha >= 0.001f) {
uint32_t bgColor = alphaMul(style.background.color, alpha);
dc.FillRect(UI::Drawable(bgColor), bounds_);
}
uint32_t textColor = colorAlpha(dc.GetTheme().itemStyle.fgColor, alpha);
uint32_t textColor = alphaMul(style.fgColor, alpha);
text_->SetTextColor(textColor);
ViewGroup::Draw(dc);
showing_ = sinceShow <= timeToShow; // Don't consider fade time

View file

@ -46,10 +46,19 @@ struct ThemeInfo {
uint32_t uItemDisabledStyleBg = 0x55000000;
uint32_t uHeaderStyleFg = 0xFFFFFFFF;
uint32_t uHeaderStyleBg = 0x00000000;
uint32_t uInfoStyleFg = 0xFFFFFFFF;
uint32_t uInfoStyleBg = 0x00000000;
uint32_t uPopupStyleFg = 0xFFFFFFFF;
uint32_t uPopupStyleBg = 0xFF303030;
uint32_t uPopupHeaderStyleFg = 0xFFFFFFFF;
uint32_t uPopupHeaderStyleBg = 0x00000000; // default to invisible
uint32_t uTooltipStyleFg = 0xFFFFFFFF;
uint32_t uTooltipStyleBg = 0xC0303030;
uint32_t uCollapsibleHeaderStyleFg = 0xFFFFFFFF;
uint32_t uCollapsibleHeaderStyleBg = 0x55000000;
uint32_t uBackgroundColor = 0xFF754D24;
uint32_t uScrollbarColor = 0x80FFFFFF;
std::string sUIAtlas = "ui_atlas";
@ -132,10 +141,19 @@ static void LoadThemeInfo(const std::vector<Path> &directories) {
section.Get("ItemDisabledStyleBg", &info.uItemDisabledStyleBg, info.uItemDisabledStyleBg);
section.Get("HeaderStyleFg", &info.uHeaderStyleFg, info.uHeaderStyleFg);
section.Get("HeaderStyleBg", &info.uHeaderStyleBg, info.uHeaderStyleBg);
section.Get("InfoStyleFg", &info.uInfoStyleFg, info.uInfoStyleFg);
section.Get("InfoStyleBg", &info.uInfoStyleBg, info.uInfoStyleBg);
section.Get("PopupStyleFg", &info.uPopupStyleFg, info.uItemStyleFg); // Backwards compat
section.Get("PopupStyleBg", &info.uPopupStyleBg, info.uPopupStyleBg);
section.Get("TooltipStyleFg", &info.uTooltipStyleFg, info.uTooltipStyleFg); // Backwards compat
section.Get("TooltipStyleBg", &info.uTooltipStyleBg, info.uTooltipStyleBg);
section.Get("PopupHeaderStyleFg", &info.uPopupHeaderStyleFg, info.uItemStyleFg); // Backwards compat
section.Get("PopupHeaderStyleBg", &info.uPopupHeaderStyleBg, info.uPopupHeaderStyleBg);
section.Get("CollapsibleHeaderStyleFg", &info.uCollapsibleHeaderStyleFg, info.uItemStyleFg); // Backwards compat
section.Get("CollapsibleHeaderStyleBg", &info.uCollapsibleHeaderStyleBg, info.uItemStyleBg);
section.Get("BackgroundColor", &info.uBackgroundColor, info.uBackgroundColor);
section.Get("ScrollbarColor", &info.uScrollbarColor, info.uScrollbarColor);
std::string tmpPath;
section.Get("UIAtlas", &tmpPath, "");
@ -187,17 +205,26 @@ void UpdateTheme(UIContext *ctx) {
ReloadAllThemeInfo();
}
size_t i;
for (i = 0; i < themeInfos.size(); ++i) {
int defaultThemeIndex = -1;
int selectedThemeIndex = -1;
for (int i = 0; i < themeInfos.size(); ++i) {
if (themeInfos[i].name == "Default") {
defaultThemeIndex = i;
}
if (themeInfos[i].name == g_Config.sThemeName) {
break;
selectedThemeIndex = i;
}
}
// Reset to Default if not found
if (i >= themeInfos.size()) {
if (selectedThemeIndex < 0 || selectedThemeIndex >= themeInfos.size()) {
g_Config.sThemeName = "Default";
i = 0;
selectedThemeIndex = defaultThemeIndex;
if (selectedThemeIndex < 0) {
_dbg_assert_(false);
// No themes? Bad.
return;
}
}
#if defined(USING_WIN_UI) || PPSSPP_PLATFORM(UWP) || defined(USING_QT_UI)
@ -216,27 +243,35 @@ void UpdateTheme(UIContext *ctx) {
ui_theme.sliderKnob = ImageID("I_CIRCLE");
ui_theme.dropShadow4Grid = ImageID("I_DROP_SHADOW");
const ThemeInfo &themeInfo = themeInfos[selectedThemeIndex];
// Actual configurable themes setting start here
ui_theme.itemStyle = MakeStyle(themeInfos[i].uItemStyleFg, themeInfos[i].uItemStyleBg);
ui_theme.itemFocusedStyle = MakeStyle(themeInfos[i].uItemFocusedStyleFg, themeInfos[i].uItemFocusedStyleBg);
ui_theme.itemDownStyle = MakeStyle(themeInfos[i].uItemDownStyleFg, themeInfos[i].uItemDownStyleBg);
ui_theme.itemDisabledStyle = MakeStyle(themeInfos[i].uItemDisabledStyleFg, themeInfos[i].uItemDisabledStyleBg);
ui_theme.itemStyle = MakeStyle(themeInfo.uItemStyleFg, themeInfo.uItemStyleBg);
ui_theme.itemFocusedStyle = MakeStyle(themeInfo.uItemFocusedStyleFg, themeInfo.uItemFocusedStyleBg);
ui_theme.itemDownStyle = MakeStyle(themeInfo.uItemDownStyleFg, themeInfo.uItemDownStyleBg);
ui_theme.itemDisabledStyle = MakeStyle(themeInfo.uItemDisabledStyleFg, themeInfo.uItemDisabledStyleBg);
ui_theme.headerStyle.fgColor = themeInfos[i].uHeaderStyleFg;
ui_theme.infoStyle = MakeStyle(themeInfos[i].uInfoStyleFg, themeInfos[i].uInfoStyleBg);
ui_theme.headerStyle = MakeStyle(themeInfo.uHeaderStyleFg, themeInfo.uHeaderStyleBg);
ui_theme.collapsibleHeaderStyle = MakeStyle(themeInfo.uCollapsibleHeaderStyleFg, themeInfo.uCollapsibleHeaderStyleBg);
ui_theme.infoStyle = MakeStyle(themeInfo.uInfoStyleFg, themeInfo.uInfoStyleBg);
ui_theme.popupStyle = MakeStyle(themeInfos[i].uItemStyleFg, themeInfos[i].uPopupStyleBg);
ui_theme.backgroundColor = themeInfos[i].uBackgroundColor;
ui_theme.popupStyle = MakeStyle(themeInfo.uPopupStyleFg, themeInfo.uPopupStyleBg);
ui_theme.popupHeaderStyle = MakeStyle(themeInfo.uPopupHeaderStyleFg, themeInfo.uPopupHeaderStyleBg);
ui_theme.tooltipStyle = MakeStyle(themeInfo.uTooltipStyleFg, themeInfo.uTooltipStyleBg);
ui_theme.backgroundColor = themeInfo.uBackgroundColor;
ui_theme.scrollbarColor = themeInfo.uScrollbarColor;
// Load any missing atlas metadata (the images are loaded from UIContext).
LoadAtlasMetadata(ui_atlas, (themeInfos[i].sUIAtlas + ".meta").c_str(), true);
LoadAtlasMetadata(ui_atlas, (themeInfo.sUIAtlas + ".meta").c_str(), true);
#if !(PPSSPP_PLATFORM(WINDOWS) || PPSSPP_PLATFORM(ANDROID))
LoadAtlasMetadata(font_atlas, "font_atlas.meta", ui_atlas.num_fonts == 0);
#else
LoadAtlasMetadata(font_atlas, "asciifont_atlas.meta", ui_atlas.num_fonts == 0);
#endif
ctx->setUIAtlas(themeInfos[i].sUIAtlas + ".zim");
ctx->setUIAtlas(themeInfo.sUIAtlas + ".zim");
}
UI::Theme *GetTheme() {

View file

@ -21,8 +21,17 @@ ItemDownStyleBg = "#000080FF"
ItemDisabledStyleFg = "#808080FF"
ItemDisabledStyleBg = "#C0C0C0FF"
HeaderStyleFg = "#FFFFFFFF"
HeaderStyleBg = "#00000000"
InfoStyleFg = "#FFFFFFFF"
InfoStyleBg = "#00000000"
PopupStyleFg = "#000000FF"
PopupStyleBg = "#FFFFAAFF"
PopupHeaderStyleFg = "#FFFFFFFF"
PopupHeaderStyleBg = "#000080FF"
CollapsibleHeaderStyleFg = "#000000FF"
CollapsibleHeaderStyleBg = "#C0C0C0FF"
TooltipStyleFg = "#FFFFFFFF"
TooltipStyleBg = "#000080D0"
BackgroundColor = "#008080FF"
ScrollbarColor = "#00000080"
UIAtlas = "../ui_atlas"

View file

@ -9,10 +9,19 @@ ItemDownStyleBg = "#3999BDFF"
ItemDisabledStyleFg = "#EEEEEE80"
ItemDisabledStyleBg = "#00000055"
HeaderStyleFg = "#FFFFFFFF"
HeaderStyleBg = "#00000000"
InfoStyleFg = "#FFFFFFFF"
InfoStyleBg = "#00000000"
PopupStyleFg = "#FFFFFFFF"
PopupStyleBg = "#1f4d5eFF"
PopupHeaderStyleFg = "#FFFFFFFF"
PopupHeaderStyleBg = "#00000000"
CollapsibleHeaderStyleFg = "#FFFFFFFF"
CollapsibleHeaderStyleBg = "#00000055"
TooltipStyleFg = "#FFFFFFFF"
TooltipStyleBg = "#303030C0"
BackgroundColor = "#244D75FF"
ScrollbarColor = "#FFFFFF80"
UIAtlas = "../ui_atlas"
# Colors are either in the format "#RGBA" or 0xABGR (e.g. green is "#00FF00FF" or 0xFF00FF00)
@ -30,8 +39,17 @@ ItemDownStyleBg = "#2b7b99FF"
ItemDisabledStyleFg = "#EEEEEE80"
ItemDisabledStyleBg = "#1b1c1c55"
HeaderStyleFg = "#FFFFFFFF"
HeaderStyleBg = "#00000000"
InfoStyleFg = "#FFFFFFFF"
InfoStyleBg = "#00000000"
PopupStyleFg = "#FFFFFFFF"
PopupStyleBg = "#0c1d24FF"
PopupHeaderStyleFg = "#FFFFFFFF"
PopupHeaderStyleBg = "#00000000"
CollapsibleHeaderStyleFg = "#FFFFFFFF"
CollapsibleHeaderStyleBg = "#00000055"
TooltipStyleFg = "#FFFFFFFF"
TooltipStyleBg = "#303030C0"
BackgroundColor = "#000000FF"
ScrollbarColor = "#FFFFFF80"
UIAtlas = "../ui_atlas"

View file

@ -19,8 +19,17 @@ ItemDownStyleBg = "#4E433BFF"
ItemDisabledStyleFg = "#EEEEEE80"
ItemDisabledStyleBg = "#00000055"
HeaderStyleFg = "#FFFFFFFF"
HeaderStyleBg = "#00000000"
InfoStyleFg = "#FFFFFFFF"
InfoStyleBg = "#00000000"
PopupStyleFg = "#FFFFFFFF"
PopupStyleBg = "#9498A1FF"
PopupHeaderStyleFg = "#FFFFFFFF"
PopupHeaderStyleBg = "#00000000"
CollapsibleHeaderStyleFg = "#FFFFFFFF"
CollapsibleHeaderStyleBg = "#2D4459B0"
TooltipStyleFg = "#FFFFFFFF"
TooltipStyleBg = "#303030C0"
BackgroundColor = "#122537FF"
ScrollbarColor = "#FFFFFF80"
UIAtlas = "../ui_atlas"

View file

@ -20,8 +20,17 @@ ItemDownStyleBg = "#FFFFFFFF"
ItemDisabledStyleFg = "#FFFFFFC0"
ItemDisabledStyleBg = "#000000FF"
HeaderStyleFg = "#FFFFFFFF"
HeaderStyleBg = "#00000000"
InfoStyleFg = "#FFFFFFFF"
InfoStyleBg = "#00000000"
PopupStyleFg = "#C3D7A4FF"
PopupStyleBg = "#94B185FF"
PopupHeaderStyleFg = "#FFFFFFFF"
PopupHeaderStyleBg = "#00000000"
CollapsibleHeaderStyleFg = "#C3D7A4FF"
CollapsibleHeaderStyleBg = "#000000C0"
TooltipStyleFg = "#FFFFFFFF"
TooltipStyleBg = "#303030C0"
BackgroundColor = "#62865AFF"
ScrollbarColor = "#FFFFFF80"
UIAtlas = "../ui_atlas"