diff --git a/Common/UI/View.cpp b/Common/UI/View.cpp index e69673e711..a0fc9f5aab 100644 --- a/Common/UI/View.cpp +++ b/Common/UI/View.cpp @@ -487,7 +487,7 @@ void Choice::Draw(UIContext &dc) { } if (image_.isValid() && text_.empty()) { - dc.Draw()->DrawImage(image_, bounds_.centerX(), bounds_.centerY(), 1.0f, style.fgColor, ALIGN_CENTER); + dc.Draw()->DrawImageRotated(image_, bounds_.centerX(), bounds_.centerY(), imgScale_, imgRot_, style.fgColor, imgFlipH_); } else { dc.SetFontStyle(dc.theme->uiFont); @@ -498,6 +498,7 @@ void Choice::Draw(UIContext &dc) { const AtlasImage *image = dc.Draw()->GetAtlas()->getImage(image_); paddingX += image->w + 12; availWidth -= image->w + 12; + // TODO: Use scale rotation and flip here as well (DrawImageRotated is always ALIGN_CENTER for now) dc.Draw()->DrawImage(image_, bounds_.x + 6, bounds_.centerY(), 1.0f, 0xFFFFFFFF, ALIGN_LEFT | ALIGN_VCENTER); } @@ -508,7 +509,7 @@ void Choice::Draw(UIContext &dc) { dc.DrawTextRect(text_.c_str(), bounds_, style.fgColor, ALIGN_CENTER | FLAG_WRAP_TEXT); } else { if (rightIconImage_.isValid()) { - dc.Draw()->DrawImage(rightIconImage_, bounds_.x2() - 32 - paddingX, bounds_.centerY(), 0.5f, style.fgColor, ALIGN_CENTER); + dc.Draw()->DrawImageRotated(rightIconImage_, bounds_.x2() - 32 - paddingX, bounds_.centerY(), rightIconScale_, rightIconRot_, style.fgColor, rightIconFlipH_); } Bounds textBounds(bounds_.x + paddingX + textPadding_.left, bounds_.y, availWidth, bounds_.h); dc.DrawTextRect(text_.c_str(), textBounds, style.fgColor, ALIGN_VCENTER | FLAG_WRAP_TEXT); diff --git a/Common/UI/View.h b/Common/UI/View.h index 710c7634ea..2b56716028 100644 --- a/Common/UI/View.h +++ b/Common/UI/View.h @@ -695,6 +695,8 @@ public: : ClickableItem(layoutParams), text_(text), smallText_(smallText), image_(ImageID::invalid()) {} Choice(ImageID image, LayoutParams *layoutParams = nullptr) : ClickableItem(layoutParams), image_(image), rightIconImage_(ImageID::invalid()) {} + Choice(ImageID image, float imgScale, float imgRot, bool imgFlipH = false, LayoutParams *layoutParams = nullptr) + : ClickableItem(layoutParams), image_(image), rightIconImage_(ImageID::invalid()), imgScale_(imgScale), imgRot_(imgRot), imgFlipH_(imgFlipH) {} void Click() override; virtual void HighlightChanged(bool highlighted); @@ -704,7 +706,10 @@ public: virtual void SetCentered(bool c) { centered_ = c; } - virtual void SetIcon(ImageID iconImage) { + virtual void SetIcon(ImageID iconImage, float scale = 1.0f, float rot = 0.0f, bool flipH = false) { + rightIconScale_ = scale; + rightIconRot_ = rot; + rightIconFlipH_ = flipH; rightIconImage_ = iconImage; } @@ -716,10 +721,16 @@ protected: std::string text_; std::string smallText_; ImageID image_; // Centered if no text, on the left if text. - ImageID rightIconImage_ = ImageID::invalid(); // Shows in the right. Only used for the Gold icon on the main menu. + ImageID rightIconImage_ = ImageID::invalid(); // Shows in the right. + float rightIconScale_; + float rightIconRot_; + bool rightIconFlipH_; Padding textPadding_; bool centered_ = false; bool highlighted_ = false; + float imgScale_ = 1.0f; + float imgRot_ = 0.0f; + bool imgFlipH_ = false; private: bool selected_ = false; diff --git a/UI/ComboKeyMappingScreen.cpp b/UI/ComboKeyMappingScreen.cpp index 32a8cda256..931c0b0d9b 100644 --- a/UI/ComboKeyMappingScreen.cpp +++ b/UI/ComboKeyMappingScreen.cpp @@ -32,6 +32,62 @@ #include "UI/ComboKeyMappingScreen.h" +class ButtonShapeScreen : public PopupScreen { +public: + ButtonShapeScreen(std::string title, int *setting) : PopupScreen(title), setting_(setting) {} + + void CreatePopupContents(UI::ViewGroup *parent) override { + using namespace UI; + using namespace CustomKey; + + ScrollView *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 1.0f)); + LinearLayout *items = new LinearLayoutList(ORIENT_VERTICAL); + + for (int i = 0; i < ARRAY_SIZE(comboKeyShapes); ++i) { + Choice *c = items->Add(new Choice(ImageID(comboKeyShapes[i].l), 0.6f, comboKeyShapes[i].r*PI/180, comboKeyShapes[i].f)); + c->OnClick.Add([=](UI::EventParams &e) { + *setting_ = i; + TriggerFinish(DR_OK); + return UI::EVENT_DONE; + }); + } + + scroll->Add(items); + parent->Add(scroll); + } + +private: + int *setting_; +}; + +class ButtonIconScreen : public PopupScreen { +public: + ButtonIconScreen(std::string title, int *setting) : PopupScreen(title), setting_(setting) {} + + void CreatePopupContents(UI::ViewGroup *parent) override { + using namespace UI; + using namespace CustomKey; + + ScrollView *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 1.0f)); + LinearLayout *items = new LinearLayoutList(ORIENT_VERTICAL); + + for (int i = 0; i < ARRAY_SIZE(comboKeyImages); ++i) { + Choice *c = items->Add(new Choice(ImageID(comboKeyImages[i].i), 1.0f, comboKeyImages[i].r*PI/180)); + c->OnClick.Add([=](UI::EventParams &e) { + *setting_ = i; + TriggerFinish(DR_OK); + return UI::EVENT_DONE; + }); + } + + scroll->Add(items); + parent->Add(scroll); + } + +private: + int *setting_; +}; + class ButtonPreview : public UI::View { public: ButtonPreview(ImageID bgImg, ImageID img, float rotationIcon, bool flipShape, float rotationShape, int x, int y) @@ -155,20 +211,27 @@ void ComboKeyScreen::CreateViews() { vertLayout->Add(new ItemHeader(co->T("Button style"))); vertLayout->Add(new CheckBox(show, co->T("Visible"))); - // All icon and name are defined in GamepadEmu.h - static const char *imageNames[ARRAY_SIZE(comboKeyImages)]; - for (int i = 0; i < ARRAY_SIZE(imageNames); ++i) { - imageNames[i] = comboKeyImages[i].n; - } - PopupMultiChoice *icon = vertLayout->Add(new PopupMultiChoice(&(cfg->image), co->T("Icon"), imageNames, 0, ARRAY_SIZE(imageNames), mc->GetName(), screenManager())); - icon->OnChoice.Handle(this, &ComboKeyScreen::onCombo); - - // All shape and name are defined in GamepadEmu.h - static const char *shapeNames[ARRAY_SIZE(comboKeyShapes)]; - for (int i = 0; i < ARRAY_SIZE(shapeNames); ++i) { - shapeNames[i] = comboKeyShapes[i].n; - } - vertLayout->Add(new PopupMultiChoice(&(cfg->shape), co->T("Shape"), shapeNames, 0, ARRAY_SIZE(shapeNames), mc->GetName(), screenManager()))->OnChoice.Handle(this, &ComboKeyScreen::onCombo); + Choice *icon = vertLayout->Add(new Choice(co->T("Icon"))); + icon->SetIcon(ImageID(comboKeyImages[cfg->image].i), 1.0f, comboKeyImages[cfg->image].r*PI/180); // Set right icon on the choice + icon->OnClick.Add([=](UI::EventParams &e) { + auto iconScreen = new ButtonIconScreen(co->T("Icon"), &(cfg->image)); + if (e.v) + iconScreen->SetPopupOrigin(e.v); + + screenManager()->push(iconScreen); + return UI::EVENT_DONE; + }); + + Choice *shape = vertLayout->Add(new Choice(co->T("Shape"))); + shape->SetIcon(ImageID(comboKeyShapes[cfg->shape].l), 0.6f, comboKeyShapes[cfg->shape].r*PI/180, comboKeyShapes[cfg->shape].f); // Set right icon on the choice + shape->OnClick.Add([=](UI::EventParams &e) { + auto shape = new ButtonShapeScreen(co->T("Shape"), &(cfg->shape)); + if (e.v) + shape->SetPopupOrigin(e.v); + + screenManager()->push(shape); + return UI::EVENT_DONE; + }); vertLayout->Add(new ItemHeader(co->T("Button Binding"))); vertLayout->Add(new CheckBox(&(cfg->toggle), co->T("Toggle mode"))); @@ -249,6 +312,11 @@ void ComboKeyScreen::saveArray() { } } +void ComboKeyScreen::dialogFinished(const Screen *dialog, DialogResult result) { + saveArray(); + RecreateViews(); +} + void ComboKeyScreen::onFinish(DialogResult result) { saveArray(); g_Config.Save("ComboKeyScreen::onFinish"); @@ -258,9 +326,3 @@ UI::EventReturn ComboKeyScreen::ChoiceEventHandler::onChoiceClick(UI::EventParam checkbox_->Toggle(); return UI::EVENT_DONE; }; - -UI::EventReturn ComboKeyScreen::onCombo(UI::EventParams &e) { - saveArray(); - CreateViews(); - return UI::EVENT_DONE; -} diff --git a/UI/ComboKeyMappingScreen.h b/UI/ComboKeyMappingScreen.h index aa4fd71a06..4ee477444d 100644 --- a/UI/ComboKeyMappingScreen.h +++ b/UI/ComboKeyMappingScreen.h @@ -32,7 +32,10 @@ public: void CreateViews() override; void onFinish(DialogResult result) override; - UI::EventReturn onCombo(UI::EventParams &e); + +protected: + void dialogFinished(const Screen *dialog, DialogResult result) override; + private: void saveArray(); diff --git a/UI/GamepadEmu.h b/UI/GamepadEmu.h index 6cb7090b62..3b320b3ce8 100644 --- a/UI/GamepadEmu.h +++ b/UI/GamepadEmu.h @@ -212,44 +212,42 @@ protected: namespace CustomKey { // Image list struct keyImage { - const char* n; // UI name ImageID i; // ImageID float r; // Rotation angle in degree }; static const keyImage comboKeyImages[] = { - { "1", ImageID("I_1"), 0.0f }, - { "2", ImageID("I_2"), 0.0f }, - { "3", ImageID("I_3"), 0.0f }, - { "4", ImageID("I_4"), 0.0f }, - { "5", ImageID("I_5"), 0.0f }, - { "6", ImageID("I_6"), 0.0f }, - { "A", ImageID("I_A"), 0.0f }, - { "B", ImageID("I_B"), 0.0f }, - { "C", ImageID("I_C"), 0.0f }, - { "D", ImageID("I_D"), 0.0f }, - { "E", ImageID("I_E"), 0.0f }, - { "F", ImageID("I_F"), 0.0f }, - { "Circle", ImageID("I_CIRCLE"), 0.0f }, - { "Cross", ImageID("I_CROSS"), 0.0f }, - { "Square", ImageID("I_SQUARE"), 0.0f }, - { "Triangle", ImageID("I_TRIANGLE"), 0.0f }, - { "L", ImageID("I_L"), 0.0f }, - { "R", ImageID("I_R"), 0.0f }, - { "Start", ImageID("I_START"), 0.0f }, - { "Select", ImageID("I_SELECT"), 0.0f }, - { "Plus", ImageID("I_CROSS"), 45.0f }, - { "Rhombus", ImageID("I_SQUARE"), 45.0f }, - { "Down Triangle", ImageID("I_TRIANGLE"), 180.0f }, - { "Arrow up", ImageID("I_ARROW"), 90.0f}, - { "Arrow down", ImageID("I_ARROW"), 270.0f}, - { "Arrow left", ImageID("I_ARROW"), 0.0f}, - { "Arrow right", ImageID("I_ARROW"), 180.0f}, - { "Gear", ImageID("I_GEAR"), 0.0f}, + { ImageID("I_1"), 0.0f }, + { ImageID("I_2"), 0.0f }, + { ImageID("I_3"), 0.0f }, + { ImageID("I_4"), 0.0f }, + { ImageID("I_5"), 0.0f }, + { ImageID("I_6"), 0.0f }, + { ImageID("I_A"), 0.0f }, + { ImageID("I_B"), 0.0f }, + { ImageID("I_C"), 0.0f }, + { ImageID("I_D"), 0.0f }, + { ImageID("I_E"), 0.0f }, + { ImageID("I_F"), 0.0f }, + { ImageID("I_CIRCLE"), 0.0f }, + { ImageID("I_CROSS"), 0.0f }, + { ImageID("I_SQUARE"), 0.0f }, + { ImageID("I_TRIANGLE"), 0.0f }, + { ImageID("I_L"), 0.0f }, + { ImageID("I_R"), 0.0f }, + { ImageID("I_START"), 0.0f }, + { ImageID("I_SELECT"), 0.0f }, + { ImageID("I_CROSS"), 45.0f }, + { ImageID("I_SQUARE"), 45.0f }, + { ImageID("I_TRIANGLE"), 180.0f }, + { ImageID("I_ARROW"), 90.0f}, + { ImageID("I_ARROW"), 270.0f}, + { ImageID("I_ARROW"), 0.0f}, + { ImageID("I_ARROW"), 180.0f}, + { ImageID("I_GEAR"), 0.0f}, }; // Shape list struct keyShape { - const char* n; // UI name ImageID i; // ImageID ImageID l; // ImageID line version float r; // Rotation angle in dregree @@ -257,16 +255,16 @@ namespace CustomKey { bool d; // Invert height and width for context dimension (for example for 90 degree rot) }; static const keyShape comboKeyShapes[] = { - { "Circle", ImageID("I_ROUND"), ImageID("I_ROUND_LINE"), 0.0f, false, false }, - { "Rectangle", ImageID("I_RECT"), ImageID("I_RECT_LINE"), 0.0f, false, false }, - { "Vertical Rectangle", ImageID("I_RECT"), ImageID("I_RECT_LINE"), 90.0f, false, true }, - { "L button", ImageID("I_SHOULDER"), ImageID("I_SHOULDER_LINE"), 0.0f, false, false }, - { "R button", ImageID("I_SHOULDER"), ImageID("I_SHOULDER_LINE"), 0.0f, true, false }, - { "Arrow up", ImageID("I_DIR"), ImageID("I_DIR_LINE"), 270.0f, false, true }, - { "Arrow down", ImageID("I_DIR"), ImageID("I_DIR_LINE"), 90.0f, false, true }, - { "Arrow left", ImageID("I_DIR"), ImageID("I_DIR_LINE"), 180.0f, false, false }, - { "Arrow right", ImageID("I_DIR"), ImageID("I_DIR_LINE"), 0.0f, false, false }, - { "Square", ImageID("I_SQUARE_SHAPE"), ImageID("I_SQUARE_SHAPE_LINE"), 0.0f, false, false }, + { ImageID("I_ROUND"), ImageID("I_ROUND_LINE"), 0.0f, false, false }, + { ImageID("I_RECT"), ImageID("I_RECT_LINE"), 0.0f, false, false }, + { ImageID("I_RECT"), ImageID("I_RECT_LINE"), 90.0f, false, true }, + { ImageID("I_SHOULDER"), ImageID("I_SHOULDER_LINE"), 0.0f, false, false }, + { ImageID("I_SHOULDER"), ImageID("I_SHOULDER_LINE"), 0.0f, true, false }, + { ImageID("I_DIR"), ImageID("I_DIR_LINE"), 270.0f, false, true }, + { ImageID("I_DIR"), ImageID("I_DIR_LINE"), 90.0f, false, true }, + { ImageID("I_DIR"), ImageID("I_DIR_LINE"), 180.0f, false, false }, + { ImageID("I_DIR"), ImageID("I_DIR_LINE"), 0.0f, false, false }, + { ImageID("I_SQUARE_SHAPE"), ImageID("I_SQUARE_SHAPE_LINE"), 0.0f, false, false }, }; // Button list diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 5e27198fe9..1baa87abb1 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -1130,7 +1130,7 @@ void MainScreen::CreateViews() { if (!System_GetPropertyBool(SYSPROP_APP_GOLD)) { Choice *gold = rightColumnItems->Add(new Choice(mm->T("Buy PPSSPP Gold"))); gold->OnClick.Handle(this, &MainScreen::OnSupport); - gold->SetIcon(ImageID("I_ICONGOLD")); + gold->SetIcon(ImageID("I_ICONGOLD"), 0.5f); } #if !PPSSPP_PLATFORM(UWP) diff --git a/assets/lang/en_US.ini b/assets/lang/en_US.ini index 9b6e49a58e..a93da6638b 100644 --- a/assets/lang/en_US.ini +++ b/assets/lang/en_US.ini @@ -676,10 +676,6 @@ An.Right = Analog Right An.Up = Analog Up Analog limiter = Analog limiter Analog Stick = Analog stick -Arrow down = Arrow down -Arrow left = Arrow left -Arrow right = Arrow right -Arrow up = Arrow up Audio/Video Recording = Audio/Video recording Auto Analog Rotation (CCW) = Auto analog rotation (CCW) Auto Analog Rotation (CW) = Auto analog rotation (CW) @@ -703,14 +699,11 @@ D-pad up = D-pad up DevMenu = DevMenu Double tap button = Double tap button Down = Dpad Down -Down Triangle = Down Triangle Dpad = Dpad Frame Advance = Frame advance -Gear = Gear Hold = Hold Home = Home L = L -L button = L button Left = Dpad Left Load State = Load state Mute toggle = Mute toggle @@ -719,15 +712,11 @@ None = None Note = Note OpenChat = Open chat Pause = Pause -Plus = Plus R = R -R button = R button RapidFire = Rapid-fire Record = Record -Rectangle = Rectangle Remote hold = Remote hold Rewind = Rewind -Rhombus = Rhombus Right = Dpad Right Right Analog Stick = Right Analog Stick RightAn.Down = RightAn.Down @@ -755,7 +744,6 @@ Toggle mode = Toggle mode Triangle = Triangle Fast-forward = Fast-forward Up = Dpad Up -Vertical Rectangle = Vertical Rectangle Vol + = Vol + Vol - = Vol - Wlan = WLAN