From 4c7bbad89d8bc9ca33d86372cfa7db9fc6bf1097 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 24 Sep 2021 08:09:56 -0700 Subject: [PATCH] UI: Shrink value for all choice variants. --- Common/UI/UIScreen.cpp | 126 +++++++++++++---------------------------- Common/UI/UIScreen.h | 59 ++++++++++++------- 2 files changed, 76 insertions(+), 109 deletions(-) diff --git a/Common/UI/UIScreen.cpp b/Common/UI/UIScreen.cpp index fa8860018d..58a5b41b62 100644 --- a/Common/UI/UIScreen.cpp +++ b/Common/UI/UIScreen.cpp @@ -460,42 +460,30 @@ void PopupMultiChoice::ChoiceCallback(int num) { } } -void PopupMultiChoice::Draw(UIContext &dc) { - Style style = dc.theme->itemStyle; - if (!IsEnabled()) { - style = dc.theme->itemDisabledStyle; - } - int paddingX = 12; - dc.SetFontStyle(dc.theme->uiFont); - - float ignore; - dc.MeasureText(dc.theme->uiFont, 1.0f, 1.0f, valueText_.c_str(), &textPadding_.right, &ignore, ALIGN_RIGHT | ALIGN_VCENTER); - textPadding_.right += paddingX; - - Choice::Draw(dc); - dc.DrawText(valueText_.c_str(), bounds_.x2() - paddingX, bounds_.centerY(), style.fgColor, ALIGN_RIGHT | ALIGN_VCENTER); +std::string PopupMultiChoice::ValueText() const { + return valueText_; } PopupSliderChoice::PopupSliderChoice(int *value, int minValue, int maxValue, const std::string &text, ScreenManager *screenManager, const std::string &units, LayoutParams *layoutParams) - : Choice(text, "", false, layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), step_(1), units_(units), screenManager_(screenManager) { + : AbstractChoiceWithValueDisplay(text, layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), step_(1), units_(units), screenManager_(screenManager) { fmt_ = "%i"; OnClick.Handle(this, &PopupSliderChoice::HandleClick); } PopupSliderChoice::PopupSliderChoice(int *value, int minValue, int maxValue, const std::string &text, int step, ScreenManager *screenManager, const std::string &units, LayoutParams *layoutParams) - : Choice(text, "", false, layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), step_(step), units_(units), screenManager_(screenManager) { + : AbstractChoiceWithValueDisplay(text, layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), step_(step), units_(units), screenManager_(screenManager) { fmt_ = "%i"; OnClick.Handle(this, &PopupSliderChoice::HandleClick); } PopupSliderChoiceFloat::PopupSliderChoiceFloat(float *value, float minValue, float maxValue, const std::string &text, ScreenManager *screenManager, const std::string &units, LayoutParams *layoutParams) - : Choice(text, "", false, layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), step_(1.0f), units_(units), screenManager_(screenManager) { + : AbstractChoiceWithValueDisplay(text, layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), step_(1.0f), units_(units), screenManager_(screenManager) { fmt_ = "%2.2f"; OnClick.Handle(this, &PopupSliderChoiceFloat::HandleClick); } PopupSliderChoiceFloat::PopupSliderChoiceFloat(float *value, float minValue, float maxValue, const std::string &text, float step, ScreenManager *screenManager, const std::string &units, LayoutParams *layoutParams) - : Choice(text, "", false, layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), step_(step), units_(units), screenManager_(screenManager) { + : AbstractChoiceWithValueDisplay(text, layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), step_(step), units_(units), screenManager_(screenManager) { fmt_ = "%2.2f"; OnClick.Handle(this, &PopupSliderChoiceFloat::HandleClick); } @@ -523,14 +511,7 @@ EventReturn PopupSliderChoice::HandleChange(EventParams &e) { return EVENT_DONE; } -void PopupSliderChoice::Draw(UIContext &dc) { - Style style = dc.theme->itemStyle; - if (!IsEnabled()) { - style = dc.theme->itemDisabledStyle; - } - int paddingX = 12; - dc.SetFontStyle(dc.theme->uiFont); - +std::string PopupSliderChoice::ValueText() const { // Always good to have space for Unicode. char temp[256]; if (zeroLabel_.size() && *value_ == 0) { @@ -541,12 +522,7 @@ void PopupSliderChoice::Draw(UIContext &dc) { sprintf(temp, fmt_, *value_); } - float ignore; - dc.MeasureText(dc.theme->uiFont, 1.0f, 1.0f, temp, &textPadding_.right, &ignore, ALIGN_RIGHT | ALIGN_VCENTER); - textPadding_.right += paddingX; - - Choice::Draw(dc); - dc.DrawText(temp, bounds_.x2() - paddingX, bounds_.centerY(), style.fgColor, ALIGN_RIGHT | ALIGN_VCENTER); + return temp; } EventReturn PopupSliderChoiceFloat::HandleClick(EventParams &e) { @@ -570,14 +546,7 @@ EventReturn PopupSliderChoiceFloat::HandleChange(EventParams &e) { return EVENT_DONE; } -void PopupSliderChoiceFloat::Draw(UIContext &dc) { - Style style = dc.theme->itemStyle; - if (!IsEnabled()) { - style = dc.theme->itemDisabledStyle; - } - int paddingX = 12; - dc.SetFontStyle(dc.theme->uiFont); - +std::string PopupSliderChoiceFloat::ValueText() const { char temp[256]; if (zeroLabel_.size() && *value_ == 0.0f) { strcpy(temp, zeroLabel_.c_str()); @@ -585,12 +554,7 @@ void PopupSliderChoiceFloat::Draw(UIContext &dc) { sprintf(temp, fmt_, *value_); } - float ignore; - dc.MeasureText(dc.theme->uiFont, 1.0f, 1.0f, temp, &textPadding_.right, &ignore, ALIGN_RIGHT | ALIGN_VCENTER); - textPadding_.right += paddingX; - - Choice::Draw(dc); - dc.DrawText(temp, bounds_.x2() - paddingX, bounds_.centerY(), style.fgColor, ALIGN_RIGHT | ALIGN_VCENTER); + return temp; } EventReturn SliderPopupScreen::OnDecrease(EventParams ¶ms) { @@ -776,7 +740,7 @@ void SliderFloatPopupScreen::OnCompleted(DialogResult result) { } PopupTextInputChoice::PopupTextInputChoice(std::string *value, const std::string &title, const std::string &placeholder, int maxLen, ScreenManager *screenManager, LayoutParams *layoutParams) -: Choice(title, "", false, layoutParams), screenManager_(screenManager), value_(value), placeHolder_(placeholder), maxLen_(maxLen) { +: AbstractChoiceWithValueDisplay(title, layoutParams), screenManager_(screenManager), value_(value), placeHolder_(placeholder), maxLen_(maxLen) { OnClick.Handle(this, &PopupTextInputChoice::HandleClick); } @@ -791,20 +755,8 @@ EventReturn PopupTextInputChoice::HandleClick(EventParams &e) { return EVENT_DONE; } -void PopupTextInputChoice::Draw(UIContext &dc) { - Style style = dc.theme->itemStyle; - if (!IsEnabled()) { - style = dc.theme->itemDisabledStyle; - } - int paddingX = 12; - dc.SetFontStyle(dc.theme->uiFont); - - float ignore; - dc.MeasureText(dc.theme->uiFont, 1.0f, 1.0f, value_->c_str(), &textPadding_.right, &ignore, ALIGN_RIGHT | ALIGN_VCENTER); - textPadding_.right += paddingX; - - Choice::Draw(dc); - dc.DrawText(value_->c_str(), bounds_.x2() - 12, bounds_.centerY(), style.fgColor, ALIGN_RIGHT | ALIGN_VCENTER); +std::string PopupTextInputChoice::ValueText() const { + return *value_; } EventReturn PopupTextInputChoice::HandleChange(EventParams &e) { @@ -841,7 +793,31 @@ void TextEditPopupScreen::OnCompleted(DialogResult result) { } } -void ChoiceWithValueDisplay::Draw(UIContext &dc) { +void AbstractChoiceWithValueDisplay::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const { + const std::string valueText = ValueText(); + int paddingX = 12; + // Assume we want at least 20% of the size for the label, at a minimum. + float availWidth = (horiz.size - paddingX * 2) * 0.8f; + if (availWidth < 0) { + availWidth = 65535.0f; + } + float scale = CalculateValueScale(dc, valueText, availWidth); + Bounds availBounds(0, 0, availWidth, vert.size); + + float valueW, valueH; + dc.MeasureTextRect(dc.theme->uiFont, scale, scale, valueText.c_str(), (int)valueText.size(), availBounds, &valueW, &valueH, ALIGN_RIGHT | ALIGN_VCENTER | FLAG_WRAP_TEXT); + valueW += paddingX; + + // Give the choice itself less space to grow in, so it shrinks if needed. + MeasureSpec horizLabel = horiz; + horizLabel.size -= valueW; + Choice::GetContentDimensionsBySpec(dc, horiz, vert, w, h); + + w += valueW; + h = std::max(h, valueH); +} + +void AbstractChoiceWithValueDisplay::Draw(UIContext &dc) { Style style = dc.theme->itemStyle; if (!IsEnabled()) { style = dc.theme->itemDisabledStyle; @@ -866,31 +842,7 @@ void ChoiceWithValueDisplay::Draw(UIContext &dc) { dc.SetFontScale(1.0f, 1.0f); } -void ChoiceWithValueDisplay::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const { - int paddingX = 12; - const std::string valueText = ValueText(); - // Assume we want at least 20% of the size for the label, at a minimum. - float availWidth = (horiz.size - paddingX * 2) * 0.8f; - if (availWidth < 0) { - availWidth = 65535.0f; - } - float scale = CalculateValueScale(dc, valueText, availWidth); - Bounds availBounds(0, 0, availWidth, vert.size); - - float valueW, valueH; - dc.MeasureTextRect(dc.theme->uiFont, scale, scale, valueText.c_str(), (int)valueText.size(), availBounds, &valueW, &valueH, ALIGN_RIGHT | ALIGN_VCENTER | FLAG_WRAP_TEXT); - valueW += paddingX; - - // Give the choice itself less space to grow in, so it shrinks if needed. - MeasureSpec horizLabel = horiz; - horizLabel.size -= valueW; - Choice::GetContentDimensionsBySpec(dc, horiz, vert, w, h); - - w += valueW; - h = std::max(h, valueH); -} - -float ChoiceWithValueDisplay::CalculateValueScale(const UIContext &dc, const std::string &valueText, float availWidth) const { +float AbstractChoiceWithValueDisplay::CalculateValueScale(const UIContext &dc, const std::string &valueText, float availWidth) const { float actualWidth, actualHeight; Bounds availBounds(0, 0, availWidth, bounds_.h); dc.MeasureTextRect(dc.theme->uiFont, 1.0f, 1.0f, valueText.c_str(), (int)valueText.size(), availBounds, &actualWidth, &actualHeight); diff --git a/Common/UI/UIScreen.h b/Common/UI/UIScreen.h index fa84538001..173f98249a 100644 --- a/Common/UI/UIScreen.h +++ b/Common/UI/UIScreen.h @@ -246,12 +246,27 @@ private: int maxLen_; }; +class AbstractChoiceWithValueDisplay : public UI::Choice { +public: + AbstractChoiceWithValueDisplay(const std::string &text, LayoutParams *layoutParams = nullptr) + : Choice(text, layoutParams) { + } + + virtual void Draw(UIContext &dc) override; + void GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const; + +protected: + virtual std::string ValueText() const = 0; + + float CalculateValueScale(const UIContext &dc, const std::string &valueText, float availWidth) const; +}; + // Reads and writes value to determine the current selection. -class PopupMultiChoice : public UI::Choice { +class PopupMultiChoice : public AbstractChoiceWithValueDisplay { public: PopupMultiChoice(int *value, const std::string &text, const char **choices, int minVal, int numChoices, const char *category, ScreenManager *screenManager, UI::LayoutParams *layoutParams = nullptr) - : UI::Choice(text, "", false, layoutParams), value_(value), choices_(choices), minVal_(minVal), numChoices_(numChoices), + : AbstractChoiceWithValueDisplay(text, layoutParams), value_(value), choices_(choices), minVal_(minVal), numChoices_(numChoices), category_(category), screenManager_(screenManager) { if (*value >= numChoices + minVal) *value = numChoices + minVal - 1; @@ -261,8 +276,7 @@ public: UpdateText(); } - virtual void Draw(UIContext &dc) override; - virtual void Update() override; + void Update() override; void HideChoice(int c) { hidden_.insert(c); @@ -271,6 +285,8 @@ public: UI::Event OnChoice; protected: + std::string ValueText() const override; + int *value_; const char **choices_; int minVal_; @@ -325,13 +341,11 @@ private: std::string *valueStr_; }; -class PopupSliderChoice : public Choice { +class PopupSliderChoice : public AbstractChoiceWithValueDisplay { public: PopupSliderChoice(int *value, int minValue, int maxValue, const std::string &text, ScreenManager *screenManager, const std::string &units = "", LayoutParams *layoutParams = 0); PopupSliderChoice(int *value, int minValue, int maxValue, const std::string &text, int step, ScreenManager *screenManager, const std::string &units = "", LayoutParams *layoutParams = 0); - virtual void Draw(UIContext &dc) override; - void SetFormat(const char *fmt) { fmt_ = fmt; } @@ -344,6 +358,9 @@ public: Event OnChange; +protected: + std::string ValueText() const override; + private: EventReturn HandleClick(EventParams &e); EventReturn HandleChange(EventParams &e); @@ -360,13 +377,11 @@ private: bool restoreFocus_; }; -class PopupSliderChoiceFloat : public Choice { +class PopupSliderChoiceFloat : public AbstractChoiceWithValueDisplay { public: PopupSliderChoiceFloat(float *value, float minValue, float maxValue, const std::string &text, ScreenManager *screenManager, const std::string &units = "", LayoutParams *layoutParams = 0); PopupSliderChoiceFloat(float *value, float minValue, float maxValue, const std::string &text, float step, ScreenManager *screenManager, const std::string &units = "", LayoutParams *layoutParams = 0); - virtual void Draw(UIContext &dc) override; - void SetFormat(const char *fmt) { fmt_ = fmt; } @@ -376,6 +391,9 @@ public: Event OnChange; +protected: + std::string ValueText() const override; + private: EventReturn HandleClick(EventParams &e); EventReturn HandleChange(EventParams &e); @@ -390,14 +408,15 @@ private: bool restoreFocus_; }; -class PopupTextInputChoice: public Choice { +class PopupTextInputChoice: public AbstractChoiceWithValueDisplay { public: PopupTextInputChoice(std::string *value, const std::string &title, const std::string &placeholder, int maxLen, ScreenManager *screenManager, LayoutParams *layoutParams = 0); - virtual void Draw(UIContext &dc) override; - Event OnChange; +protected: + std::string ValueText() const override; + private: EventReturn HandleClick(EventParams &e); EventReturn HandleChange(EventParams &e); @@ -409,24 +428,20 @@ private: bool restoreFocus_; }; -class ChoiceWithValueDisplay : public UI::Choice { +class ChoiceWithValueDisplay : public AbstractChoiceWithValueDisplay { public: ChoiceWithValueDisplay(int *value, const std::string &text, LayoutParams *layoutParams = 0) - : Choice(text, layoutParams), iValue_(value) {} + : AbstractChoiceWithValueDisplay(text, layoutParams), iValue_(value) {} ChoiceWithValueDisplay(std::string *value, const std::string &text, const char *category, LayoutParams *layoutParams = 0) - : Choice(text, layoutParams), sValue_(value), category_(category) {} + : AbstractChoiceWithValueDisplay(text, layoutParams), sValue_(value), category_(category) {} ChoiceWithValueDisplay(std::string *value, const std::string &text, std::string (*translateCallback)(const char *value), LayoutParams *layoutParams = 0) - : Choice(text, layoutParams), sValue_(value), translateCallback_(translateCallback) { + : AbstractChoiceWithValueDisplay(text, layoutParams), sValue_(value), translateCallback_(translateCallback) { } - void Draw(UIContext &dc) override; - void GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const override; - private: - std::string ValueText() const; - float CalculateValueScale(const UIContext &dc, const std::string &valueText, float availWidth) const; + std::string ValueText() const override; int *iValue_ = nullptr; std::string *sValue_ = nullptr;