mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-22 02:39:05 +02:00
Implement correct word wrapping for popup notices that don't fit on the screen
This commit is contained in:
1 parent
e5bafa4264
commit
56feb8692f
3 files changed
+34
-30
No files matched your search
+31
-28
@@ -68,17 +68,7 @@ static NoticeLevel GetNoticeLevel(OSDType type) {
|
||||
}
|
||||
|
||||
// Align only matters here for the ASCII-only flag.
|
||||
static void MeasureNotice(const UIContext &dc, NoticeLevel level, const std::string &text, const std::string &details, const std::string &iconName, int align, float *width, float *height, float *height1) {
|
||||
dc.MeasureText(dc.GetTheme().uiFont, 1.0f, 1.0f, text, width, height, align);
|
||||
|
||||
*height1 = *height;
|
||||
|
||||
float width2 = 0.0f, height2 = 0.0f;
|
||||
if (!details.empty()) {
|
||||
dc.MeasureText(dc.GetTheme().uiFont, extraTextScale, extraTextScale, details, &width2, &height2, align);
|
||||
*width = std::max(*width, width2);
|
||||
}
|
||||
|
||||
static void MeasureNotice(const UIContext &dc, NoticeLevel level, const std::string &text, const std::string &details, const std::string &iconName, int align, float maxWidth, float *width, float *height, float *height1) {
|
||||
float iconW = 0.0f;
|
||||
float iconH = 0.0f;
|
||||
if (!iconName.empty() && !startsWith(iconName, "I_")) { // Check for atlas image. Bit hacky, but we choose prefixes for icon IDs anyway in a way that this is safe.
|
||||
@@ -96,9 +86,25 @@ static void MeasureNotice(const UIContext &dc, NoticeLevel level, const std::str
|
||||
}
|
||||
}
|
||||
|
||||
iconW += 5.0f;
|
||||
float chromeWidth = iconW + 5.0f + 12.0f;
|
||||
float availableWidth = maxWidth - chromeWidth;
|
||||
|
||||
*width += iconW + 12.0f;
|
||||
// OK, now that we have figured out how much space we have for the text, we can measure it (with wrapping if needed).
|
||||
// We currently don't wrap the title.
|
||||
|
||||
float titleWidth, titleHeight;
|
||||
dc.MeasureText(dc.GetTheme().uiFont, 1.0f, 1.0f, text, &titleWidth, &titleHeight, align);
|
||||
|
||||
*width = std::min(titleWidth, availableWidth);
|
||||
*height1 = titleHeight;
|
||||
|
||||
float width2 = 0.0f, height2 = 0.0f;
|
||||
if (!details.empty()) {
|
||||
dc.MeasureTextRect(dc.GetTheme().uiFont, extraTextScale, extraTextScale, details, availableWidth, &width2, &height2, align | FLAG_WRAP_TEXT);
|
||||
*width = std::max(*width, width2);
|
||||
}
|
||||
|
||||
*width += chromeWidth;
|
||||
if (height2 == 0.0f && iconH < 2.0f * *height1) {
|
||||
// Center vertically using the icon.
|
||||
*height1 = std::max(*height1, iconH + 2.0f);
|
||||
@@ -107,14 +113,14 @@ static void MeasureNotice(const UIContext &dc, NoticeLevel level, const std::str
|
||||
}
|
||||
|
||||
// Align only matters here for the ASCII-only flag.
|
||||
static void MeasureOSDEntry(const UIContext &dc, const OnScreenDisplay::Entry &entry, int align, float *width, float *height, float *height1) {
|
||||
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) {
|
||||
const rc_client_achievement_t *achievement = rc_client_get_achievement_info(Achievements::GetClient(), entry.numericID);
|
||||
MeasureAchievement(dc, achievement, AchievementRenderStyle::UNLOCKED, width, height);
|
||||
*width = 550.0f;
|
||||
*width = std::min(maxWidth, 550.0f);
|
||||
*height1 = *height;
|
||||
} else {
|
||||
MeasureNotice(dc, GetNoticeLevel(entry.type), entry.text, entry.text2, entry.iconName, align, width, height, height1);
|
||||
MeasureNotice(dc, GetNoticeLevel(entry.type), entry.text, entry.text2, entry.iconName, align, maxWidth, width, height, height1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +178,7 @@ static void RenderNotice(UIContext &dc, Bounds bounds, float height1, NoticeLeve
|
||||
Bounds primaryBounds = bounds;
|
||||
primaryBounds.h = height1;
|
||||
|
||||
dc.DrawTextShadowRect(text, primaryBounds.Inset(2.0f, 0.0f, 1.0f, 0.0f), foreGround, (align & FLAG_DYNAMIC_ASCII) | ALIGN_VCENTER);
|
||||
dc.DrawTextShadowRect(text, primaryBounds.Inset(2.0f, 0.0f, 1.0f, 0.0f), foreGround, (align & FLAG_DYNAMIC_ASCII) | ALIGN_VCENTER | FLAG_ELLIPSIZE_TEXT);
|
||||
|
||||
if (!details.empty()) {
|
||||
Bounds bottomTextBounds = bounds.Inset(3.0f, height1 + 5.0f, 3.0f, 3.0f);
|
||||
@@ -181,7 +187,7 @@ static void RenderNotice(UIContext &dc, Bounds bounds, float height1, NoticeLeve
|
||||
dc.FillRect(backgroundDark, bottomTextBounds);
|
||||
}
|
||||
dc.SetFontScale(extraTextScale, extraTextScale);
|
||||
dc.DrawTextRect(details, bottomTextBounds.Inset(1.0f, 1.0f), foreGround, (align & FLAG_DYNAMIC_ASCII) | ALIGN_LEFT);
|
||||
dc.DrawTextRect(details, bottomTextBounds.Inset(1.0f, 1.0f), foreGround, (align & FLAG_DYNAMIC_ASCII) | ALIGN_LEFT | FLAG_WRAP_TEXT);
|
||||
}
|
||||
dc.SetFontScale(1.0f, 1.0f);
|
||||
}
|
||||
@@ -380,14 +386,14 @@ void OnScreenMessagesView::Draw(UIContext &dc) {
|
||||
measuredEntry.style = AchievementRenderStyle::UNLOCKED;
|
||||
MeasureAchievement(dc, achievement, AchievementRenderStyle::UNLOCKED, &measuredEntry.w, &measuredEntry.h);
|
||||
measuredEntry.h1 = measuredEntry.h;
|
||||
measuredEntry.w = 550.0f;
|
||||
measuredEntry.w = std::min(bounds_.w, 550.0f);
|
||||
break;
|
||||
}
|
||||
case OSDType::PROGRESS_BAR:
|
||||
MeasureOSDProgressBar(dc, entry, &measuredEntry.w, &measuredEntry.h);
|
||||
break;
|
||||
default:
|
||||
MeasureOSDEntry(dc, entry, measuredEntry.align, &measuredEntry.w, &measuredEntry.h, &measuredEntry.h1);
|
||||
MeasureOSDEntry(dc, entry, measuredEntry.align, bounds_.w, &measuredEntry.w, &measuredEntry.h, &measuredEntry.h1);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -575,16 +581,13 @@ void OSDOverlayScreen::update() {
|
||||
}
|
||||
|
||||
void NoticeView::GetContentDimensionsBySpec(const UIContext &dc, UI::MeasureSpec horiz, UI::MeasureSpec vert, float &w, float &h) const {
|
||||
Bounds bounds(0, 0, layoutParams_->width, layoutParams_->height);
|
||||
if (bounds.w < 0) {
|
||||
float layoutWidth = layoutParams_->width;
|
||||
if (layoutWidth < 0) {
|
||||
// If there's no size, let's grow as big as we want.
|
||||
bounds.w = horiz.size;
|
||||
layoutWidth = horiz.size;
|
||||
}
|
||||
if (bounds.h < 0) {
|
||||
bounds.h = vert.size;
|
||||
}
|
||||
ApplyBoundsBySpec(bounds, horiz, vert);
|
||||
MeasureNotice(dc, level_, text_, detailsText_, iconName_, 0, &w, &h, &height1_);
|
||||
ApplyBoundBySpec(layoutWidth, horiz);
|
||||
MeasureNotice(dc, level_, text_, detailsText_, iconName_, 0, layoutWidth, &w, &h, &height1_);
|
||||
// Layout hack! Some weird problems with the layout that I can't figure out right now..
|
||||
if (squishy_) {
|
||||
w = 50.0;
|
||||
|
||||
Reference in new issue
Block a user