mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 09:39:33 +01:00
Merge pull request #22816 from hrydgard/popup-round-corners
UI: Round corners and a little padding on popups and notifications
This commit is contained in:
9 files changed
+53
-32
No files matched your search
@@ -393,7 +393,8 @@ void UIContext::FillRoundRect(const UI::Drawable &drawable, const Bounds &bounds
|
||||
uidrawbuffer_->DrawRoundRect(bounds, radius, drawable.color, RoundRectStyle::Filled, corners);
|
||||
break;
|
||||
default:
|
||||
// Not supported
|
||||
// Not supported, draw it square.
|
||||
FillRect(drawable, bounds);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ void MeasureNotice(const UIContext &dc, NoticeLevel level, std::string_view text
|
||||
*height = std::max(heightSum, iconH + m) + padding * 2.0f;
|
||||
}
|
||||
|
||||
void RenderNotice(UIContext &dc, Bounds bounds, float height1, NoticeLevel level, std::string_view text, std::string_view details, std::string_view iconName, int align, float alpha, OSDMessageFlags flags, float timeVal, float padding, RoundCorners corners) {
|
||||
void RenderNotice(UIContext &dc, Bounds bounds, float height1, NoticeLevel level, std::string_view text, std::string_view details, std::string_view iconName, int align, float alpha, OSDMessageFlags flags, float timeVal, float padding, float radius, RoundCorners corners) {
|
||||
UI::Drawable background = UI::Drawable(colorAlpha(GetNoticeBackgroundColor(level), alpha));
|
||||
|
||||
dc.SetFontStyle(dc.GetTheme().uiFont);
|
||||
@@ -100,7 +100,7 @@ void RenderNotice(UIContext &dc, Bounds bounds, float height1, NoticeLevel level
|
||||
uint32_t foreGround = whiteAlpha(alpha);
|
||||
|
||||
if (!(flags & OSDMessageFlags::Transparent)) {
|
||||
dc.FillRoundRect(background, bounds, dc.GetTheme().choiceRoundRadius, corners);
|
||||
dc.FillRoundRect(background, bounds, radius, corners);
|
||||
}
|
||||
bounds = bounds.Expand(-padding);
|
||||
|
||||
|
||||
+1
-1
@@ -59,4 +59,4 @@ uint32_t GetNoticeBackgroundColor(NoticeLevel type);
|
||||
// padding is added around the contents, inside the background. Pass the same to both.
|
||||
void MeasureNotice(const UIContext &dc, NoticeLevel level, std::string_view text, std::string_view details, std::string_view iconName, int align, float maxWidth, float *width, float *height, float *height1, float padding = 0.0f);
|
||||
// Doesn't draw a drop shadow, floating notices draw their own.
|
||||
void RenderNotice(UIContext &dc, Bounds bounds, float height1, NoticeLevel level, std::string_view text, std::string_view details, std::string_view iconName, int align, float alpha, OSDMessageFlags flags, float timeVal, float padding = 0.0f, RoundCorners corners = RoundCorners::None);
|
||||
void RenderNotice(UIContext &dc, Bounds bounds, float height1, NoticeLevel level, std::string_view text, std::string_view details, std::string_view iconName, int align, float alpha, OSDMessageFlags flags, float timeVal, float padding = 0.0f, float radius = 0.0f, RoundCorners corners = RoundCorners::All);
|
||||
@@ -192,6 +192,7 @@ void PopupScreen::CreateViews() {
|
||||
// Since we scale a bit, make the dropshadow bleed past the edges.
|
||||
box_->SetDropShadowExpand(std::max(g_display.dp_xres, g_display.dp_yres));
|
||||
box_->SetSpacing(0.0f);
|
||||
box_->SetPadding(Margins(8));
|
||||
|
||||
if (!title_.empty()) {
|
||||
View *title = new PopupHeader(title_);
|
||||
@@ -230,11 +231,16 @@ void PopupScreen::CreateViews() {
|
||||
defaultButton_->OnClick.Handle<UIScreen>(this, &UIScreen::OnOK);
|
||||
}
|
||||
|
||||
// The buttons have margins between them, so round them all.
|
||||
for (int i = 0; i < buttonRow->GetNumSubviews(); i++) {
|
||||
buttonRow->GetViewByIndex(i)->SetRoundCorners(RoundCorners::All);
|
||||
}
|
||||
box_->Add(buttonRow);
|
||||
}
|
||||
|
||||
// The popup layout isn't compatible with round corners.
|
||||
box_->ApplyRoundCorners(RoundCorners::None);
|
||||
box_->SetRoundCorners(RoundCorners::All);
|
||||
// Rounds the top of the header and the bottom of the last view, to match the box.
|
||||
box_->ApplyRoundCorners(RoundCorners::All);
|
||||
}
|
||||
|
||||
void MessagePopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
@@ -654,8 +660,12 @@ void SliderPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
vert->Add(slider_);
|
||||
|
||||
LinearLayout *lin = vert->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(UI::Margins(10, 10))));
|
||||
lin->Add(new Button("", ImageID("I_MINUS"), new LayoutParams(60.0f, 60.0f)))->OnClick.Handle(this, &SliderPopupScreen::OnDecrease);
|
||||
lin->Add(new Button("", ImageID("I_PLUS"), new LayoutParams(60.0f, 60.0f)))->OnClick.Handle(this, &SliderPopupScreen::OnIncrease);
|
||||
Button *decrease = lin->Add(new Button("", ImageID("I_MINUS"), new LayoutParams(60.0f, 60.0f)));
|
||||
decrease->OnClick.Handle(this, &SliderPopupScreen::OnDecrease);
|
||||
decrease->SetRoundCorners();
|
||||
Button *increase = lin->Add(new Button("", ImageID("I_PLUS"), new LayoutParams(60.0f, 60.0f)));
|
||||
increase->OnClick.Handle(this, &SliderPopupScreen::OnIncrease);
|
||||
increase->SetRoundCorners();
|
||||
|
||||
edit_ = new TextEdit("", Title(), "", new LinearLayoutParams(1.0f));
|
||||
edit_->SetMaxLen(16);
|
||||
@@ -670,12 +680,14 @@ void SliderPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
|
||||
if (defaultValue_ != NO_DEFAULT_FLOAT) {
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
lin->Add(new Button(di->T("Reset"), new LayoutParams(WRAP_CONTENT, 60.0f)))->OnClick.Add([=](UI::EventParams &) {
|
||||
Button *reset = lin->Add(new Button(di->T("Reset"), new LayoutParams(WRAP_CONTENT, 60.0f)));
|
||||
reset->OnClick.Add([=](UI::EventParams &) {
|
||||
sliderValue_ = defaultValue_;
|
||||
changing_ = true;
|
||||
UpdateTextBox();
|
||||
changing_ = false;
|
||||
});
|
||||
reset->SetRoundCorners();
|
||||
}
|
||||
|
||||
if (!negativeLabel_.empty())
|
||||
|
||||
@@ -663,6 +663,7 @@ void ListView::CreateAllItems() {
|
||||
OnItemCallback(i, e);
|
||||
});
|
||||
}
|
||||
linLayout_->ApplyRoundCorners();
|
||||
}
|
||||
|
||||
void ListView::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) {
|
||||
|
||||
+5
-4
@@ -734,11 +734,12 @@ void PopupHeader::Draw(UIContext &dc) {
|
||||
}
|
||||
|
||||
// Header background
|
||||
dc.FillRect(dc.GetTheme().popupTitleStyle.background, bounds_);
|
||||
dc.FillRoundRect(dc.GetTheme().popupTitleStyle.background, bounds_, dc.GetTheme().choiceRoundRadius, roundCorners_);
|
||||
// Header title text
|
||||
dc.DrawText(text_, bounds_.x + tx, bounds_.centerY(), dc.GetTheme().popupTitleStyle.fgColor, ALIGN_LEFT | ALIGN_VCENTER);
|
||||
// Underline
|
||||
dc.Draw()->DrawImageCenterTexel(dc.GetTheme().whiteImage, bounds_.x, bounds_.y2()-2, bounds_.x2(), bounds_.y2(), dc.GetTheme().popupTitleStyle.fgColor);
|
||||
|
||||
// Underline. Skipping it with the new style.
|
||||
// dc.Draw()->DrawImageCenterTexel(dc.GetTheme().whiteImage, bounds_.x, bounds_.y2()-2, bounds_.x2(), bounds_.y2(), dc.GetTheme().popupTitleStyle.fgColor);
|
||||
|
||||
if (availableWidth < tw) {
|
||||
dc.PopScissor();
|
||||
@@ -1282,7 +1283,7 @@ void TextEdit::Draw(UIContext &dc) {
|
||||
dc.SetFontStyle(dc.GetTheme().uiFont);
|
||||
|
||||
// TODO: make background themeable?
|
||||
dc.FillRect(HasFocus() ? UI::Drawable(0x80000000) : UI::Drawable(0x30000000), bounds_);
|
||||
dc.FillRoundRect(HasFocus() ? UI::Drawable(0x80000000) : UI::Drawable(0x30000000), bounds_, dc.GetTheme().choiceRoundRadius * 0.5f);
|
||||
dc.PushScissor(textBounds);
|
||||
Bounds origTextBounds = textBounds;
|
||||
uint32_t textColor = popupStyle_ ? dc.GetTheme().popupStyle.fgColor : dc.GetTheme().infoStyle.fgColor;
|
||||
|
||||
@@ -187,7 +187,11 @@ void ViewGroup::Draw(UIContext &dc) {
|
||||
dc.PushScissor(bounds_);
|
||||
}
|
||||
|
||||
dc.FillRect(bg_, bounds_);
|
||||
if (roundCorners_ != RoundCorners::None) {
|
||||
dc.FillRoundRect(bg_, bounds_, dc.GetTheme().choiceRoundRadius, roundCorners_);
|
||||
} else {
|
||||
dc.FillRect(bg_, bounds_);
|
||||
}
|
||||
for (View *view : views_) {
|
||||
if (view->GetVisibility() == V_VISIBLE) {
|
||||
// Check if bounds are in current scissor rectangle.
|
||||
|
||||
+16
-16
@@ -26,6 +26,11 @@ static inline const char *DeNull(const char *ptr) {
|
||||
|
||||
static const float g_atlasIconSize = 36.0f;
|
||||
|
||||
// Inside the background, enough to keep the contents clear of the rounded corners.
|
||||
static float NoticeViewPadding(const UIContext &dc) {
|
||||
return dc.GetTheme().choiceRoundRadius * 0.5f;
|
||||
}
|
||||
|
||||
// Align only matters here for the ASCII-only flag.
|
||||
static void MeasureOSDEntry(const UIContext &dc, const OnScreenDisplay::Entry &entry, int align, float maxWidth, float *width, float *height, float *height1) {
|
||||
if (entry.type == OSDType::ACHIEVEMENT_UNLOCKED) {
|
||||
@@ -34,7 +39,7 @@ static void MeasureOSDEntry(const UIContext &dc, const OnScreenDisplay::Entry &e
|
||||
*width = std::min(maxWidth, 550.0f);
|
||||
*height1 = *height;
|
||||
} else {
|
||||
MeasureNotice(dc, GetNoticeLevel(entry.type), entry.text, entry.text2, entry.iconName, align, maxWidth, width, height, height1);
|
||||
MeasureNotice(dc, GetNoticeLevel(entry.type), entry.text, entry.text2, entry.iconName, align, maxWidth, width, height, height1, NoticeViewPadding(dc));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,13 +54,14 @@ static void RenderOSDEntry(UIContext &dc, const OnScreenDisplay::Entry &entry, B
|
||||
if (!(entry.flags & OSDMessageFlags::Transparent)) {
|
||||
dc.DrawRectDropShadow(bounds, 12.0f, 0.7f * alpha);
|
||||
}
|
||||
RenderNotice(dc, bounds, height1, GetNoticeLevel(entry.type), entry.text, entry.text2, entry.iconName, align, alpha, entry.flags, now - entry.startTime);
|
||||
RenderNotice(dc, bounds, height1, GetNoticeLevel(entry.type), entry.text, entry.text2, entry.iconName, align, alpha, entry.flags, now - entry.startTime, NoticeViewPadding(dc), dc.GetTheme().choiceRoundRadius * 0.75f);
|
||||
}
|
||||
}
|
||||
|
||||
static void RenderOSDProgressBar(UIContext &dc, const OnScreenDisplay::Entry &entry, Bounds bounds, int align, float alpha) {
|
||||
dc.DrawRectDropShadow(bounds, 12.0f, 0.7f * alpha);
|
||||
|
||||
const float radius = dc.GetTheme().choiceRoundRadius * 0.75f;
|
||||
uint32_t backgroundColor = colorAlpha(0x806050, alpha);
|
||||
uint32_t progressBackgroundColor = colorAlpha(0xa08070, alpha);
|
||||
|
||||
@@ -68,20 +74,19 @@ static void RenderOSDProgressBar(UIContext &dc, const OnScreenDisplay::Entry &en
|
||||
float ratio = (float)(entry.progress - entry.minValue) / (float)entry.maxValue;
|
||||
|
||||
Bounds boundLeft = bounds;
|
||||
Bounds boundRight = bounds;
|
||||
|
||||
boundLeft.w *= ratio;
|
||||
boundRight.x += ratio * boundRight.w;
|
||||
boundRight.w *= (1.0f - ratio);
|
||||
|
||||
dc.FillRect(progressBackground, boundLeft);
|
||||
dc.FillRect(background, boundRight);
|
||||
// Clip the progress part, so its rounded corners match the background's at any width.
|
||||
dc.FillRoundRect(background, bounds, radius);
|
||||
dc.PushScissor(boundLeft);
|
||||
dc.FillRoundRect(progressBackground, bounds, radius);
|
||||
dc.PopScissor();
|
||||
} else {
|
||||
// Indeterminate spinner
|
||||
float alpha = cos(time_now_d() * 5.0) * 0.5f + 0.5f;
|
||||
uint32_t pulse = colorBlend(backgroundColor, progressBackgroundColor, alpha);
|
||||
UI::Drawable background = UI::Drawable(pulse);
|
||||
dc.FillRect(background, bounds);
|
||||
dc.FillRoundRect(background, bounds, radius);
|
||||
}
|
||||
|
||||
dc.SetFontStyle(dc.GetTheme().uiFont);
|
||||
@@ -101,7 +106,7 @@ static void RenderLeaderboardTracker(UIContext &dc, const Bounds &bounds, const
|
||||
uint32_t backgroundColor = colorAlpha(0x806050, alpha);
|
||||
UI::Drawable background = UI::Drawable(backgroundColor);
|
||||
dc.DrawRectDropShadow(bounds, 12.0f, 0.7f * alpha);
|
||||
dc.FillRect(background, bounds);
|
||||
dc.FillRoundRect(background, bounds, dc.GetTheme().choiceRoundRadius * 0.75f);
|
||||
dc.SetFontStyle(dc.GetTheme().uiFont);
|
||||
dc.SetFontScale(1.0f, 1.0f);
|
||||
dc.DrawTextShadowRect(text, bounds.Inset(5.0f, 5.0f), colorAlpha(0xFFFFFFFF, alpha), ALIGN_VCENTER | ALIGN_HCENTER);
|
||||
@@ -427,11 +432,6 @@ ViewLayoutMode OSDOverlayScreen::LayoutMode() const {
|
||||
return ViewLayoutMode::ApplyInsets;
|
||||
}
|
||||
|
||||
// Inside the background, enough to keep the contents clear of the rounded corners.
|
||||
static float NoticeViewPadding(const UIContext &dc) {
|
||||
return dc.GetTheme().choiceRoundRadius * 0.5f;
|
||||
}
|
||||
|
||||
NoticeView::NoticeView(NoticeLevel level, std::string_view text, std::string_view detailsText, UI::LayoutParams *layoutParams)
|
||||
: InertView(layoutParams), level_(level), text_(text), detailsText_(detailsText) {
|
||||
if (!layoutParams) {
|
||||
@@ -454,6 +454,6 @@ void NoticeView::GetContentDimensionsBySpec(const UIContext &dc, UI::MeasureSpec
|
||||
void NoticeView::Draw(UIContext &dc) {
|
||||
dc.PushScissor(bounds_);
|
||||
const int align = wrapText_ ? FLAG_WRAP_TEXT : 0;
|
||||
RenderNotice(dc, bounds_, height1_, level_, text_, detailsText_, iconName_, align, 1.0f, OSDMessageFlags::None, 0.0f, NoticeViewPadding(dc), roundCorners_);
|
||||
RenderNotice(dc, bounds_, height1_, level_, text_, detailsText_, iconName_, align, 1.0f, OSDMessageFlags::None, 0.0f, NoticeViewPadding(dc), dc.GetTheme().choiceRoundRadius, roundCorners_);
|
||||
dc.PopScissor();
|
||||
}
|
||||
@@ -596,11 +596,13 @@ void RenderAchievement(UIContext &dc, const rc_client_achievement_t *achievement
|
||||
dc.Begin();
|
||||
|
||||
if (style != AchievementRenderStyle::LISTED) {
|
||||
// On-screen notification.
|
||||
dc.DrawRectDropShadow(bounds, 12.0f, 0.7f * alpha);
|
||||
dc.FillRoundRect(background, bounds, dc.GetTheme().choiceRoundRadius * 0.75f);
|
||||
} else {
|
||||
dc.FillRect(background, bounds);
|
||||
}
|
||||
|
||||
dc.FillRect(background, bounds);
|
||||
|
||||
dc.Flush();
|
||||
dc.Begin();
|
||||
|
||||
|
||||
Reference in new issue
Block a user