diff --git a/Common/StringUtils.cpp b/Common/StringUtils.cpp index e812bad1b6..ee4478a5b4 100644 --- a/Common/StringUtils.cpp +++ b/Common/StringUtils.cpp @@ -154,6 +154,23 @@ std::string LineNumberString(const std::string &str) { return output.str(); } +std::string IndentString(const std::string &str, const std::string &sep, bool skipFirst) { + std::stringstream input(str); + std::stringstream output; + std::string line; + + bool doIndent = !skipFirst; + while (std::getline(input, line)) { + if (doIndent) { + output << sep; + } + doIndent = true; + output << line << "\n"; + } + + return output.str(); +} + void SkipSpace(const char **ptr) { while (**ptr && isspace(**ptr)) { (*ptr)++; diff --git a/Common/StringUtils.h b/Common/StringUtils.h index e19d98f879..7a3e879dca 100644 --- a/Common/StringUtils.h +++ b/Common/StringUtils.h @@ -31,6 +31,7 @@ // Useful for shaders with error messages.. std::string LineNumberString(const std::string &str); +std::string IndentString(const std::string &str, const std::string &sep, bool skipFirst = false); // Other simple string utilities. diff --git a/Common/UI/UIScreen.cpp b/Common/UI/UIScreen.cpp index 8e8d447dc9..156eea5c35 100644 --- a/Common/UI/UIScreen.cpp +++ b/Common/UI/UIScreen.cpp @@ -27,9 +27,9 @@ UIScreen::~UIScreen() { } void UIScreen::DoRecreateViews() { - std::lock_guard guard(screenManager()->inputLock_); - if (recreateViews_) { + std::lock_guard guard(screenManager()->inputLock_); + UI::PersistMap persisted; bool persisting = root_ != nullptr; if (persisting) { @@ -144,7 +144,7 @@ bool UIScreen::touch(const TouchInput &touch) { std::vector views; root_->Query(touch.x, touch.y, views); for (auto view : views) { - INFO_LOG(SYSTEM, "%s", view->Describe().c_str()); + INFO_LOG(SYSTEM, "%s", view->DescribeLog().c_str()); } } @@ -655,7 +655,7 @@ void SliderPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { char temp[64]; sprintf(temp, "%d", sliderValue_); - edit_ = new TextEdit(temp, "", new LinearLayoutParams(10.0f)); + edit_ = new TextEdit(temp, Title(), "", new LinearLayoutParams(10.0f)); edit_->SetMaxLen(16); edit_->SetTextColor(dc.theme->popupStyle.fgColor); edit_->SetTextAlign(FLAG_DYNAMIC_ASCII); @@ -689,7 +689,7 @@ void SliderFloatPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { char temp[64]; sprintf(temp, "%0.3f", sliderValue_); - edit_ = new TextEdit(temp, "", new LinearLayoutParams(10.0f)); + edit_ = new TextEdit(temp, Title(), "", new LinearLayoutParams(10.0f)); edit_->SetMaxLen(16); edit_->SetTextColor(dc.theme->popupStyle.fgColor); edit_->SetTextAlign(FLAG_DYNAMIC_ASCII); @@ -818,7 +818,7 @@ void TextEditPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { textEditValue_ = *value_; LinearLayout *lin = parent->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams((UI::Size)300, WRAP_CONTENT))); - edit_ = new TextEdit(textEditValue_, placeholder_, new LinearLayoutParams(1.0f)); + edit_ = new TextEdit(textEditValue_, Title(), placeholder_, new LinearLayoutParams(1.0f)); edit_->SetMaxLen(maxLen_); edit_->SetTextColor(dc.theme->popupStyle.fgColor); lin->Add(edit_); diff --git a/Common/UI/UIScreen.h b/Common/UI/UIScreen.h index aa660b0084..3e1fa8fdc9 100644 --- a/Common/UI/UIScreen.h +++ b/Common/UI/UIScreen.h @@ -88,6 +88,7 @@ protected: virtual bool ShowButtons() const { return true; } virtual bool CanComplete(DialogResult result) { return true; } virtual void OnCompleted(DialogResult result) {} + const std::string &Title() { return title_; } virtual void update() override; diff --git a/Common/UI/View.cpp b/Common/UI/View.cpp index 9c6c1153cf..89c1da4dfb 100644 --- a/Common/UI/View.cpp +++ b/Common/UI/View.cpp @@ -6,6 +6,7 @@ #include "Common/Render/DrawBuffer.h" #include "Common/Render/TextureAtlas.h" #include "Common/Data/Encoding/Utf8.h" +#include "Common/Data/Text/I18n.h" #include "Common/UI/UI.h" #include "Common/UI/View.h" #include "Common/UI/Context.h" @@ -135,7 +136,7 @@ void View::Query(float x, float y, std::vector &list) { } } -std::string View::Describe() const { +std::string View::DescribeLog() const { return StringFromFormat("%0.1f,%0.1f %0.1fx%0.1f", bounds_.x, bounds_.y, bounds_.w, bounds_.h); } @@ -513,6 +514,11 @@ void Choice::Draw(UIContext &dc) { } } +std::string Choice::DescribeText() const { + auto u = GetI18NCategory("UI Elements"); + return ReplaceAll(u->T("%1 choice"), "%1", text_); +} + InfoItem::InfoItem(const std::string &text, const std::string &rightText, LayoutParams *layoutParams) : Item(layoutParams), text_(text), rightText_(rightText) { // We set the colors later once we have a UIContext. @@ -547,6 +553,11 @@ void InfoItem::Draw(UIContext &dc) { // dc.Draw()->DrawImageCenterTexel(dc.theme->whiteImage, bounds_.x, bounds_.y, bounds_.x2(), bounds_.y + 2, dc.theme->itemDownStyle.bgColor); } +std::string InfoItem::DescribeText() const { + auto u = GetI18NCategory("UI Elements"); + return ReplaceAll(ReplaceAll(u->T("%1: %2"), "%1", text_), "%2", rightText_); +} + ItemHeader::ItemHeader(const std::string &text, LayoutParams *layoutParams) : Item(layoutParams), text_(text) { layoutParams_->width = FILL_PARENT; @@ -572,6 +583,11 @@ void ItemHeader::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec hor dc.MeasureTextRect(dc.theme->uiFontSmall, 1.0f, 1.0f, text_.c_str(), (int)text_.length(), bounds, &w, &h, ALIGN_LEFT | ALIGN_VCENTER); } +std::string ItemHeader::DescribeText() const { + auto u = GetI18NCategory("UI Elements"); + return ReplaceAll(u->T("%1 heading"), "%1", text_); +} + void PopupHeader::Draw(UIContext &dc) { const float paddingHorizontal = 12; const float availableWidth = bounds_.w - paddingHorizontal * 2; @@ -600,6 +616,11 @@ void PopupHeader::Draw(UIContext &dc) { } } +std::string PopupHeader::DescribeText() const { + auto u = GetI18NCategory("UI Elements"); + return ReplaceAll(u->T("%1 heading"), "%1", text_); +} + void CheckBox::Toggle() { if (toggle_) { *toggle_ = !(*toggle_); @@ -642,6 +663,15 @@ void CheckBox::Draw(UIContext &dc) { dc.SetFontScale(1.0f, 1.0f); } +std::string CheckBox::DescribeText() const { + auto u = GetI18NCategory("UI Elements"); + std::string text = ReplaceAll(u->T("%1 checkbox"), "%1", text_); + if (!smallText_.empty()) { + text += "\n" + smallText_; + } + return text; +} + float CheckBox::CalculateTextScale(const UIContext &dc, float availWidth) const { float actualWidth, actualHeight; Bounds availBounds(0, 0, availWidth, bounds_.h); @@ -705,6 +735,11 @@ void Button::GetContentDimensions(const UIContext &dc, float &w, float &h) const h *= scale_; } +std::string Button::DescribeText() const { + auto u = GetI18NCategory("UI Elements"); + return ReplaceAll(u->T("%1 button"), "%1", GetText()); +} + void Button::Click() { Clickable::Click(); UI::PlayUISound(UI::UISound::CONFIRM); @@ -729,7 +764,7 @@ void Button::Draw(UIContext &dc) { } dc.SetFontStyle(dc.theme->uiFont); dc.SetFontScale(scale_, scale_); - if (imageID_.isValid() && text_.empty()) { + if (imageID_.isValid() && (ignoreText_ || text_.empty())) { dc.Draw()->DrawImage(imageID_, bounds_.centerX(), bounds_.centerY(), scale_, 0xFFFFFFFF, ALIGN_CENTER); } else if (!text_.empty()) { dc.DrawText(text_.c_str(), bounds_.centerX(), bounds_.centerY(), style.fgColor, ALIGN_CENTER); @@ -812,8 +847,8 @@ void TextView::Draw(UIContext &dc) { } } -TextEdit::TextEdit(const std::string &text, const std::string &placeholderText, LayoutParams *layoutParams) - : View(layoutParams), text_(text), undo_(text), placeholderText_(placeholderText), +TextEdit::TextEdit(const std::string &text, const std::string &title, const std::string &placeholderText, LayoutParams *layoutParams) + : View(layoutParams), text_(text), title_(title), undo_(text), placeholderText_(placeholderText), textColor_(0xFFFFFFFF), maxLen_(255) { caret_ = (int)text_.size(); } @@ -861,6 +896,11 @@ void TextEdit::GetContentDimensions(const UIContext &dc, float &w, float &h) con h += 2; } +std::string TextEdit::DescribeText() const { + auto u = GetI18NCategory("UI Elements"); + return ReplaceAll(u->T("%1 text field"), "%1", GetText()); +} + // Handles both windows and unix line endings. static std::string FirstLine(const std::string &text) { size_t pos = text.find("\r\n"); @@ -1037,6 +1077,12 @@ void ProgressBar::Draw(UIContext &dc) { dc.DrawTextRect(temp, bounds_, 0xFFFFFFFF, ALIGN_CENTER); } +std::string ProgressBar::DescribeText() const { + auto u = GetI18NCategory("UI Elements"); + float percent = progress_ * 100.0f; + return ReplaceAll(u->T("Progress: %1%"), "%1", StringFromInt((int)percent)); +} + void Spinner::GetContentDimensions(const UIContext &dc, float &w, float &h) const { w = 48; h = 48; @@ -1181,6 +1227,12 @@ void Slider::Draw(UIContext &dc) { dc.DrawText(temp, bounds_.x2() - 22, bounds_.centerY(), dc.theme->popupStyle.fgColor, ALIGN_CENTER | FLAG_DYNAMIC_ASCII); } +std::string Slider::DescribeText() const { + if (showPercent_) + return StringFromFormat("%i%% / %i%%", *value_, maxValue_); + return StringFromFormat("%i / %i", *value_, maxValue_); +} + void Slider::Update() { View::Update(); if (repeat_ >= 0) { @@ -1291,6 +1343,10 @@ void SliderFloat::Draw(UIContext &dc) { dc.DrawText(temp, bounds_.x2() - 22, bounds_.centerY(), dc.theme->popupStyle.fgColor, ALIGN_CENTER); } +std::string SliderFloat::DescribeText() const { + return StringFromFormat("%0.2f / %0.2f", *value_, maxValue_); +} + void SliderFloat::Update() { View::Update(); if (repeat_ >= 0) { diff --git a/Common/UI/View.h b/Common/UI/View.h index 4f779fa1f4..1d7c2b40d2 100644 --- a/Common/UI/View.h +++ b/Common/UI/View.h @@ -365,7 +365,9 @@ public: // If this view covers these coordinates, it should add itself and its children to the list. virtual void Query(float x, float y, std::vector &list); - virtual std::string Describe() const; + virtual std::string DescribeLog() const; + // Accessible/searchable description. + virtual std::string DescribeText() const { return ""; } virtual void FocusChanged(int focusFlags) {} virtual void PersistData(PersistStatus status, std::string anonId, PersistMap &storage); @@ -514,8 +516,6 @@ class Button : public Clickable { public: Button(const std::string &text, LayoutParams *layoutParams = 0) : Clickable(layoutParams), text_(text), imageID_(ImageID::invalid()) {} - Button(ImageID imageID, LayoutParams *layoutParams = 0) - : Clickable(layoutParams), imageID_(imageID) {} Button(const std::string &text, ImageID imageID, LayoutParams *layoutParams = 0) : Clickable(layoutParams), text_(text), imageID_(imageID) {} @@ -523,6 +523,7 @@ public: void Draw(UIContext &dc) override; void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; const std::string &GetText() const { return text_; } + std::string DescribeText() const override; void SetPadding(int w, int h) { paddingW_ = w; paddingH_ = h; @@ -530,6 +531,9 @@ public: void SetImageID(ImageID imageID) { imageID_ = imageID; } + void SetIgnoreText(bool ignore) { + ignoreText_ = ignore; + } // Needed an extra small button... void SetScale(float f) { @@ -543,6 +547,7 @@ private: int paddingW_ = 16; int paddingH_ = 8; float scale_ = 1.0f; + bool ignoreText_ = false; }; class Slider : public Clickable { @@ -555,6 +560,7 @@ public: step_ = step <= 0 ? 1 : step; } void Draw(UIContext &dc) override; + std::string DescribeText() const override; bool Key(const KeyInput &input) override; void Touch(const TouchInput &input) override; void Update() override; @@ -585,6 +591,7 @@ public: SliderFloat(float *value, float minValue, float maxValue, LayoutParams *layoutParams = 0) : Clickable(layoutParams), value_(value), minValue_(minValue), maxValue_(maxValue), paddingLeft_(5), paddingRight_(70), repeat_(-1) {} void Draw(UIContext &dc) override; + std::string DescribeText() const override; bool Key(const KeyInput &input) override; void Touch(const TouchInput &input) override; void Update() override; @@ -661,6 +668,7 @@ public: virtual void HighlightChanged(bool highlighted); void GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const override; void Draw(UIContext &dc) override; + std::string DescribeText() const override; virtual void SetCentered(bool c) { centered_ = c; } @@ -711,6 +719,7 @@ public: InfoItem(const std::string &text, const std::string &rightText, LayoutParams *layoutParams = nullptr); void Draw(UIContext &dc) override; + std::string DescribeText() const override; // These are focusable so that long lists of them can be keyboard scrolled. bool CanBeFocused() const override { return true; } @@ -737,6 +746,7 @@ class ItemHeader : public Item { public: ItemHeader(const std::string &text, LayoutParams *layoutParams = 0); void Draw(UIContext &dc) override; + std::string DescribeText() const override; void GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const override; private: @@ -751,6 +761,8 @@ public: layoutParams_->height = 64; } void Draw(UIContext &dc) override; + std::string DescribeText() const override; + private: std::string text_; }; @@ -763,6 +775,7 @@ public: } void Draw(UIContext &dc) override; + std::string DescribeText() const override; void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; EventReturn OnClicked(EventParams &e); @@ -803,6 +816,8 @@ public: w = size_; h = size_; } void Draw(UIContext &dc) override {} + std::string DescribeText() const override { return ""; } + private: float size_; }; @@ -820,6 +835,7 @@ public: void SetText(const std::string &text) { text_ = text; } const std::string &GetText() const { return text_; } + std::string DescribeText() const override { return GetText(); } void SetSmall(bool small) { small_ = small; } void SetTextColor(uint32_t color) { textColor_ = color; hasTextColor_ = true; } void SetShadow(bool shadow) { shadow_ = shadow; } @@ -841,7 +857,7 @@ private: class TextEdit : public View { public: - TextEdit(const std::string &text, const std::string &placeholderText, LayoutParams *layoutParams = 0); + TextEdit(const std::string &text, const std::string &title, const std::string &placeholderText, LayoutParams *layoutParams = nullptr); void SetText(const std::string &text) { text_ = text; scrollPos_ = 0; caret_ = (int)text_.size(); } void SetTextColor(uint32_t color) { textColor_ = color; hasTextColor_ = true; } const std::string &GetText() const { return text_; } @@ -850,6 +866,7 @@ public: void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; void Draw(UIContext &dc) override; + std::string DescribeText() const override; bool Key(const KeyInput &key) override; void Touch(const TouchInput &touch) override; @@ -860,6 +877,7 @@ private: void InsertAtCaret(const char *text); std::string text_; + std::string title_; std::string undo_; std::string placeholderText_; uint32_t textColor_; @@ -880,13 +898,15 @@ enum ImageSizeMode { class ImageView : public InertView { public: - ImageView(ImageID atlasImage, ImageSizeMode sizeMode, LayoutParams *layoutParams = 0) - : InertView(layoutParams), atlasImage_(atlasImage), sizeMode_(sizeMode) {} + ImageView(ImageID atlasImage, const std::string &text, ImageSizeMode sizeMode, LayoutParams *layoutParams = 0) + : InertView(layoutParams), text_(text), atlasImage_(atlasImage), sizeMode_(sizeMode) {} void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; void Draw(UIContext &dc) override; + std::string DescribeText() const override { return text_; } private: + std::string text_; ImageID atlasImage_; ImageSizeMode sizeMode_; }; @@ -898,6 +918,7 @@ public: void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; void Draw(UIContext &dc) override; + std::string DescribeText() const override; void SetProgress(float progress) { if (progress > 1.0f) { @@ -922,6 +943,7 @@ public: void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; void Draw(UIContext &dc) override; + std::string DescribeText() const override { return ""; } void SetColor(uint32_t color) { color_ = color; } private: diff --git a/Common/UI/ViewGroup.cpp b/Common/UI/ViewGroup.cpp index f022b6b137..1f8ebd0436 100644 --- a/Common/UI/ViewGroup.cpp +++ b/Common/UI/ViewGroup.cpp @@ -1,8 +1,12 @@ #include +#include #include -#include +#include #include +#include +#include +#include "Common/Data/Text/I18n.h" #include "Common/Input/KeyCodes.h" #include "Common/Math/curves.h" #include "Common/UI/Context.h" @@ -154,6 +158,64 @@ void ViewGroup::Draw(UIContext &dc) { } } +std::string ViewGroup::DescribeText() const { + std::stringstream ss; + bool needNewline = false; + for (View *view : views_) { + if (view->GetVisibility() != V_VISIBLE) + continue; + std::string s = view->DescribeText(); + if (s.empty()) + continue; + + if (needNewline) { + ss << "\n"; + } + ss << s; + needNewline = s[s.length() - 1] != '\n'; + } + return ss.str(); +} + +std::string ViewGroup::DescribeListUnordered(const char *heading) const { + std::stringstream ss; + ss << heading << "\n"; + + bool needNewline = false; + for (View *view : views_) { + if (view->GetVisibility() != V_VISIBLE) + continue; + std::string s = view->DescribeText(); + if (s.empty()) + continue; + + ss << " - " << IndentString(s, " ", true); + } + return ss.str(); +} + +std::string ViewGroup::DescribeListOrdered(const char *heading) const { + std::stringstream ss; + ss << heading << "\n"; + + // This is how much space we need for the highest number. + int sz = (int)floorf(log10f((float)views_.size())) + 1; + std::string indent = " " + std::string(sz, ' '); + + bool needNewline = false; + int n = 1; + for (View *view : views_) { + if (view->GetVisibility() != V_VISIBLE) + continue; + std::string s = view->DescribeText(); + if (s.empty()) + continue; + + ss << std::setw(sz) << n++ << ". " << IndentString(s, indent, true); + } + return ss.str(); +} + void ViewGroup::Update() { View::Update(); for (View *view : views_) { @@ -582,6 +644,11 @@ void LinearLayout::Layout() { } } +std::string LinearLayoutList::DescribeText() const { + auto u = GetI18NCategory("UI Elements"); + return DescribeListOrdered(u->T("List:")); +} + void FrameLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) { if (views_.empty()) { MeasureBySpec(layoutParams_->width, 0.0f, horiz, &measuredWidth_); @@ -1134,6 +1201,11 @@ void GridLayout::Layout() { } } +std::string GridLayoutList::DescribeText() const { + auto u = GetI18NCategory("UI Elements"); + return DescribeListOrdered(u->T("List:")); +} + TabHolder::TabHolder(Orientation orientation, float stripSize, LayoutParams *layoutParams) : LinearLayout(Opposite(orientation), layoutParams), stripSize_(stripSize) { SetSpacing(0.0f); @@ -1354,6 +1426,11 @@ void ChoiceStrip::Draw(UIContext &dc) { } } +std::string ChoiceStrip::DescribeText() const { + auto u = GetI18NCategory("UI Elements"); + return DescribeListUnordered(u->T("Choices:")); +} + StickyChoice *ChoiceStrip::Choice(int index) { if ((size_t)index < views_.size()) return static_cast(views_[index]); @@ -1386,6 +1463,11 @@ void ListView::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) } } +std::string ListView::DescribeText() const { + auto u = GetI18NCategory("UI Elements"); + return DescribeListOrdered(u->T("List:")); +} + EventReturn ListView::OnItemCallback(int num, EventParams &e) { EventParams ev{}; ev.v = nullptr; diff --git a/Common/UI/ViewGroup.h b/Common/UI/ViewGroup.h index 7e093d775b..dfedc175d8 100644 --- a/Common/UI/ViewGroup.h +++ b/Common/UI/ViewGroup.h @@ -80,9 +80,13 @@ public: void Unlock() { modifyLock_.unlock(); } void SetClip(bool clip) { clip_ = clip; } - std::string Describe() const override { return "ViewGroup: " + View::Describe(); } + std::string DescribeLog() const override { return "ViewGroup: " + View::DescribeLog(); } + std::string DescribeText() const override; protected: + std::string DescribeListUnordered(const char *heading) const; + std::string DescribeListOrdered(const char *heading) const; + std::mutex modifyLock_; // Hold this when changing the subviews. std::vector views_; View *defaultFocusView_ = nullptr; @@ -132,7 +136,7 @@ public: void Overflow(bool allow) { overflow_ = allow; } - std::string Describe() const override { return "AnchorLayout: " + View::Describe(); } + std::string DescribeLog() const override { return "AnchorLayout: " + View::DescribeLog(); } private: void MeasureViews(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert); @@ -182,7 +186,7 @@ public: void SetSpacing(float spacing) { spacing_ = spacing; } - std::string Describe() const override { return (orientation_ == ORIENT_HORIZONTAL ? "LinearLayoutHoriz: " : "LinearLayoutVert: ") + View::Describe(); } + std::string DescribeLog() const override { return (orientation_ == ORIENT_HORIZONTAL ? "LinearLayoutHoriz: " : "LinearLayoutVert: ") + View::DescribeLog(); } protected: Orientation orientation_; @@ -191,6 +195,15 @@ private: float spacing_; }; +class LinearLayoutList : public LinearLayout { +public: + LinearLayoutList(Orientation orientation, LayoutParams *layoutParams = nullptr) + : LinearLayout(orientation, layoutParams) { + } + + std::string DescribeText() const override; +}; + // GridLayout is a little different from the Android layout. This one has fixed size // rows and columns. Items are not allowed to deviate from the set sizes. // Initially, only horizontal layout is supported. @@ -212,13 +225,22 @@ public: void Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) override; void Layout() override; - std::string Describe() const override { return "GridLayout: " + View::Describe(); } + std::string DescribeLog() const override { return "GridLayout: " + View::DescribeLog(); } private: GridLayoutSettings settings_; int numColumns_; }; +class GridLayoutList : public GridLayout { +public: + GridLayoutList(GridLayoutSettings settings, LayoutParams *layoutParams = nullptr) + : GridLayout(settings, layoutParams) { + } + + std::string DescribeText() const override; +}; + // A scrollview usually contains just a single child - a linear layout or similar. class ScrollView : public ViewGroup { public: @@ -231,7 +253,7 @@ public: bool Key(const KeyInput &input) override; void Touch(const TouchInput &input) override; void Draw(UIContext &dc) override; - std::string Describe() const override { return "ScrollView: " + View::Describe(); } + std::string DescribeLog() const override { return "ScrollView: " + View::DescribeLog(); } void ScrollTo(float newScrollPos); void ScrollToBottom(); @@ -287,7 +309,8 @@ public: void SetTopTabs(bool tabs) { topTabs_ = tabs; } void Draw(UIContext &dc) override; - std::string Describe() const override { return "ChoiceStrip: " + View::Describe(); } + std::string DescribeLog() const override { return "ChoiceStrip: " + View::DescribeLog(); } + std::string DescribeText() const override; Event OnChoice; @@ -313,7 +336,7 @@ public: void SetCurrentTab(int tab, bool skipTween = false); int GetCurrentTab() const { return currentTab_; } - std::string Describe() const override { return "TabHolder: " + View::Describe(); } + std::string DescribeLog() const override { return "TabHolder: " + View::DescribeLog(); } void PersistData(PersistStatus status, std::string anonId, PersistMap &storage) override; @@ -383,7 +406,8 @@ public: virtual void Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) override; virtual void SetMaxHeight(float mh) { maxHeight_ = mh; } Event OnChoice; - std::string Describe() const override { return "ListView: " + View::Describe(); } + std::string DescribeLog() const override { return "ListView: " + View::DescribeLog(); } + std::string DescribeText() const override; private: void CreateAllItems(); diff --git a/UI/ChatScreen.cpp b/UI/ChatScreen.cpp index c09d92708a..b21d64d27e 100644 --- a/UI/ChatScreen.cpp +++ b/UI/ChatScreen.cpp @@ -22,7 +22,7 @@ void ChatMenu::CreatePopupContents(UI::ViewGroup *parent) { scroll_ = outer->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0))); LinearLayout *bottom = outer->Add(new LinearLayout(ORIENT_HORIZONTAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT))); #if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || defined(SDL) - chatEdit_ = bottom->Add(new TextEdit("", n->T("Chat Here"), new LinearLayoutParams(1.0))); + chatEdit_ = bottom->Add(new TextEdit("", n->T("Chat message"), n->T("Chat Here"), new LinearLayoutParams(1.0))); #if defined(USING_WIN_UI) // freeze the ui when using ctrl + C hotkey need workaround if (g_Config.bBypassOSKWithKeyboard && !g_Config.bFullScreen) { diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index 9226a1831f..0ef83bcf2b 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -243,7 +243,7 @@ void ControlMappingScreen::CreateViews() { rightScroll_ = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f)); rightScroll_->SetTag("ControlMapping"); rightScroll_->SetScrollToTop(false); - LinearLayout *rightColumn = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f)); + LinearLayout *rightColumn = new LinearLayoutList(ORIENT_VERTICAL, new LinearLayoutParams(1.0f)); rightScroll_->Add(rightColumn); root_->Add(leftColumn); @@ -434,6 +434,7 @@ public: xAxis_(xAxis), xDir_(xDir), yAxis_(yAxis), yDir_(yDir) {} void Draw(UIContext &dc) override; + std::string DescribeText() const override { return ""; } void Update() override; void Axis(const AxisInput &input) override { // TODO: Check input.deviceId? diff --git a/UI/CwCheatScreen.cpp b/UI/CwCheatScreen.cpp index 57f0a2ad61..6d95c6a18e 100644 --- a/UI/CwCheatScreen.cpp +++ b/UI/CwCheatScreen.cpp @@ -97,7 +97,7 @@ void CwCheatScreen::CreateViews() { rightScroll_->SetTag("CwCheats"); rightScroll_->SetScrollToTop(false); rightScroll_->ScrollTo(g_Config.fCwCheatScrollPosition); - LinearLayout *rightColumn = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(200, FILL_PARENT, actionMenuMargins)); + LinearLayout *rightColumn = new LinearLayoutList(ORIENT_VERTICAL, new LinearLayoutParams(200, FILL_PARENT, actionMenuMargins)); rightScroll_->Add(rightColumn); rightColumn->Add(new ItemHeader(cw->T("Cheats"))); diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 633ac9c4f7..70b5a16450 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -213,7 +213,7 @@ void LogScreen::CreateViews() { scroll_ = outer->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0))); LinearLayout *bottom = outer->Add(new LinearLayout(ORIENT_HORIZONTAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT))); bottom->Add(new Button(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); - cmdLine_ = bottom->Add(new TextEdit("", "Command Line", new LinearLayoutParams(1.0))); + cmdLine_ = bottom->Add(new TextEdit("", "Command", "Command Line", new LinearLayoutParams(1.0))); cmdLine_->OnEnter.Handle(this, &LogScreen::OnSubmit); bottom->Add(new Button(di->T("Submit")))->OnClick.Handle(this, &LogScreen::OnSubmit); @@ -264,7 +264,7 @@ void LogConfigScreen::CreateViews() { UI::GridLayoutSettings gridsettings(cellSize, 64, 5); gridsettings.fillCells = true; - GridLayout *grid = vert->Add(new GridLayout(gridsettings, new LayoutParams(FILL_PARENT, WRAP_CONTENT))); + GridLayout *grid = vert->Add(new GridLayoutList(gridsettings, new LayoutParams(FILL_PARENT, WRAP_CONTENT))); for (int i = 0; i < LogManager::GetNumChannels(); i++) { LogTypes::LOG_TYPE type = (LogTypes::LOG_TYPE)i; @@ -449,7 +449,7 @@ void SystemInfoScreen::CreateViews() { root_->Add(tabHolder); ViewGroup *deviceSpecsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); deviceSpecsScroll->SetTag("DevSystemInfoDeviceSpecs"); - LinearLayout *deviceSpecs = new LinearLayout(ORIENT_VERTICAL); + LinearLayout *deviceSpecs = new LinearLayoutList(ORIENT_VERTICAL); deviceSpecs->SetSpacing(0); deviceSpecsScroll->Add(deviceSpecs); tabHolder->AddTab(si->T("Device Info"), deviceSpecsScroll); @@ -603,7 +603,7 @@ void SystemInfoScreen::CreateViews() { ViewGroup *buildConfigScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); buildConfigScroll->SetTag("DevSystemInfoBuildConfig"); - LinearLayout *buildConfig = new LinearLayout(ORIENT_VERTICAL); + LinearLayout *buildConfig = new LinearLayoutList(ORIENT_VERTICAL); buildConfig->SetSpacing(0); buildConfigScroll->Add(buildConfig); tabHolder->AddTab(si->T("Build Config"), buildConfigScroll); @@ -641,7 +641,7 @@ void SystemInfoScreen::CreateViews() { ViewGroup *cpuExtensionsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); cpuExtensionsScroll->SetTag("DevSystemInfoCPUExt"); - LinearLayout *cpuExtensions = new LinearLayout(ORIENT_VERTICAL); + LinearLayout *cpuExtensions = new LinearLayoutList(ORIENT_VERTICAL); cpuExtensions->SetSpacing(0); cpuExtensionsScroll->Add(cpuExtensions); @@ -656,7 +656,7 @@ void SystemInfoScreen::CreateViews() { ViewGroup *gpuExtensionsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); gpuExtensionsScroll->SetTag("DevSystemInfoOGLExt"); - LinearLayout *gpuExtensions = new LinearLayout(ORIENT_VERTICAL); + LinearLayout *gpuExtensions = new LinearLayoutList(ORIENT_VERTICAL); gpuExtensions->SetSpacing(0); gpuExtensionsScroll->Add(gpuExtensions); @@ -685,7 +685,7 @@ void SystemInfoScreen::CreateViews() { if (exts.size() > 0) { ViewGroup *eglExtensionsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); eglExtensionsScroll->SetTag("DevSystemInfoEGLExt"); - LinearLayout *eglExtensions = new LinearLayout(ORIENT_VERTICAL); + LinearLayout *eglExtensions = new LinearLayoutList(ORIENT_VERTICAL); eglExtensions->SetSpacing(0); eglExtensionsScroll->Add(eglExtensions); @@ -835,7 +835,7 @@ void JitCompareScreen::CreateViews() { leftColumn->Add(new Choice(dev->T("Stats")))->OnClick.Handle(this, &JitCompareScreen::OnShowStats); leftColumn->Add(new Choice(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); blockName_ = leftColumn->Add(new TextView(dev->T("No block"))); - blockAddr_ = leftColumn->Add(new TextEdit("", "", new LayoutParams(FILL_PARENT, WRAP_CONTENT))); + blockAddr_ = leftColumn->Add(new TextEdit("", dev->T("Block address"), "", new LayoutParams(FILL_PARENT, WRAP_CONTENT))); blockAddr_->OnTextChange.Handle(this, &JitCompareScreen::OnAddressChange); blockStats_ = leftColumn->Add(new TextView("")); @@ -1095,7 +1095,7 @@ void ShaderListScreen::CreateViews() { layout->Add(new Button(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); for (size_t i = 0; i < ARRAY_SIZE(shaderTypes); i++) { ScrollView *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0)); - LinearLayout *shaderList = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT)); + LinearLayout *shaderList = new LinearLayoutList(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT)); int count = ListShaders(shaderTypes[i].type, shaderList); scroll->Add(shaderList); tabs_->AddTab(StringFromFormat("%s (%d)", shaderTypes[i].name, count), scroll); @@ -1124,7 +1124,7 @@ void ShaderViewScreen::CreateViews() { scroll->SetTag("DevShaderView"); layout->Add(scroll); - LinearLayout *lineLayout = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); + LinearLayout *lineLayout = new LinearLayoutList(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); lineLayout->SetSpacing(0.0); scroll->Add(lineLayout); @@ -1163,7 +1163,7 @@ void FrameDumpTestScreen::CreateViews() { ViewGroup *dumpsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); dumpsScroll->SetTag("GameSettingsGraphics"); - LinearLayout *dumps = new LinearLayout(ORIENT_VERTICAL); + LinearLayout *dumps = new LinearLayoutList(ORIENT_VERTICAL); dumps->SetSpacing(0); dumpsScroll->Add(dumps); tabHolder->AddTab("Dumps", dumps); diff --git a/UI/DisplayLayoutScreen.cpp b/UI/DisplayLayoutScreen.cpp index 95bddf64cd..0ab23394ec 100644 --- a/UI/DisplayLayoutScreen.cpp +++ b/UI/DisplayLayoutScreen.cpp @@ -65,7 +65,9 @@ public: : MultiTouchDisplay(img, scale, new UI::AnchorLayoutParams(x * screenBounds.w, y * screenBounds.h, UI::NONE, UI::NONE, true)), x_(x), y_(y), screenBounds_(screenBounds) { UpdateScale(scale); - } + } + + std::string DescribeText() const override; void SaveDisplayPosition() { x_ = bounds_.centerX() / screenBounds_.w; @@ -84,6 +86,11 @@ private: const Bounds &screenBounds_; }; +std::string DragDropDisplay::DescribeText() const { + auto u = GetI18NCategory("UI Elements"); + return u->T("Screen representation"); +} + DisplayLayoutScreen::DisplayLayoutScreen() { // Ignore insets - just couldn't get the logic to work. ignoreInsets_ = true; @@ -219,6 +226,10 @@ public: Boundary(UI::LayoutParams *layoutParams) : UI::View(layoutParams) { } + std::string DescribeText() const override { + return ""; + } + void Draw(UIContext &dc) override { dc.Draw()->DrawImageCenterTexel(dc.theme->whiteImage, bounds_.x, bounds_.y, bounds_.x2(), bounds_.y2(), dc.theme->itemDownStyle.background.color); } diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 58378d8b81..61c4c6b333 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1002,6 +1002,10 @@ public: } } + std::string DescribeText() const override { + return ""; + } + void SetColor(uint32_t c) { color_ = c; } diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 413dbd820b..21343aac6c 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -216,7 +216,7 @@ void GameSettingsScreen::CreateViews() { // Graphics ViewGroup *graphicsSettingsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); graphicsSettingsScroll->SetTag("GameSettingsGraphics"); - LinearLayout *graphicsSettings = new LinearLayout(ORIENT_VERTICAL); + LinearLayout *graphicsSettings = new LinearLayoutList(ORIENT_VERTICAL); graphicsSettings->SetSpacing(0); graphicsSettingsScroll->Add(graphicsSettings); tabHolder->AddTab(ms->T("Graphics"), graphicsSettingsScroll); @@ -589,7 +589,7 @@ void GameSettingsScreen::CreateViews() { // Audio ViewGroup *audioSettingsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); audioSettingsScroll->SetTag("GameSettingsAudio"); - LinearLayout *audioSettings = new LinearLayout(ORIENT_VERTICAL); + LinearLayout *audioSettings = new LinearLayoutList(ORIENT_VERTICAL); audioSettings->SetSpacing(0); audioSettingsScroll->Add(audioSettings); tabHolder->AddTab(ms->T("Audio"), audioSettingsScroll); @@ -641,7 +641,7 @@ void GameSettingsScreen::CreateViews() { // Control ViewGroup *controlsSettingsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); controlsSettingsScroll->SetTag("GameSettingsControls"); - LinearLayout *controlsSettings = new LinearLayout(ORIENT_VERTICAL); + LinearLayout *controlsSettings = new LinearLayoutList(ORIENT_VERTICAL); controlsSettings->SetSpacing(0); controlsSettingsScroll->Add(controlsSettings); tabHolder->AddTab(ms->T("Controls"), controlsSettingsScroll); @@ -752,7 +752,7 @@ void GameSettingsScreen::CreateViews() { ViewGroup *networkingSettingsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); networkingSettingsScroll->SetTag("GameSettingsNetworking"); - LinearLayout *networkingSettings = new LinearLayout(ORIENT_VERTICAL); + LinearLayout *networkingSettings = new LinearLayoutList(ORIENT_VERTICAL); networkingSettings->SetSpacing(0); networkingSettingsScroll->Add(networkingSettings); tabHolder->AddTab(ms->T("Networking"), networkingSettingsScroll); @@ -839,7 +839,7 @@ void GameSettingsScreen::CreateViews() { ViewGroup *toolsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); toolsScroll->SetTag("GameSettingsTools"); - LinearLayout *tools = new LinearLayout(ORIENT_VERTICAL); + LinearLayout *tools = new LinearLayoutList(ORIENT_VERTICAL); tools->SetSpacing(0); toolsScroll->Add(tools); tabHolder->AddTab(ms->T("Tools"), toolsScroll); @@ -854,7 +854,7 @@ void GameSettingsScreen::CreateViews() { // System ViewGroup *systemSettingsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); systemSettingsScroll->SetTag("GameSettingsSystem"); - LinearLayout *systemSettings = new LinearLayout(ORIENT_VERTICAL); + LinearLayout *systemSettings = new LinearLayoutList(ORIENT_VERTICAL); systemSettings->SetSpacing(0); systemSettingsScroll->Add(systemSettings); tabHolder->AddTab(ms->T("System"), systemSettingsScroll); @@ -1603,7 +1603,7 @@ void DeveloperToolsScreen::CreateViews() { AddStandardBack(root_); - LinearLayout *list = settingsScroll->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); + LinearLayout *list = settingsScroll->Add(new LinearLayoutList(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); list->SetSpacing(0); list->Add(new ItemHeader(sy->T("General"))); @@ -1802,7 +1802,7 @@ void HostnameSelectScreen::CreatePopupContents(UI::ViewGroup *parent) { LinearLayout *valueRow = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT, Margins(0, 0, 0, 10))); - addrView_ = new TextEdit(*value_, ""); + addrView_ = new TextEdit(*value_, n->T("Hostname"), ""); addrView_->SetTextAlign(FLAG_DYNAMIC_ASCII); valueRow->Add(addrView_); parent->Add(valueRow); diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index 6daf7bcb3c..d38bac4b92 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -18,6 +18,7 @@ #include #include "Common/Data/Color/RGBAUtil.h" +#include "Common/Data/Text/I18n.h" #include "Common/System/Display.h" #include "Common/System/System.h" #include "Common/Render/TextureAtlas.h" @@ -36,7 +37,7 @@ static u32 GetButtonColor() { return g_Config.iTouchButtonStyle != 0 ? 0xFFFFFF : 0xc0b080; } -GamepadView::GamepadView(UI::LayoutParams *layoutParams) : UI::View(layoutParams) { +GamepadView::GamepadView(const char *key, UI::LayoutParams *layoutParams) : UI::View(layoutParams), key_(key) { lastFrameTime_ = time_now_d(); } @@ -53,6 +54,11 @@ void GamepadView::Update() { lastFrameTime_ = now; } +std::string GamepadView::DescribeText() const { + auto co = GetI18NCategory("Controls"); + return co->T(key_); +} + float GamepadView::GetButtonOpacity() { if (coreState != CORE_RUNNING) { return 0.0f; @@ -262,8 +268,8 @@ bool PSPButton::IsDown() { return (__CtrlPeekButtons() & pspButtonBit_) != 0; } -PSPDpad::PSPDpad(ImageID arrowIndex, ImageID arrowDownIndex, ImageID overlayIndex, float scale, float spacing, UI::LayoutParams *layoutParams) - : GamepadView(layoutParams), arrowIndex_(arrowIndex), arrowDownIndex_(arrowDownIndex), overlayIndex_(overlayIndex), +PSPDpad::PSPDpad(ImageID arrowIndex, const char *key, ImageID arrowDownIndex, ImageID overlayIndex, float scale, float spacing, UI::LayoutParams *layoutParams) + : GamepadView(key, layoutParams), arrowIndex_(arrowIndex), arrowDownIndex_(arrowDownIndex), overlayIndex_(overlayIndex), scale_(scale), spacing_(spacing), dragPointerId_(-1), down_(0) { } @@ -391,8 +397,8 @@ void PSPDpad::Draw(UIContext &dc) { } } -PSPStick::PSPStick(ImageID bgImg, ImageID stickImg, ImageID stickDownImg, int stick, float scale, UI::LayoutParams *layoutParams) - : GamepadView(layoutParams), dragPointerId_(-1), bgImg_(bgImg), stickImageIndex_(stickImg), stickDownImg_(stickDownImg), stick_(stick), scale_(scale), centerX_(-1), centerY_(-1) { +PSPStick::PSPStick(ImageID bgImg, const char *key, ImageID stickImg, ImageID stickDownImg, int stick, float scale, UI::LayoutParams *layoutParams) + : GamepadView(key, layoutParams), dragPointerId_(-1), bgImg_(bgImg), stickImageIndex_(stickImg), stickDownImg_(stickDownImg), stick_(stick), scale_(scale), centerX_(-1), centerY_(-1) { stick_size_ = 50; } @@ -494,8 +500,8 @@ void PSPStick::ProcessTouch(float x, float y, bool down) { } } -PSPCustomStick::PSPCustomStick(ImageID bgImg, ImageID stickImg, ImageID stickDownImg, float scale, UI::LayoutParams *layoutParams) - : PSPStick(bgImg, stickImg, stickDownImg, -1, scale, layoutParams) { +PSPCustomStick::PSPCustomStick(ImageID bgImg, const char *key, ImageID stickImg, ImageID stickDownImg, float scale, UI::LayoutParams *layoutParams) + : PSPStick(bgImg, key, stickImg, stickDownImg, -1, scale, layoutParams) { } void PSPCustomStick::Draw(UIContext &dc) { @@ -769,49 +775,49 @@ UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause) { const ImageID stickBg = g_Config.iTouchButtonStyle ? ImageID("I_STICK_BG_LINE") : ImageID("I_STICK_BG"); static const ImageID comboKeyImages[5] = { ImageID("I_1"), ImageID("I_2"), ImageID("I_3"), ImageID("I_4"), ImageID("I_5") }; - auto addPSPButton = [=](int buttonBit, ImageID bgImg, ImageID bgDownImg, ImageID img, const ConfigTouchPos &touch, ButtonOffset off = { 0, 0 }) -> PSPButton * { + auto addPSPButton = [=](int buttonBit, const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, const ConfigTouchPos &touch, ButtonOffset off = { 0, 0 }) -> PSPButton * { if (touch.show) { - return root->Add(new PSPButton(buttonBit, bgImg, bgDownImg, img, touch.scale, buttonLayoutParams(touch, off))); + return root->Add(new PSPButton(buttonBit, key, bgImg, bgDownImg, img, touch.scale, buttonLayoutParams(touch, off))); } return nullptr; }; - auto addComboKey = [=](int buttonBit, bool toggle, ImageID bgImg, ImageID bgDownImg, ImageID img, const ConfigTouchPos &touch) -> ComboKey * { + auto addComboKey = [=](int buttonBit, const char *key, bool toggle, ImageID bgImg, ImageID bgDownImg, ImageID img, const ConfigTouchPos &touch) -> ComboKey * { if (touch.show) { - return root->Add(new ComboKey(buttonBit, toggle, bgImg, bgDownImg, img, touch.scale, buttonLayoutParams(touch))); + return root->Add(new ComboKey(buttonBit, key, toggle, bgImg, bgDownImg, img, touch.scale, buttonLayoutParams(touch))); } return nullptr; }; - auto addBoolButton = [=](bool *value, ImageID bgImg, ImageID bgDownImg, ImageID img, const ConfigTouchPos &touch) -> BoolButton * { + auto addBoolButton = [=](bool *value, const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, const ConfigTouchPos &touch) -> BoolButton * { if (touch.show) { - return root->Add(new BoolButton(value, bgImg, bgDownImg, img, touch.scale, buttonLayoutParams(touch))); + return root->Add(new BoolButton(value, key, bgImg, bgDownImg, img, touch.scale, buttonLayoutParams(touch))); } return nullptr; }; - auto addFPSLimitButton = [=](FPSLimit value, ImageID bgImg, ImageID bgDownImg, ImageID img, const ConfigTouchPos &touch) -> FPSLimitButton * { + auto addFPSLimitButton = [=](FPSLimit value, const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, const ConfigTouchPos &touch) -> FPSLimitButton * { if (touch.show) { - return root->Add(new FPSLimitButton(value, bgImg, bgDownImg, img, touch.scale, buttonLayoutParams(touch))); + return root->Add(new FPSLimitButton(value, key, bgImg, bgDownImg, img, touch.scale, buttonLayoutParams(touch))); } return nullptr; }; if (!System_GetPropertyBool(SYSPROP_HAS_BACK_BUTTON) || g_Config.bShowTouchPause) { - root->Add(new BoolButton(pause, roundImage, ImageID("I_ROUND"), ImageID("I_ARROW"), 1.0f, new AnchorLayoutParams(halfW, 20, NONE, NONE, true)))->SetAngle(90); + root->Add(new BoolButton(pause, "Pause button", roundImage, ImageID("I_ROUND"), ImageID("I_ARROW"), 1.0f, new AnchorLayoutParams(halfW, 20, NONE, NONE, true)))->SetAngle(90); } // touchActionButtonCenter.show will always be true, since that's the default. if (g_Config.bShowTouchCircle) - addPSPButton(CTRL_CIRCLE, roundImage, ImageID("I_ROUND"), ImageID("I_CIRCLE"), g_Config.touchActionButtonCenter, circleOffset); + addPSPButton(CTRL_CIRCLE, "Circle button", roundImage, ImageID("I_ROUND"), ImageID("I_CIRCLE"), g_Config.touchActionButtonCenter, circleOffset); if (g_Config.bShowTouchCross) - addPSPButton(CTRL_CROSS, roundImage, ImageID("I_ROUND"), ImageID("I_CROSS"), g_Config.touchActionButtonCenter, crossOffset); + addPSPButton(CTRL_CROSS, "Cross button", roundImage, ImageID("I_ROUND"), ImageID("I_CROSS"), g_Config.touchActionButtonCenter, crossOffset); if (g_Config.bShowTouchTriangle) - addPSPButton(CTRL_TRIANGLE, roundImage, ImageID("I_ROUND"), ImageID("I_TRIANGLE"), g_Config.touchActionButtonCenter, triangleOffset); + addPSPButton(CTRL_TRIANGLE, "Triangle button", roundImage, ImageID("I_ROUND"), ImageID("I_TRIANGLE"), g_Config.touchActionButtonCenter, triangleOffset); if (g_Config.bShowTouchSquare) - addPSPButton(CTRL_SQUARE, roundImage, ImageID("I_ROUND"), ImageID("I_SQUARE"), g_Config.touchActionButtonCenter, squareOffset); + addPSPButton(CTRL_SQUARE, "Square button", roundImage, ImageID("I_ROUND"), ImageID("I_SQUARE"), g_Config.touchActionButtonCenter, squareOffset); - addPSPButton(CTRL_START, rectImage, ImageID("I_RECT"), ImageID("I_START"), g_Config.touchStartKey); - addPSPButton(CTRL_SELECT, rectImage, ImageID("I_RECT"), ImageID("I_SELECT"), g_Config.touchSelectKey); + addPSPButton(CTRL_START, "Start button", rectImage, ImageID("I_RECT"), ImageID("I_START"), g_Config.touchStartKey); + addPSPButton(CTRL_SELECT, "Select button", rectImage, ImageID("I_RECT"), ImageID("I_SELECT"), g_Config.touchSelectKey); - BoolButton *unthrottle = addBoolButton(&PSP_CoreParameter().unthrottle, rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchUnthrottleKey); + BoolButton *unthrottle = addBoolButton(&PSP_CoreParameter().unthrottle, "Unthrottle button", rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchUnthrottleKey); if (unthrottle) { unthrottle->SetAngle(180.0f); unthrottle->OnChange.Add([](UI::EventParams &e) { @@ -823,50 +829,50 @@ UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause) { } if (g_Config.touchRapidFireKey.show) { - auto rapidFire = root->Add(new RapidFireButton(rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchRapidFireKey.scale, buttonLayoutParams(g_Config.touchRapidFireKey))); + auto rapidFire = root->Add(new RapidFireButton("Rapid fire button", rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchRapidFireKey.scale, buttonLayoutParams(g_Config.touchRapidFireKey))); rapidFire->SetAngle(90.0f, 180.0f); } if (g_Config.touchAnalogRotationCWKey.show) { - auto analogRotationCC = root->Add(new AnalogRotationButton(true, rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchAnalogRotationCWKey.scale, buttonLayoutParams(g_Config.touchAnalogRotationCWKey))); + auto analogRotationCC = root->Add(new AnalogRotationButton(true, "Analog clockwise rotation button", rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchAnalogRotationCWKey.scale, buttonLayoutParams(g_Config.touchAnalogRotationCWKey))); analogRotationCC->SetAngle(190.0f, 180.0f); } if (g_Config.touchAnalogRotationCCWKey.show) { - auto analogRotationCCW = root->Add(new AnalogRotationButton(false, rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchAnalogRotationCCWKey.scale, buttonLayoutParams(g_Config.touchAnalogRotationCCWKey))); + auto analogRotationCCW = root->Add(new AnalogRotationButton(false, "Analog counter clockwise rotation button", rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchAnalogRotationCCWKey.scale, buttonLayoutParams(g_Config.touchAnalogRotationCCWKey))); analogRotationCCW->SetAngle(350.0f, 180.0f); } - FPSLimitButton *speed1 = addFPSLimitButton(FPSLimit::CUSTOM1, rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchSpeed1Key); + FPSLimitButton *speed1 = addFPSLimitButton(FPSLimit::CUSTOM1, "Alternate speed 1 button", rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchSpeed1Key); if (speed1) speed1->SetAngle(170.0f, 180.0f); - FPSLimitButton *speed2 = addFPSLimitButton(FPSLimit::CUSTOM2, rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchSpeed2Key); + FPSLimitButton *speed2 = addFPSLimitButton(FPSLimit::CUSTOM2, "Alternate speed 2 button", rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchSpeed2Key); if (speed2) speed2->SetAngle(190.0f, 180.0f); - addPSPButton(CTRL_LTRIGGER, shoulderImage, ImageID("I_SHOULDER"), ImageID("I_L"), g_Config.touchLKey); - PSPButton *rTrigger = addPSPButton(CTRL_RTRIGGER, shoulderImage, ImageID("I_SHOULDER"), ImageID("I_R"), g_Config.touchRKey); + addPSPButton(CTRL_LTRIGGER, "Left shoulder button", shoulderImage, ImageID("I_SHOULDER"), ImageID("I_L"), g_Config.touchLKey); + PSPButton *rTrigger = addPSPButton(CTRL_RTRIGGER, "Right shoulder button", shoulderImage, ImageID("I_SHOULDER"), ImageID("I_R"), g_Config.touchRKey); if (rTrigger) rTrigger->FlipImageH(true); if (g_Config.touchDpad.show) - root->Add(new PSPDpad(dirImage, ImageID("I_DIR"), ImageID("I_ARROW"), g_Config.touchDpad.scale, g_Config.fDpadSpacing, buttonLayoutParams(g_Config.touchDpad))); + root->Add(new PSPDpad(dirImage, "D-pad", ImageID("I_DIR"), ImageID("I_ARROW"), g_Config.touchDpad.scale, g_Config.fDpadSpacing, buttonLayoutParams(g_Config.touchDpad))); if (g_Config.touchAnalogStick.show) - root->Add(new PSPStick(stickBg, stickImage, ImageID("I_STICK"), 0, g_Config.touchAnalogStick.scale, buttonLayoutParams(g_Config.touchAnalogStick))); + root->Add(new PSPStick(stickBg, "Left analog stick", stickImage, ImageID("I_STICK"), 0, g_Config.touchAnalogStick.scale, buttonLayoutParams(g_Config.touchAnalogStick))); if (g_Config.touchRightAnalogStick.show) { if (g_Config.bRightAnalogCustom) - root->Add(new PSPCustomStick(stickBg, stickImage, ImageID("I_STICK"), g_Config.touchRightAnalogStick.scale, buttonLayoutParams(g_Config.touchRightAnalogStick))); + root->Add(new PSPCustomStick(stickBg, "Right analog stick", stickImage, ImageID("I_STICK"), g_Config.touchRightAnalogStick.scale, buttonLayoutParams(g_Config.touchRightAnalogStick))); else - root->Add(new PSPStick(stickBg, stickImage, ImageID("I_STICK"), 1, g_Config.touchRightAnalogStick.scale, buttonLayoutParams(g_Config.touchRightAnalogStick))); + root->Add(new PSPStick(stickBg, "Right analog stick", stickImage, ImageID("I_STICK"), 1, g_Config.touchRightAnalogStick.scale, buttonLayoutParams(g_Config.touchRightAnalogStick))); } - addComboKey(g_Config.iCombokey0, g_Config.bComboToggle0, roundImage, ImageID("I_ROUND"), comboKeyImages[0], g_Config.touchCombo0); - addComboKey(g_Config.iCombokey1, g_Config.bComboToggle1, roundImage, ImageID("I_ROUND"), comboKeyImages[1], g_Config.touchCombo1); - addComboKey(g_Config.iCombokey2, g_Config.bComboToggle2, roundImage, ImageID("I_ROUND"), comboKeyImages[2], g_Config.touchCombo2); - addComboKey(g_Config.iCombokey3, g_Config.bComboToggle3, roundImage, ImageID("I_ROUND"), comboKeyImages[3], g_Config.touchCombo3); - addComboKey(g_Config.iCombokey4, g_Config.bComboToggle4, roundImage, ImageID("I_ROUND"), comboKeyImages[4], g_Config.touchCombo4); + addComboKey(g_Config.iCombokey0, "Combo 1 button", g_Config.bComboToggle0, roundImage, ImageID("I_ROUND"), comboKeyImages[0], g_Config.touchCombo0); + addComboKey(g_Config.iCombokey1, "Combo 2 button", g_Config.bComboToggle1, roundImage, ImageID("I_ROUND"), comboKeyImages[1], g_Config.touchCombo1); + addComboKey(g_Config.iCombokey2, "Combo 3 button", g_Config.bComboToggle2, roundImage, ImageID("I_ROUND"), comboKeyImages[2], g_Config.touchCombo2); + addComboKey(g_Config.iCombokey3, "Combo 4 button", g_Config.bComboToggle3, roundImage, ImageID("I_ROUND"), comboKeyImages[3], g_Config.touchCombo3); + addComboKey(g_Config.iCombokey4, "Combo 5 button", g_Config.bComboToggle4, roundImage, ImageID("I_ROUND"), comboKeyImages[4], g_Config.touchCombo4); return root; } diff --git a/UI/GamepadEmu.h b/UI/GamepadEmu.h index 3cacb147c4..d6fc612a8e 100644 --- a/UI/GamepadEmu.h +++ b/UI/GamepadEmu.h @@ -26,25 +26,27 @@ class GamepadView : public UI::View { public: - GamepadView(UI::LayoutParams *layoutParams); + GamepadView(const char *key, UI::LayoutParams *layoutParams); void Touch(const TouchInput &input) override; bool Key(const KeyInput &input) override { return false; } void Update() override; + std::string DescribeText() const override; protected: virtual float GetButtonOpacity(); + const char *key_; double lastFrameTime_; float secondsWithoutTouch_ = 0.0; }; class MultiTouchButton : public GamepadView { public: - MultiTouchButton(ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) - : GamepadView(layoutParams), scale_(scale), bgImg_(bgImg), bgDownImg_(bgDownImg), img_(img) { + MultiTouchButton(const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) + : GamepadView(key, layoutParams), scale_(scale), bgImg_(bgImg), bgDownImg_(bgDownImg), img_(img) { } void Touch(const TouchInput &input) override; @@ -71,8 +73,8 @@ private: class BoolButton : public MultiTouchButton { public: - BoolButton(bool *value, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) - : MultiTouchButton(bgImg, bgDownImg, img, scale, layoutParams), value_(value) { + BoolButton(bool *value, const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) + : MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), value_(value) { } void Touch(const TouchInput &input) override; @@ -86,8 +88,8 @@ private: class FPSLimitButton : public MultiTouchButton { public: - FPSLimitButton(FPSLimit limit, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) - : MultiTouchButton(bgImg, bgDownImg, img, scale, layoutParams), limit_(limit) { + FPSLimitButton(FPSLimit limit, const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) + : MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), limit_(limit) { } void Touch(const TouchInput &input) override; @@ -99,8 +101,8 @@ private: class RapidFireButton : public MultiTouchButton { public: - RapidFireButton(ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) - : MultiTouchButton(bgImg, bgDownImg, img, scale, layoutParams) { + RapidFireButton(const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) + : MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams) { } void Touch(const TouchInput &input) override; bool IsDown() override; @@ -108,8 +110,8 @@ public: class AnalogRotationButton : public MultiTouchButton { public: - AnalogRotationButton(bool clockWise, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) - : MultiTouchButton(bgImg, bgDownImg, img, scale, layoutParams), clockWise_(clockWise) { + AnalogRotationButton(bool clockWise, const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) + : MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), clockWise_(clockWise) { } void Touch(const TouchInput &input) override; void Update() override; @@ -121,8 +123,8 @@ private: class PSPButton : public MultiTouchButton { public: - PSPButton(int pspButtonBit, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) - : MultiTouchButton(bgImg, bgDownImg, img, scale, layoutParams), pspButtonBit_(pspButtonBit) { + PSPButton(int pspButtonBit, const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) + : MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), pspButtonBit_(pspButtonBit) { } void Touch(const TouchInput &input) override; bool IsDown() override; @@ -133,7 +135,7 @@ private: class PSPDpad : public GamepadView { public: - PSPDpad(ImageID arrowIndex, ImageID arrowDownIndex, ImageID overlayIndex, float scale, float spacing, UI::LayoutParams *layoutParams); + PSPDpad(ImageID arrowIndex, const char *key, ImageID arrowDownIndex, ImageID overlayIndex, float scale, float spacing, UI::LayoutParams *layoutParams); void Touch(const TouchInput &input) override; void Draw(UIContext &dc) override; @@ -154,7 +156,7 @@ private: class PSPStick : public GamepadView { public: - PSPStick(ImageID bgImg, ImageID stickImg, ImageID stickDownImg, int stick, float scale, UI::LayoutParams *layoutParams); + PSPStick(ImageID bgImg, const char *key, ImageID stickImg, ImageID stickDownImg, int stick, float scale, UI::LayoutParams *layoutParams); void Touch(const TouchInput &input) override; void Draw(UIContext &dc) override; @@ -179,7 +181,7 @@ private: class PSPCustomStick : public PSPStick { public: - PSPCustomStick(ImageID bgImg, ImageID stickImg, ImageID stickDownImg, float scale, UI::LayoutParams *layoutParams); + PSPCustomStick(ImageID bgImg, const char *key, ImageID stickImg, ImageID stickDownImg, float scale, UI::LayoutParams *layoutParams); void Touch(const TouchInput &input) override; void Draw(UIContext &dc) override; @@ -201,8 +203,8 @@ const int baseActionButtonSpacing = 60; class ComboKey : public MultiTouchButton { public: - ComboKey(int pspButtonBit, bool toggle, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) - : MultiTouchButton(bgImg, bgDownImg, img, scale, layoutParams), pspButtonBit_(pspButtonBit), toggle_(toggle) { + ComboKey(int pspButtonBit, const char *key, bool toggle, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams) + : MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), pspButtonBit_(pspButtonBit), toggle_(toggle) { } void Touch(const TouchInput &input) override; private: diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index abaec2e11a..116e6cd467 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -119,6 +119,7 @@ public: : UI::Clickable(layoutParams), gridStyle_(gridStyle), gamePath_(gamePath) {} void Draw(UIContext &dc) override; + std::string DescribeText() const override; void GetContentDimensions(const UIContext &dc, float &w, float &h) const override { if (gridStyle_) { w = 144*g_Config.fGameGridScale; @@ -408,6 +409,12 @@ void GameButton::Draw(UIContext &dc) { dc.RebindTexture(); } +std::string GameButton::DescribeText() const { + std::shared_ptr ginfo = g_gameInfoCache->GetInfo(nullptr, gamePath_, 0); + auto u = GetI18NCategory("UI Elements"); + return ReplaceAll(u->T("%1 button"), "%1", ginfo->GetTitle()); +} + class DirButton : public UI::Button { public: DirButton(const std::string &path, bool gridStyle, UI::LayoutParams *layoutParams) @@ -663,17 +670,17 @@ void GameBrowser::Refresh() { Add(topBar); if (*gridStyle_) { - gameList_ = new UI::GridLayout(UI::GridLayoutSettings(150*g_Config.fGameGridScale, 85*g_Config.fGameGridScale), new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); + gameList_ = new UI::GridLayoutList(UI::GridLayoutSettings(150*g_Config.fGameGridScale, 85*g_Config.fGameGridScale), new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); Add(gameList_); } else { - UI::LinearLayout *gl = new UI::LinearLayout(UI::ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); + UI::LinearLayout *gl = new UI::LinearLayoutList(UI::ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); gl->SetSpacing(4.0f); gameList_ = gl; Add(gameList_); } } else { if (*gridStyle_) { - gameList_ = new UI::GridLayout(UI::GridLayoutSettings(150*g_Config.fGameGridScale, 85*g_Config.fGameGridScale), new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); + gameList_ = new UI::GridLayoutList(UI::GridLayoutSettings(150*g_Config.fGameGridScale, 85*g_Config.fGameGridScale), new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); } else { UI::LinearLayout *gl = new UI::LinearLayout(UI::ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); gl->SetSpacing(4.0f); @@ -733,7 +740,7 @@ void GameBrowser::Refresh() { fileInfo.clear(); path_.GetListing(fileInfo, "zip:rar:r01:7z:"); if (!fileInfo.empty()) { - UI::LinearLayout *zl = new UI::LinearLayout(UI::ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); + UI::LinearLayout *zl = new UI::LinearLayoutList(UI::ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); zl->SetSpacing(4.0f); Add(zl); for (size_t i = 0; i < fileInfo.size(); i++) { @@ -1065,15 +1072,17 @@ void MainScreen::CreateViews() { rightColumnItems->SetSpacing(0.0f); AnchorLayout *logos = new AnchorLayout(new AnchorLayoutParams(FILL_PARENT, 60.0f, false)); if (System_GetPropertyBool(SYSPROP_APP_GOLD)) { - logos->Add(new ImageView(ImageID("I_ICONGOLD"), IS_DEFAULT, new AnchorLayoutParams(64, 64, 0, 0, NONE, NONE, false))); + logos->Add(new ImageView(ImageID("I_ICONGOLD"), "", IS_DEFAULT, new AnchorLayoutParams(64, 64, 0, 0, NONE, NONE, false))); } else { - logos->Add(new ImageView(ImageID("I_ICON"), IS_DEFAULT, new AnchorLayoutParams(64, 64, 0, 0, NONE, NONE, false))); + logos->Add(new ImageView(ImageID("I_ICON"), "", IS_DEFAULT, new AnchorLayoutParams(64, 64, 0, 0, NONE, NONE, false))); } - logos->Add(new ImageView(ImageID("I_LOGO"), IS_DEFAULT, new AnchorLayoutParams(180, 64, 64, -5.0f, NONE, NONE, false))); + logos->Add(new ImageView(ImageID("I_LOGO"), "PPSSPP", IS_DEFAULT, new AnchorLayoutParams(180, 64, 64, -5.0f, NONE, NONE, false))); #if !defined(MOBILE_DEVICE) if (!g_Config.bFullScreen) { - fullscreenButton_ = logos->Add(new Button(ImageID(g_Config.bFullScreen ? "I_RESTORE" : "I_FULLSCREEN"), new AnchorLayoutParams(48, 48, NONE, 0, 0, NONE, false))); + auto gr = GetI18NCategory("Graphics"); + fullscreenButton_ = logos->Add(new Button(gr->T("FullScreen", "Full Screen"), ImageID(g_Config.bFullScreen ? "I_RESTORE" : "I_FULLSCREEN"), new AnchorLayoutParams(48, 48, NONE, 0, 0, NONE, false))); + fullscreenButton_->SetIgnoreText(true); fullscreenButton_->OnClick.Handle(this, &MainScreen::OnFullScreenToggle); } #endif @@ -1539,7 +1548,7 @@ void GridSettingsScreen::CreatePopupContents(UI::ViewGroup *parent) { auto sy = GetI18NCategory("System"); ScrollView *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, 50, 1.0f)); - LinearLayout *items = new LinearLayout(ORIENT_VERTICAL); + LinearLayout *items = new LinearLayoutList(ORIENT_VERTICAL); items->Add(new CheckBox(&g_Config.bGridView1, sy->T("Display Recent on a grid"))); items->Add(new CheckBox(&g_Config.bGridView2, sy->T("Display Games on a grid"))); diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index d1937e290d..19bcc038ab 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -589,9 +589,9 @@ void CreditsScreen::CreateViews() { root_->Add(new Button(cr->T("Share PPSSPP"), new AnchorLayoutParams(260, 64, NONE, NONE, 10, rightYOffset + 158, false)))->OnClick.Handle(this, &CreditsScreen::OnShare); #endif if (System_GetPropertyBool(SYSPROP_APP_GOLD)) { - root_->Add(new ImageView(ImageID("I_ICONGOLD"), IS_DEFAULT, new AnchorLayoutParams(100, 64, 10, 10, NONE, NONE, false))); + root_->Add(new ImageView(ImageID("I_ICONGOLD"), "", IS_DEFAULT, new AnchorLayoutParams(100, 64, 10, 10, NONE, NONE, false))); } else { - root_->Add(new ImageView(ImageID("I_ICON"), IS_DEFAULT, new AnchorLayoutParams(100, 64, 10, 10, NONE, NONE, false))); + root_->Add(new ImageView(ImageID("I_ICON"), "", IS_DEFAULT, new AnchorLayoutParams(100, 64, 10, 10, NONE, NONE, false))); } } diff --git a/UI/OnScreenDisplay.cpp b/UI/OnScreenDisplay.cpp index e63eb37d08..1b4700e9f6 100644 --- a/UI/OnScreenDisplay.cpp +++ b/UI/OnScreenDisplay.cpp @@ -1,3 +1,4 @@ +#include #include "UI/OnScreenDisplay.h" #include "Common/Data/Color/RGBAUtil.h" @@ -44,6 +45,18 @@ void OnScreenMessagesView::Draw(UIContext &dc) { osm.Unlock(); } +std::string OnScreenMessagesView::DescribeText() const { + std::stringstream ss; + const auto &messages = osm.Messages(); + for (auto iter = messages.begin(); iter != messages.end(); ++iter) { + if (iter != messages.begin()) { + ss << "\n"; + } + ss << iter->text; + } + return ss.str(); +} + void OnScreenMessages::Clean() { restart: double now = time_now_d(); diff --git a/UI/OnScreenDisplay.h b/UI/OnScreenDisplay.h index 6cb83aa877..75f7e93a83 100644 --- a/UI/OnScreenDisplay.h +++ b/UI/OnScreenDisplay.h @@ -43,6 +43,7 @@ class OnScreenMessagesView : public UI::InertView { public: OnScreenMessagesView(UI::LayoutParams *layoutParams = nullptr) : UI::InertView(layoutParams) {} void Draw(UIContext &dc); + std::string DescribeText() const override; }; extern OnScreenMessages osm; diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index db826278e3..f94559acb3 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -333,7 +333,7 @@ void GamePauseScreen::CreateViews() { ViewGroup *leftColumn = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0, scrollMargins)); root_->Add(leftColumn); - LinearLayout *leftColumnItems = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT)); + LinearLayout *leftColumnItems = new LinearLayoutList(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT)); leftColumn->Add(leftColumnItems); leftColumnItems->Add(new Spacer(0.0)); diff --git a/UI/PauseScreen.h b/UI/PauseScreen.h index 69c84d53af..926302c141 100644 --- a/UI/PauseScreen.h +++ b/UI/PauseScreen.h @@ -69,6 +69,7 @@ public: void GetContentDimensionsBySpec(const UIContext &dc, UI::MeasureSpec horiz, UI::MeasureSpec vert, float &w, float &h) const override; void Draw(UIContext &dc) override; + std::string DescribeText() const override { return text_; } void DeviceLost() override; void DeviceRestored(Draw::DrawContext *draw) override; diff --git a/UI/RemoteISOScreen.cpp b/UI/RemoteISOScreen.cpp index 8dfabde16a..6ce5950fda 100644 --- a/UI/RemoteISOScreen.cpp +++ b/UI/RemoteISOScreen.cpp @@ -593,7 +593,7 @@ void RemoteISOSettingsScreen::CreateViews() { ViewGroup *remoteisoSettingsScroll = new ScrollView(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT)); remoteisoSettingsScroll->SetTag("RemoteISOSettings"); - LinearLayout *remoteisoSettings = new LinearLayout(ORIENT_VERTICAL); + LinearLayout *remoteisoSettings = new LinearLayoutList(ORIENT_VERTICAL); remoteisoSettings->SetSpacing(0); remoteisoSettingsScroll->Add(remoteisoSettings); diff --git a/UI/ReportScreen.cpp b/UI/ReportScreen.cpp index d9bc939df9..a5cf54e098 100644 --- a/UI/ReportScreen.cpp +++ b/UI/ReportScreen.cpp @@ -298,7 +298,7 @@ void ReportScreen::CreateViews() { overallDescription_->SetShadow(true); UI::Orientation ratingsOrient = leftColumnWidth >= 750.0f ? ORIENT_HORIZONTAL : ORIENT_VERTICAL; - UI::LinearLayout *ratingsHolder = new LinearLayout(ratingsOrient, new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT)); + UI::LinearLayout *ratingsHolder = new LinearLayoutList(ratingsOrient, new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT)); leftColumnItems->Add(ratingsHolder); ratingsHolder->Add(new RatingChoice("Graphics", &graphics_))->SetEnabledPtr(&ratingEnabled_)->OnChoice.Handle(this, &ReportScreen::HandleChoice); ratingsHolder->Add(new RatingChoice("Speed", &speed_))->SetEnabledPtr(&ratingEnabled_)->OnChoice.Handle(this, &ReportScreen::HandleChoice); diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index 3d52c42410..72972da1d8 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -135,13 +135,13 @@ private: std::string savePath_; }; -class SortedLinearLayout : public UI::LinearLayout { +class SortedLinearLayout : public UI::LinearLayoutList { public: typedef std::function CompareFunc; typedef std::function DoneFunc; SortedLinearLayout(UI::Orientation orientation, UI::LayoutParams *layoutParams = nullptr) - : UI::LinearLayout(orientation, layoutParams) { + : UI::LinearLayoutList(orientation, layoutParams) { } void SetCompare(CompareFunc lessFunc, DoneFunc doneFunc) { @@ -174,6 +174,7 @@ public: } void Draw(UIContext &dc) override; + std::string DescribeText() const override; void GetContentDimensions(const UIContext &dc, float &w, float &h) const override { w = 500; h = 74; @@ -323,6 +324,11 @@ void SavedataButton::Draw(UIContext &dc) { dc.RebindTexture(); } +std::string SavedataButton::DescribeText() const { + auto u = GetI18NCategory("UI Elements"); + return ReplaceAll(u->T("%1 button"), "%1", title_) + "\n" + subtitle_; +} + SavedataBrowser::SavedataBrowser(std::string path, UI::LayoutParams *layoutParams) : LinearLayout(UI::ORIENT_VERTICAL, layoutParams), path_(path) { Refresh(); diff --git a/UI/Store.cpp b/UI/Store.cpp index b893c48b2d..2ccf72c6a7 100644 --- a/UI/Store.cpp +++ b/UI/Store.cpp @@ -62,6 +62,7 @@ public: void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; void Draw(UIContext &dc) override; + std::string DescribeText() const override { return ""; } void SetFilename(std::string filename); void SetColor(uint32_t color) { color_ = color; } @@ -456,7 +457,7 @@ void StoreScreen::CreateViews() { ScrollView *leftScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(WRAP_CONTENT, FILL_PARENT, 0.4f)); leftScroll->SetTag("StoreMainList"); content->Add(leftScroll); - scrollItemView_ = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT)); + scrollItemView_ = new LinearLayoutList(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT)); leftScroll->Add(scrollItemView_); std::vector entries = FilterEntries(); diff --git a/UI/TextureUtil.h b/UI/TextureUtil.h index 5a4710a65a..e2d0210ae9 100644 --- a/UI/TextureUtil.h +++ b/UI/TextureUtil.h @@ -49,6 +49,7 @@ public: void GetContentDimensions(const UIContext &dc, float &w, float &h) const override; void Draw(UIContext &dc) override; + std::string DescribeText() const override { return ""; } private: std::string gamePath_; diff --git a/UI/TiltAnalogSettingsScreen.cpp b/UI/TiltAnalogSettingsScreen.cpp index e4379606e7..99e2a7a4f6 100644 --- a/UI/TiltAnalogSettingsScreen.cpp +++ b/UI/TiltAnalogSettingsScreen.cpp @@ -29,7 +29,7 @@ void TiltAnalogSettingsScreen::CreateViews() { root_ = new ScrollView(ORIENT_VERTICAL); root_->SetTag("TiltAnalogSettings"); - LinearLayout *settings = new LinearLayout(ORIENT_VERTICAL); + LinearLayout *settings = new LinearLayoutList(ORIENT_VERTICAL); settings->SetSpacing(0); settings->Add(new ItemHeader(co->T("Invert Axes"))); diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index 1c50073232..9a6b7d0615 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -38,8 +38,8 @@ static u32 GetButtonColor() { class DragDropButton : public MultiTouchButton { public: - DragDropButton(ConfigTouchPos &pos, ImageID bgImg, ImageID img, const Bounds &screenBounds) - : MultiTouchButton(bgImg, bgImg, img, pos.scale, new UI::AnchorLayoutParams(pos.x * screenBounds.w, pos.y * screenBounds.h, UI::NONE, UI::NONE, true)), + DragDropButton(ConfigTouchPos &pos, const char *key, ImageID bgImg, ImageID img, const Bounds &screenBounds) + : MultiTouchButton(key, bgImg, bgImg, img, pos.scale, new UI::AnchorLayoutParams(pos.x * screenBounds.w, pos.y * screenBounds.h, UI::NONE, UI::NONE, true)), x_(pos.x), y_(pos.y), theScale_(pos.scale), screenBounds_(screenBounds) { scale_ = theScale_; } @@ -76,8 +76,8 @@ private: class PSPActionButtons : public DragDropButton { public: - PSPActionButtons(ConfigTouchPos &pos, float &spacing, const Bounds &screenBounds) - : DragDropButton(pos, ImageID::invalid(), ImageID::invalid(), screenBounds), spacing_(spacing) { + PSPActionButtons(ConfigTouchPos &pos, const char *key, float &spacing, const Bounds &screenBounds) + : DragDropButton(pos, key, ImageID::invalid(), ImageID::invalid(), screenBounds), spacing_(spacing) { using namespace UI; roundId_ = g_Config.iTouchButtonStyle ? ImageID("I_ROUND_LINE") : ImageID("I_ROUND"); }; @@ -155,8 +155,8 @@ private: class PSPDPadButtons : public DragDropButton { public: - PSPDPadButtons(ConfigTouchPos &pos, float &spacing, const Bounds &screenBounds) - : DragDropButton(pos, ImageID::invalid(), ImageID::invalid(), screenBounds), spacing_(spacing) { + PSPDPadButtons(ConfigTouchPos &pos, const char *key, float &spacing, const Bounds &screenBounds) + : DragDropButton(pos, key, ImageID::invalid(), ImageID::invalid(), screenBounds), spacing_(spacing) { } void Draw(UIContext &dc) override { @@ -221,6 +221,10 @@ public: } } + std::string DescribeText() const override { + return ""; + } + private: int x1, x2, y1, y2; u32 col; @@ -338,7 +342,7 @@ void ControlLayoutView::CreateViews() { // Create all the views. - PSPActionButtons *actionButtons = new PSPActionButtons(g_Config.touchActionButtonCenter, g_Config.fActionButtonSpacing, bounds); + PSPActionButtons *actionButtons = new PSPActionButtons(g_Config.touchActionButtonCenter, "Action buttons", g_Config.fActionButtonSpacing, bounds); actionButtons->setCircleVisibility(g_Config.bShowTouchCircle); actionButtons->setCrossVisibility(g_Config.bShowTouchCross); actionButtons->setTriangleVisibility(g_Config.bShowTouchTriangle); @@ -354,53 +358,53 @@ void ControlLayoutView::CreateViews() { const ImageID comboKeyImages[5] = { ImageID("I_1"), ImageID("I_2"), ImageID("I_3"), ImageID("I_4"), ImageID("I_5") }; - auto addDragDropButton = [&](ConfigTouchPos &pos, ImageID bgImg, ImageID img) { + auto addDragDropButton = [&](ConfigTouchPos &pos, const char *key, ImageID bgImg, ImageID img) { DragDropButton *b = nullptr; if (pos.show) { - b = new DragDropButton(pos, bgImg, img, bounds); + b = new DragDropButton(pos, key, bgImg, img, bounds); controls_.push_back(b); } return b; }; if (g_Config.touchDpad.show) { - controls_.push_back(new PSPDPadButtons(g_Config.touchDpad, g_Config.fDpadSpacing, bounds)); + controls_.push_back(new PSPDPadButtons(g_Config.touchDpad, "D-pad", g_Config.fDpadSpacing, bounds)); } - addDragDropButton(g_Config.touchSelectKey, rectImage, ImageID("I_SELECT")); - addDragDropButton(g_Config.touchStartKey, rectImage, ImageID("I_START")); + addDragDropButton(g_Config.touchSelectKey, "Select button", rectImage, ImageID("I_SELECT")); + addDragDropButton(g_Config.touchStartKey, "Start button", rectImage, ImageID("I_START")); - if (auto *unthrottle = addDragDropButton(g_Config.touchUnthrottleKey, rectImage, ImageID("I_ARROW"))) { + if (auto *unthrottle = addDragDropButton(g_Config.touchUnthrottleKey, "Unthrottle button", rectImage, ImageID("I_ARROW"))) { unthrottle->SetAngle(180.0f); } - if (auto *speed1 = addDragDropButton(g_Config.touchSpeed1Key, rectImage, ImageID("I_ARROW"))) { + if (auto *speed1 = addDragDropButton(g_Config.touchSpeed1Key, "Alternate speed 1 button", rectImage, ImageID("I_ARROW"))) { speed1->SetAngle(170.0f, 180.0f); } - if (auto *speed2 = addDragDropButton(g_Config.touchSpeed2Key, rectImage, ImageID("I_ARROW"))) { + if (auto *speed2 = addDragDropButton(g_Config.touchSpeed2Key, "Alternate speed 2 button", rectImage, ImageID("I_ARROW"))) { speed2->SetAngle(190.0f, 180.0f); } - if (auto *rapidFire = addDragDropButton(g_Config.touchRapidFireKey, rectImage, ImageID("I_ARROW"))) { + if (auto *rapidFire = addDragDropButton(g_Config.touchRapidFireKey, "Rapid fire button", rectImage, ImageID("I_ARROW"))) { rapidFire->SetAngle(90.0f, 180.0f); } - if (auto *analogRotationCW = addDragDropButton(g_Config.touchAnalogRotationCWKey, rectImage, ImageID("I_ARROW"))) { + if (auto *analogRotationCW = addDragDropButton(g_Config.touchAnalogRotationCWKey, "Analog clockwise rotation button", rectImage, ImageID("I_ARROW"))) { analogRotationCW->SetAngle(190.0f, 180.0f); } - if (auto *analogRotationCCW = addDragDropButton(g_Config.touchAnalogRotationCCWKey, rectImage, ImageID("I_ARROW"))) { + if (auto *analogRotationCCW = addDragDropButton(g_Config.touchAnalogRotationCCWKey, "Analog counter clockwise rotation button", rectImage, ImageID("I_ARROW"))) { analogRotationCCW->SetAngle(350.0f, 180.0f); } - addDragDropButton(g_Config.touchLKey, shoulderImage, ImageID("I_L")); - if (auto *rbutton = addDragDropButton(g_Config.touchRKey, shoulderImage, ImageID("I_R"))) { + addDragDropButton(g_Config.touchLKey, "Left shoulder button", shoulderImage, ImageID("I_L")); + if (auto *rbutton = addDragDropButton(g_Config.touchRKey, "Right shoulder button", shoulderImage, ImageID("I_R"))) { rbutton->FlipImageH(true); } - addDragDropButton(g_Config.touchAnalogStick, stickBg, stickImage); - addDragDropButton(g_Config.touchRightAnalogStick, stickBg, stickImage); - addDragDropButton(g_Config.touchCombo0, roundImage, comboKeyImages[0]); - addDragDropButton(g_Config.touchCombo1, roundImage, comboKeyImages[1]); - addDragDropButton(g_Config.touchCombo2, roundImage, comboKeyImages[2]); - addDragDropButton(g_Config.touchCombo3, roundImage, comboKeyImages[3]); - addDragDropButton(g_Config.touchCombo4, roundImage, comboKeyImages[4]); + addDragDropButton(g_Config.touchAnalogStick, "Left analog stick", stickBg, stickImage); + addDragDropButton(g_Config.touchRightAnalogStick, "Right analog stick", stickBg, stickImage); + addDragDropButton(g_Config.touchCombo0, "Combo 1 button", roundImage, comboKeyImages[0]); + addDragDropButton(g_Config.touchCombo1, "Combo 2 button", roundImage, comboKeyImages[1]); + addDragDropButton(g_Config.touchCombo2, "Combo 3 button", roundImage, comboKeyImages[2]); + addDragDropButton(g_Config.touchCombo3, "Combo 4 button", roundImage, comboKeyImages[3]); + addDragDropButton(g_Config.touchCombo4, "Combo 5 button", roundImage, comboKeyImages[4]); for (size_t i = 0; i < controls_.size(); i++) { Add(controls_[i]); diff --git a/UI/TouchControlVisibilityScreen.cpp b/UI/TouchControlVisibilityScreen.cpp index dab63b2940..9a6bf19a49 100644 --- a/UI/TouchControlVisibilityScreen.cpp +++ b/UI/TouchControlVisibilityScreen.cpp @@ -68,7 +68,7 @@ void TouchControlVisibilityScreen::CreateViews() { UI::GridLayoutSettings gridsettings(cellSize, 64, 5); gridsettings.fillCells = true; - GridLayout *grid = vert->Add(new GridLayout(gridsettings, new LayoutParams(FILL_PARENT, WRAP_CONTENT))); + GridLayout *grid = vert->Add(new GridLayoutList(gridsettings, new LayoutParams(FILL_PARENT, WRAP_CONTENT))); static const char* rightAnalogKey = "Right Analog Stick (tap to customize)"; toggles_.clear();