mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Merge pull request #21041 from hrydgard/control-mappings-ui
Fix touch controls and control mappings UI in portrait
This commit is contained in:
+43
-38
@@ -57,7 +57,7 @@ using KeyMap::MultiInputMapping;
|
||||
|
||||
class SingleControlMapper : public UI::LinearLayout {
|
||||
public:
|
||||
SingleControlMapper(int pspKey, std::string keyName, ScreenManager *scrm, UI::LinearLayoutParams *layoutParams = nullptr);
|
||||
SingleControlMapper(int pspKey, std::string keyName, bool portrait, ScreenManager *scrm, UI::LinearLayoutParams *layoutParams = nullptr);
|
||||
~SingleControlMapper() {
|
||||
g_IsMappingMouseInput = false;
|
||||
}
|
||||
@@ -79,10 +79,11 @@ private:
|
||||
std::vector<UI::View *> rows_;
|
||||
std::string keyName_;
|
||||
ScreenManager *scrm_;
|
||||
bool portrait_;
|
||||
};
|
||||
|
||||
SingleControlMapper::SingleControlMapper(int pspKey, std::string keyName, ScreenManager *scrm, UI::LinearLayoutParams *layoutParams)
|
||||
: UI::LinearLayout(ORIENT_VERTICAL, layoutParams), pspKey_(pspKey), keyName_(keyName), scrm_(scrm) {
|
||||
SingleControlMapper::SingleControlMapper(int pspKey, std::string keyName, bool portrait, ScreenManager *scrm, UI::LinearLayoutParams *layoutParams)
|
||||
: UI::LinearLayout(ORIENT_VERTICAL, layoutParams), pspKey_(pspKey), keyName_(keyName), scrm_(scrm), portrait_(portrait) {
|
||||
Refresh();
|
||||
}
|
||||
|
||||
@@ -106,7 +107,7 @@ void SingleControlMapper::Refresh() {
|
||||
float itemH = 55.0f;
|
||||
|
||||
float leftColumnWidth = 200;
|
||||
float rightColumnWidth = 350; // TODO: Should be flexible somehow. Maybe we need to implement Measure.
|
||||
float rightColumnWidth = 350;
|
||||
|
||||
LinearLayout *root = Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
root->SetSpacing(3.0f);
|
||||
@@ -129,7 +130,7 @@ void SingleControlMapper::Refresh() {
|
||||
p->OnClick.Handle(this, &SingleControlMapper::OnAddMouse);
|
||||
}
|
||||
|
||||
LinearLayout *rightColumn = root->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(rightColumnWidth, WRAP_CONTENT)));
|
||||
LinearLayout *rightColumn = root->Add(new LinearLayout(ORIENT_VERTICAL, portrait_ ? new LinearLayoutParams(1.0f) : new LinearLayoutParams(rightColumnWidth, WRAP_CONTENT)));
|
||||
rightColumn->SetSpacing(2.0f);
|
||||
std::vector<MultiInputMapping> mappings;
|
||||
KeyMap::InputMappingsFromPspButton(pspKey_, &mappings, false);
|
||||
@@ -232,59 +233,63 @@ static const BindingCategory cats[] = {
|
||||
{}, // sentinel
|
||||
};
|
||||
|
||||
void ControlMappingScreen::CreateExtraButtons(UI::ViewGroup *verticalLayout, int margins) {
|
||||
|
||||
void ControlMappingScreen::CreateSettingsViews(UI::ViewGroup *parent) {
|
||||
using namespace UI;
|
||||
auto km = GetI18NCategory(I18NCat::KEYMAPPING);
|
||||
verticalLayout->Add(new Choice(km->T("Clear All")))->OnClick.Add([](UI::EventParams &) {
|
||||
parent->Add(new Choice(km->T("Clear All")))->OnClick.Add([](UI::EventParams &) {
|
||||
KeyMap::ClearAllMappings();
|
||||
});
|
||||
verticalLayout->Add(new Choice(km->T("Default All")))->OnClick.Add([](UI::EventParams &) {
|
||||
parent->Add(new Choice(km->T("Default All")))->OnClick.Add([](UI::EventParams &) {
|
||||
KeyMap::RestoreDefault();
|
||||
});
|
||||
std::string sysName = System_GetProperty(SYSPROP_NAME);
|
||||
// If there's a builtin controller, restore to default should suffice. No need to conf the controller on top.
|
||||
if (!KeyMap::HasBuiltinController(sysName) && KeyMap::GetSeenPads().size()) {
|
||||
verticalLayout->Add(new Choice(km->T("Autoconfigure")))->OnClick.Handle(this, &ControlMappingScreen::OnAutoConfigure);
|
||||
parent->Add(new Choice(km->T("Autoconfigure")))->OnClick.Handle(this, &ControlMappingScreen::OnAutoConfigure);
|
||||
}
|
||||
verticalLayout->Add(new CheckBox(&g_Config.bAllowMappingCombos, km->T("Allow combo mappings")));
|
||||
verticalLayout->Add(new CheckBox(&g_Config.bStrictComboOrder, km->T("Strict combo input order")));
|
||||
verticalLayout->Add(new Spacer(12.0f));
|
||||
parent->Add(new CheckBox(&g_Config.bAllowMappingCombos, km->T("Allow combo mappings")));
|
||||
parent->Add(new CheckBox(&g_Config.bStrictComboOrder, km->T("Strict combo input order")));
|
||||
}
|
||||
|
||||
void ControlMappingScreen::CreateTabs() {
|
||||
std::string_view ControlMappingScreen::GetTitle() const {
|
||||
auto co = GetI18NCategory(I18NCat::CONTROLS);
|
||||
return co->T("Control mapping");
|
||||
}
|
||||
|
||||
void ControlMappingScreen::CreateContentViews(UI::ViewGroup *parent) {
|
||||
using namespace UI;
|
||||
|
||||
LinearLayout *rootLayout = parent->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
mappers_.clear();
|
||||
|
||||
size_t numMappableKeys = 0;
|
||||
const KeyMap::KeyMap_IntStrPair *mappableKeys = KeyMap::GetMappableKeys(&numMappableKeys);
|
||||
|
||||
auto km = GetI18NCategory(I18NCat::KEYMAPPING);
|
||||
|
||||
AddTab("keymap", "Control mapping", [this](UI::LinearLayout *parent) {
|
||||
size_t numMappableKeys = 0;
|
||||
const KeyMap::KeyMap_IntStrPair *mappableKeys = KeyMap::GetMappableKeys(&numMappableKeys);
|
||||
bool portrait = GetDeviceOrientation() == DeviceOrientation::Portrait;
|
||||
|
||||
auto km = GetI18NCategory(I18NCat::KEYMAPPING);
|
||||
|
||||
int curCat = -1;
|
||||
CollapsibleSection *curSection = nullptr;
|
||||
for (size_t i = 0; i < numMappableKeys; i++) {
|
||||
if (curCat < (int)ARRAY_SIZE(cats) && mappableKeys[i].key == cats[curCat + 1].firstKey) {
|
||||
if (curCat >= 0) {
|
||||
curSection->SetOpenPtr(&categoryToggles_[curCat]);
|
||||
}
|
||||
curCat++;
|
||||
curSection = parent->Add(new CollapsibleSection(km->T(cats[curCat].catName)));
|
||||
curSection->SetSpacing(6.0f);
|
||||
int curCat = -1;
|
||||
CollapsibleSection *curSection = nullptr;
|
||||
for (size_t i = 0; i < numMappableKeys; i++) {
|
||||
if (curCat < (int)ARRAY_SIZE(cats) && mappableKeys[i].key == cats[curCat + 1].firstKey) {
|
||||
if (curCat >= 0) {
|
||||
curSection->SetOpenPtr(&categoryToggles_[curCat]);
|
||||
}
|
||||
SingleControlMapper *mapper = curSection->Add(
|
||||
new SingleControlMapper(mappableKeys[i].key, mappableKeys[i].name, screenManager(),
|
||||
new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
mapper->SetTag(StringFromFormat("KeyMap%s", mappableKeys[i].name));
|
||||
mappers_.push_back(mapper);
|
||||
curCat++;
|
||||
curSection = rootLayout->Add(new CollapsibleSection(km->T(cats[curCat].catName)));
|
||||
curSection->SetSpacing(6.0f);
|
||||
}
|
||||
if (curCat >= 0 && curSection) {
|
||||
curSection->SetOpenPtr(&categoryToggles_[curCat]);
|
||||
}
|
||||
_dbg_assert_(curCat == ARRAY_SIZE(cats) - 2); // count the sentinel
|
||||
}, TabFlags::Default);
|
||||
SingleControlMapper *mapper = curSection->Add(
|
||||
new SingleControlMapper(mappableKeys[i].key, mappableKeys[i].name, portrait, screenManager()));
|
||||
mapper->SetTag(StringFromFormat("KeyMap%s", mappableKeys[i].name));
|
||||
mappers_.push_back(mapper);
|
||||
}
|
||||
if (curCat >= 0 && curSection) {
|
||||
curSection->SetOpenPtr(&categoryToggles_[curCat]);
|
||||
}
|
||||
_dbg_assert_(curCat == ARRAY_SIZE(cats) - 2); // count the sentinel
|
||||
|
||||
keyMapGeneration_ = KeyMap::g_controllerMapGeneration;
|
||||
}
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
|
||||
class SingleControlMapper;
|
||||
|
||||
class ControlMappingScreen : public UITabbedBaseDialogScreen {
|
||||
class ControlMappingScreen : public UITwoPaneBaseDialogScreen {
|
||||
public:
|
||||
ControlMappingScreen(const Path &gamePath) : UITabbedBaseDialogScreen(gamePath, TabDialogFlags::ContextMenuInPortrait) {
|
||||
ControlMappingScreen(const Path &gamePath) : UITwoPaneBaseDialogScreen(gamePath, TwoPaneFlags::SettingsInContextMenu | TwoPaneFlags::ContentsCanScroll) {
|
||||
categoryToggles_[0] = true;
|
||||
categoryToggles_[1] = true;
|
||||
categoryToggles_[2] = true;
|
||||
@@ -48,13 +48,14 @@ public:
|
||||
const char *tag() const override { return "ControlMapping"; }
|
||||
|
||||
protected:
|
||||
void CreateTabs() override;
|
||||
void CreateExtraButtons(UI::ViewGroup *verticalLayout, int margins) override;
|
||||
void CreateSettingsViews(UI::ViewGroup *parent) override;
|
||||
void CreateContentViews(UI::ViewGroup *parent) override;
|
||||
void update() override;
|
||||
|
||||
std::string_view GetTitle() const override;
|
||||
|
||||
private:
|
||||
void OnAutoConfigure(UI::EventParams ¶ms);
|
||||
bool ShowSearchControls() const override { return false; }
|
||||
|
||||
void dialogFinished(const Screen *dialog, DialogResult result) override;
|
||||
|
||||
|
||||
@@ -121,15 +121,13 @@ std::string_view CustomButtonMappingScreen::GetTitle() const {
|
||||
return co->T("Custom touch button setup");
|
||||
}
|
||||
|
||||
void CustomButtonMappingScreen::CreateViews() {
|
||||
void CustomButtonMappingScreen::CreateDialogViews(UI::ViewGroup *parent) {
|
||||
using namespace UI;
|
||||
using namespace CustomKeyData;
|
||||
auto co = GetI18NCategory(I18NCat::CONTROLS);
|
||||
auto mc = GetI18NCategory(I18NCat::MAPPABLECONTROLS);
|
||||
root_ = new LinearLayout(ORIENT_VERTICAL);
|
||||
root_->Add(new ItemHeader(GetTitle()));
|
||||
LinearLayout *root__ = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(1.0));
|
||||
root_->Add(root__);
|
||||
LinearLayout *root__ = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT, 1.0));
|
||||
parent->Add(root__);
|
||||
LinearLayout *leftColumn = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(120, FILL_PARENT));
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
|
||||
@@ -143,13 +141,14 @@ void CustomButtonMappingScreen::CreateViews() {
|
||||
for (int i = 0; i < ARRAY_SIZE(g_customKeyList); i++)
|
||||
array[i] = (0x01 == ((g_Config.CustomButton[id_].key >> i) & 0x01));
|
||||
|
||||
// TODO: Less hacky layout work
|
||||
const Bounds layoutBounds = screenManager()->getUIContext()->GetLayoutBounds();
|
||||
leftColumn->Add(new ButtonPreview(g_Config.iTouchButtonStyle == 0 ? customKeyShapes[cfg->shape].i : customKeyShapes[cfg->shape].l,
|
||||
customKeyImages[cfg->image].i, customKeyImages[cfg->image].r, customKeyShapes[cfg->shape].f, customKeyShapes[cfg->shape].r, 62, 82));
|
||||
customKeyImages[cfg->image].i, customKeyImages[cfg->image].r, customKeyShapes[cfg->shape].f, customKeyShapes[cfg->shape].r, layoutBounds.x + 62, layoutBounds.y + 102));
|
||||
|
||||
root__->Add(leftColumn);
|
||||
|
||||
ScrollView *rightScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT, 1.0f));
|
||||
leftColumn->Add(new Spacer(new LinearLayoutParams(1.0f)));
|
||||
leftColumn->Add(new Choice(di->T("Back")))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
|
||||
root__->Add(rightScroll);
|
||||
|
||||
LinearLayout *vertLayout = new LinearLayout(ORIENT_VERTICAL);
|
||||
|
||||
@@ -19,23 +19,25 @@
|
||||
|
||||
#include "UI/BaseScreens.h"
|
||||
#include "UI/GamepadEmu.h"
|
||||
#include "UI/SimpleDialogScreen.h"
|
||||
|
||||
namespace UI {
|
||||
class CheckBox;
|
||||
}
|
||||
|
||||
class CustomButtonMappingScreen : public UIBaseDialogScreen {
|
||||
class CustomButtonMappingScreen : public UISimpleBaseDialogScreen {
|
||||
public:
|
||||
CustomButtonMappingScreen(DeviceOrientation deviceOrientation, const Path &gamePath, int id) : UIBaseDialogScreen(gamePath), deviceOrientation_(deviceOrientation), id_(id) {}
|
||||
CustomButtonMappingScreen(DeviceOrientation deviceOrientation, const Path &gamePath, int id) : UISimpleBaseDialogScreen(gamePath, SimpleDialogFlags::Default), deviceOrientation_(deviceOrientation), id_(id) {}
|
||||
|
||||
const char *tag() const override { return "CustomButton"; }
|
||||
|
||||
void CreateViews() override;
|
||||
void CreateDialogViews(UI::ViewGroup *parent) override;
|
||||
void onFinish(DialogResult result) override;
|
||||
|
||||
protected:
|
||||
void dialogFinished(const Screen *dialog, DialogResult result) override;
|
||||
std::string_view GetTitle() const;
|
||||
std::string_view GetTitle() const override;
|
||||
|
||||
private:
|
||||
void saveArray();
|
||||
|
||||
|
||||
+1
-2
@@ -119,13 +119,12 @@ private:
|
||||
|
||||
class CreditsScreen : public UISimpleBaseDialogScreen {
|
||||
public:
|
||||
CreditsScreen() : UISimpleBaseDialogScreen() {}
|
||||
CreditsScreen() : UISimpleBaseDialogScreen(Path(), SimpleDialogFlags::Default) {}
|
||||
void update() override;
|
||||
|
||||
protected:
|
||||
std::string_view GetTitle() const override;
|
||||
|
||||
void CreateDialogViews(UI::ViewGroup *parent) override;
|
||||
bool CanScroll() const override { return false; }
|
||||
const char *tag() const override { return "Credits"; }
|
||||
};
|
||||
|
||||
+22
-12
@@ -419,6 +419,10 @@ void GamePauseScreen::CreateViews() {
|
||||
|
||||
root_ = new LinearLayout(portrait ? ORIENT_VERTICAL : ORIENT_HORIZONTAL);
|
||||
|
||||
if (portrait) {
|
||||
((LinearLayout *)root_)->SetSpacing(0);
|
||||
}
|
||||
|
||||
if (portrait) {
|
||||
// We have room for a title bar. Use the game DB title if available.
|
||||
std::string title;
|
||||
@@ -533,9 +537,12 @@ void GamePauseScreen::CreateViews() {
|
||||
ViewGroup *buttonColumn = nullptr;
|
||||
if (portrait) {
|
||||
buttonColumn = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
|
||||
|
||||
middleColumn = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, ITEM_HEIGHT, Margins(10, 10, 10, 10)));
|
||||
root_->Add(middleColumn);
|
||||
root_->Add(buttonColumn);
|
||||
} else {
|
||||
middleColumn = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(64, FILL_PARENT, Margins(0, 10, 0, 15)));
|
||||
middleColumn = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(ITEM_HEIGHT, FILL_PARENT, Margins(0, 10, 0, 15)));
|
||||
root_->Add(middleColumn);
|
||||
middleColumn->SetSpacing(0.0f);
|
||||
|
||||
@@ -559,15 +566,11 @@ void GamePauseScreen::CreateViews() {
|
||||
Choice *continueChoice = rightColumnItems->Add(new Choice(pa->T("Continue"), ImageID("I_PLAY")));
|
||||
root_->SetDefaultFocusView(continueChoice);
|
||||
continueChoice->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
|
||||
rightColumnItems->Add(new Spacer(20.0));
|
||||
}
|
||||
|
||||
rightColumnItems->Add(new Spacer(20.0));
|
||||
|
||||
if (g_paramSFO.IsValid() && g_Config.HasGameConfig(g_paramSFO.GetDiscID())) {
|
||||
rightColumnItems->Add(new Choice(pa->T("Game Settings"), ImageID("I_GEAR")))->OnClick.Handle(this, &GamePauseScreen::OnGameSettings);
|
||||
Choice *delGameConfig = rightColumnItems->Add(new Choice(pa->T("Delete Game Config")));
|
||||
delGameConfig->OnClick.Handle(this, &GamePauseScreen::OnDeleteConfig);
|
||||
delGameConfig->SetEnabled(!bootPending_);
|
||||
} else if (PSP_CoreParameter().fileType != IdentifiedFileType::PPSSPP_GE_DUMP) {
|
||||
rightColumnItems->Add(new Choice(pa->T("Settings"), ImageID("I_GEAR")))->OnClick.Handle(this, &GamePauseScreen::OnGameSettings);
|
||||
Choice *createGameConfig = rightColumnItems->Add(new Choice(pa->T("Create Game Config"), ImageID("I_GEAR_STAR")));
|
||||
@@ -628,7 +631,7 @@ void GamePauseScreen::CreateViews() {
|
||||
exit->SetEnabled(!bootPending_);
|
||||
|
||||
if (middleColumn) {
|
||||
middleColumn->SetSpacing(20.0f);
|
||||
middleColumn->SetSpacing(portrait ? 8.0f : 20.0f);
|
||||
playButton_ = middleColumn->Add(new Button("", g_Config.bRunBehindPauseMenu ? ImageID("I_PAUSE") : ImageID("I_PLAY"), new LinearLayoutParams(64, 64)));
|
||||
playButton_->OnClick.Add([=](UI::EventParams &e) {
|
||||
g_Config.bRunBehindPauseMenu = !g_Config.bRunBehindPauseMenu;
|
||||
@@ -643,11 +646,12 @@ void GamePauseScreen::CreateViews() {
|
||||
screenManager()->push(new GameScreen(gamePath_, true));
|
||||
});
|
||||
|
||||
Button *menuButton = middleColumn->Add(new Button("", ImageID("I_THREE_DOTS"), new LinearLayoutParams(64, 64)));
|
||||
|
||||
menuButton->OnClick.Add([this, menuButton, portrait](UI::EventParams &e) {
|
||||
ShowContextMenu(menuButton, portrait);
|
||||
});
|
||||
if (!portrait) {
|
||||
Button *menuButton = middleColumn->Add(new Button("", ImageID("I_THREE_DOTS"), new LinearLayoutParams(64, 64)));
|
||||
menuButton->OnClick.Add([this, menuButton, portrait](UI::EventParams &e) {
|
||||
ShowContextMenu(menuButton, portrait);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
playButton_ = nullptr;
|
||||
}
|
||||
@@ -671,6 +675,12 @@ void GamePauseScreen::ShowContextMenu(UI::View *menuButton, bool portrait) {
|
||||
}
|
||||
});
|
||||
|
||||
auto pa = GetI18NCategory(I18NCat::PAUSE);
|
||||
|
||||
Choice *delGameConfig = parent->Add(new Choice(pa->T("Delete Game Config")));
|
||||
delGameConfig->OnClick.Handle(this, &GamePauseScreen::OnDeleteConfig);
|
||||
delGameConfig->SetEnabled(!bootPending_);
|
||||
|
||||
if (portrait) {
|
||||
// Add some other options that are removed from the main screen in portrait mode.
|
||||
if (Reporting::IsSupported() && g_paramSFO.GetValueString("DISC_ID").size()) {
|
||||
|
||||
+1
-1
@@ -418,7 +418,7 @@ void ReportScreen::HandleBrowser(UI::EventParams &e) {
|
||||
}
|
||||
|
||||
ReportFinishScreen::ReportFinishScreen(const Path &gamePath, ReportingOverallScore score)
|
||||
: UISimpleBaseDialogScreen(), gamePath_(gamePath), score_(score) {
|
||||
: UISimpleBaseDialogScreen(Path(), SimpleDialogFlags::ContentsCanScroll), gamePath_(gamePath), score_(score) {
|
||||
}
|
||||
|
||||
std::string_view ReportFinishScreen::GetTitle() const {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
void UISimpleBaseDialogScreen::CreateViews() {
|
||||
using namespace UI;
|
||||
|
||||
const bool canScroll = CanScroll();
|
||||
const bool canScroll = flags_ & SimpleDialogFlags::ContentsCanScroll;
|
||||
ignoreBottomInset_ = canScroll;
|
||||
|
||||
const bool portrait = GetDeviceOrientation() == DeviceOrientation::Portrait;
|
||||
@@ -36,9 +36,17 @@ void UITwoPaneBaseDialogScreen::CreateViews() {
|
||||
|
||||
BeforeCreateViews();
|
||||
|
||||
auto createContentViews = [this](UI::ViewGroup *parent) {
|
||||
auto createContentViews = [this, portrait](UI::ViewGroup *parent) {
|
||||
if (flags_ & TwoPaneFlags::ContentsCanScroll) {
|
||||
ScrollView *contentScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT, 1.0f, Margins(8)));
|
||||
Margins margins(8, 8, 8, 0);
|
||||
if (flags_ & TwoPaneFlags::SettingsToTheRight) {
|
||||
// If settings are in context menu, we want to avoid double margins on the sides.
|
||||
margins.left = 0;
|
||||
} else {
|
||||
margins.right = 0;
|
||||
}
|
||||
|
||||
ScrollView *contentScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT, 1.0f, margins));
|
||||
parent->Add(contentScroll);
|
||||
CreateContentViews(contentScroll);
|
||||
} else {
|
||||
|
||||
@@ -5,11 +5,17 @@
|
||||
|
||||
#include "UI/BaseScreens.h"
|
||||
|
||||
enum class SimpleDialogFlags {
|
||||
Default = 0,
|
||||
ContentsCanScroll = 8,
|
||||
};
|
||||
ENUM_CLASS_BITOPS(SimpleDialogFlags);
|
||||
|
||||
// The simpler cousin of TabbedDialogScreen, without tabs or the other bling,
|
||||
// but with a consistent portrait-compatible back button and title.
|
||||
class UISimpleBaseDialogScreen : public UIBaseDialogScreen {
|
||||
public:
|
||||
UISimpleBaseDialogScreen(const Path &gamePath = Path()) : UIBaseDialogScreen(gamePath) {
|
||||
UISimpleBaseDialogScreen(const Path &gamePath, SimpleDialogFlags flags) : UIBaseDialogScreen(gamePath), flags_(flags) {
|
||||
// We need to check CanScroll before we know whether to ignore
|
||||
// bottom inset. Can't do that here, we do it in CreateViews
|
||||
}
|
||||
@@ -17,11 +23,10 @@ public:
|
||||
// Override this, don't override CreateViews. And don't touch root_ directly.
|
||||
virtual void CreateDialogViews(UI::ViewGroup *parent) = 0;
|
||||
virtual std::string_view GetTitle() const { return ""; }
|
||||
protected:
|
||||
virtual bool CanScroll() const { return true; }
|
||||
|
||||
private:
|
||||
void CreateViews() override;
|
||||
SimpleDialogFlags flags_;
|
||||
};
|
||||
|
||||
enum class TwoPaneFlags {
|
||||
|
||||
+1
-1
@@ -422,7 +422,7 @@ void ProductView::OnLaunchClick(UI::EventParams &e) {
|
||||
OnClickLaunch.Trigger(e2);
|
||||
}
|
||||
|
||||
StoreScreen::StoreScreen() {
|
||||
StoreScreen::StoreScreen() : UISimpleBaseDialogScreen(Path(), SimpleDialogFlags::Default) {
|
||||
lang_ = g_Config.sLanguageIni;
|
||||
loading_ = true;
|
||||
|
||||
|
||||
@@ -76,7 +76,6 @@ protected:
|
||||
void OnGameLaunch(UI::EventParams &e);
|
||||
|
||||
std::string_view GetTitle() const override;
|
||||
bool CanScroll() const override { return false; } // does its own scrolling
|
||||
private:
|
||||
void ParseListing(const std::string &json);
|
||||
ProductItemView *GetSelectedItem();
|
||||
|
||||
@@ -676,7 +676,7 @@ void TouchControlLayoutScreen::CreateViews() {
|
||||
leftColumn->Add(new Spacer(0.0f));
|
||||
|
||||
LinearLayout* rightColumn = root_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f, Margins(0.0f, 12.0f, 12.0f, 12.0f))));
|
||||
rightColumn->Add(new TextView(co->T(DeviceOrientationToString(orientation))));
|
||||
rightColumn->Add(new TextView(co->T(DeviceOrientationToString(orientation))))->SetTextSize(TextSize::Small);
|
||||
rightColumn->Add(new Spacer(new LinearLayoutParams(1.0)));
|
||||
float previewHeight = bounds.h * layoutAreaScale;
|
||||
layoutView_ = rightColumn->Add(new ControlLayoutView(GetDeviceOrientation(), new LinearLayoutParams(FILL_PARENT, previewHeight)));
|
||||
|
||||
@@ -46,15 +46,27 @@ private:
|
||||
UI::CheckBox *checkbox_;
|
||||
};
|
||||
|
||||
void TouchControlVisibilityScreen::CreateTabs() {
|
||||
std::string_view TouchControlVisibilityScreen::GetTitle() const {
|
||||
auto co = GetI18NCategory(I18NCat::CONTROLS);
|
||||
return co->T("Touch Control Visibility");
|
||||
}
|
||||
|
||||
AddTab("Visibility", co->T("Visibility"), [this](UI::LinearLayout *contents) {
|
||||
CreateVisibilityTab(contents);
|
||||
void TouchControlVisibilityScreen::CreateSettingsViews(UI::ViewGroup *parent) {
|
||||
using namespace UI;
|
||||
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
|
||||
Choice *toggleAll = parent->Add(new Choice(di->T("Toggle All")));
|
||||
toggleAll->OnClick.Add([this](UI::EventParams &e) {
|
||||
// TODO: Is this a meaningful operation to support?
|
||||
for (auto toggle : toggles_) {
|
||||
*toggle.show = nextToggleAll_;
|
||||
}
|
||||
nextToggleAll_ = !nextToggleAll_;
|
||||
});
|
||||
}
|
||||
|
||||
void TouchControlVisibilityScreen::CreateVisibilityTab(UI::LinearLayout *vert) {
|
||||
void TouchControlVisibilityScreen::CreateContentViews(UI::ViewGroup *parent) {
|
||||
using namespace UI;
|
||||
using namespace CustomKeyData;
|
||||
|
||||
@@ -63,25 +75,10 @@ void TouchControlVisibilityScreen::CreateVisibilityTab(UI::LinearLayout *vert) {
|
||||
|
||||
const bool portrait = GetDeviceOrientation() == DeviceOrientation::Portrait;
|
||||
|
||||
Choice *toggleAll = new Choice(di->T("Toggle All"), "", false, new AnchorLayoutParams(leftColumnWidth - 10, WRAP_CONTENT, 10, NONE, NONE, 84));
|
||||
|
||||
vert->SetSpacing(0);
|
||||
|
||||
vert->Add(toggleAll)->OnClick.Add([this](UI::EventParams &e) {
|
||||
// TODO: Is this a meaningful operation to support?
|
||||
for (auto toggle : toggles_) {
|
||||
*toggle.show = nextToggleAll_;
|
||||
}
|
||||
nextToggleAll_ = !nextToggleAll_;
|
||||
});
|
||||
|
||||
vert->Add(new ItemHeader(co->T("Touch Control Visibility")));
|
||||
|
||||
const int cellSize = portrait ? std::min((g_display.dp_xres / 2 - 10), 290) : 380;
|
||||
|
||||
UI::GridLayoutSettings gridsettings(cellSize, 64, 5);
|
||||
gridsettings.fillCells = true;
|
||||
GridLayout *grid = vert->Add(new GridLayoutList(gridsettings, new LayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
GridLayout *grid = parent->Add(new GridLayoutList(gridsettings, new LayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
|
||||
TouchControlConfig &touch = g_Config.GetTouchControlsConfig(GetDeviceOrientation());
|
||||
|
||||
@@ -152,7 +149,12 @@ void TouchControlVisibilityScreen::onFinish(DialogResult result) {
|
||||
g_Config.Save("TouchControlVisibilityScreen::onFinish");
|
||||
}
|
||||
|
||||
void RightAnalogMappingScreen::CreateViews() {
|
||||
std::string_view RightAnalogMappingScreen::GetTitle() const {
|
||||
auto mc = GetI18NCategory(I18NCat::MAPPABLECONTROLS);
|
||||
return mc->T("Right Analog Stick");
|
||||
}
|
||||
|
||||
void RightAnalogMappingScreen::CreateDialogViews(UI::ViewGroup *parent) {
|
||||
using namespace UI;
|
||||
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
@@ -161,34 +163,19 @@ void RightAnalogMappingScreen::CreateViews() {
|
||||
|
||||
TouchControlConfig &touch = g_Config.GetTouchControlsConfig(GetDeviceOrientation());
|
||||
|
||||
root_ = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT));
|
||||
Choice *back = new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK"), new AnchorLayoutParams(leftColumnWidth - 10, WRAP_CONTENT, 10, NONE, NONE, 10));
|
||||
root_->Add(back)->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
|
||||
TabHolder *tabHolder = new TabHolder(ORIENT_VERTICAL, leftColumnWidth, TabHolderFlags::Default, nullptr, nullptr, new AnchorLayoutParams(10, 0, 10, 0, Centering::None));
|
||||
root_->Add(tabHolder);
|
||||
ScrollView *rightPanel = new ScrollView(ORIENT_VERTICAL);
|
||||
tabHolder->AddTab(co->T("Binds"), ImageID::invalid(), rightPanel);
|
||||
LinearLayout *vert = rightPanel->Add(new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT)));
|
||||
vert->SetSpacing(0);
|
||||
|
||||
static const char *rightAnalogButton[] = {"None", "L", "R", "Square", "Triangle", "Circle", "Cross", "D-pad up", "D-pad down", "D-pad left", "D-pad right", "Start", "Select", "RightAn.Up", "RightAn.Down", "RightAn.Left", "RightAn.Right", "An.Up", "An.Down", "An.Left", "An.Right"};
|
||||
|
||||
vert->Add(new ItemHeader(co->T("Analog Style")));
|
||||
vert->Add(new CheckBox(&touch.touchRightAnalogStick.show, co->T("Visible")));
|
||||
vert->Add(new CheckBox(&g_Config.bRightAnalogCustom, co->T("Use custom right analog")));
|
||||
vert->Add(new CheckBox(&g_Config.bRightAnalogDisableDiagonal, co->T("Disable diagonal input")))->SetEnabledPtr(&g_Config.bRightAnalogCustom);
|
||||
parent->Add(new ItemHeader(co->T("Analog Style")));
|
||||
parent->Add(new CheckBox(&touch.touchRightAnalogStick.show, co->T("Visible")));
|
||||
parent->Add(new CheckBox(&g_Config.bRightAnalogCustom, co->T("Use custom right analog")));
|
||||
parent->Add(new CheckBox(&g_Config.bRightAnalogDisableDiagonal, co->T("Disable diagonal input")))->SetEnabledPtr(&g_Config.bRightAnalogCustom);
|
||||
|
||||
vert->Add(new ItemHeader(co->T("Analog Binding")));
|
||||
PopupMultiChoice *rightAnalogUp = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogUp, mc->T("RightAn.Up"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), I18NCat::MAPPABLECONTROLS, screenManager()));
|
||||
PopupMultiChoice *rightAnalogDown = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogDown, mc->T("RightAn.Down"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), I18NCat::MAPPABLECONTROLS, screenManager()));
|
||||
PopupMultiChoice *rightAnalogLeft = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogLeft, mc->T("RightAn.Left"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), I18NCat::MAPPABLECONTROLS, screenManager()));
|
||||
PopupMultiChoice *rightAnalogRight = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogRight, mc->T("RightAn.Right"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), I18NCat::MAPPABLECONTROLS, screenManager()));
|
||||
PopupMultiChoice *rightAnalogPress = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogPress, co->T("Keep this button pressed when right analog is pressed"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton) - 8, I18NCat::MAPPABLECONTROLS, screenManager()));
|
||||
rightAnalogUp->SetEnabledPtr(&g_Config.bRightAnalogCustom);
|
||||
rightAnalogDown->SetEnabledPtr(&g_Config.bRightAnalogCustom);
|
||||
rightAnalogLeft->SetEnabledPtr(&g_Config.bRightAnalogCustom);
|
||||
rightAnalogRight->SetEnabledPtr(&g_Config.bRightAnalogCustom);
|
||||
rightAnalogPress->SetEnabledPtr(&g_Config.bRightAnalogCustom);
|
||||
parent->Add(new ItemHeader(co->T("Analog Binding")));
|
||||
parent->Add(new PopupMultiChoice(&g_Config.iRightAnalogUp, mc->T("RightAn.Up"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), I18NCat::MAPPABLECONTROLS, screenManager()))->SetEnabledPtr(&g_Config.bRightAnalogCustom);
|
||||
parent->Add(new PopupMultiChoice(&g_Config.iRightAnalogDown, mc->T("RightAn.Down"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), I18NCat::MAPPABLECONTROLS, screenManager()))->SetEnabledPtr(&g_Config.bRightAnalogCustom);
|
||||
parent->Add(new PopupMultiChoice(&g_Config.iRightAnalogLeft, mc->T("RightAn.Left"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), I18NCat::MAPPABLECONTROLS, screenManager()))->SetEnabledPtr(&g_Config.bRightAnalogCustom);
|
||||
parent->Add(new PopupMultiChoice(&g_Config.iRightAnalogRight, mc->T("RightAn.Right"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), I18NCat::MAPPABLECONTROLS, screenManager()))->SetEnabledPtr(&g_Config.bRightAnalogCustom);
|
||||
parent->Add(new PopupMultiChoice(&g_Config.iRightAnalogPress, co->T("Keep this button pressed when right analog is pressed"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton) - 8, I18NCat::MAPPABLECONTROLS, screenManager()))->SetEnabledPtr(&g_Config.bRightAnalogCustom);
|
||||
}
|
||||
|
||||
void CheckBoxChoice::HandleClick(UI::EventParams &e) {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <string>
|
||||
#include "Common/Render/TextureAtlas.h"
|
||||
#include "UI/BaseScreens.h"
|
||||
#include "UI/TabbedDialogScreen.h"
|
||||
#include "UI/SimpleDialogScreen.h"
|
||||
|
||||
namespace UI {
|
||||
class CheckBox;
|
||||
@@ -34,27 +34,26 @@ struct TouchButtonToggle {
|
||||
std::function<void(UI::EventParams&)> handle;
|
||||
};
|
||||
|
||||
class TouchControlVisibilityScreen : public UITabbedBaseDialogScreen {
|
||||
class TouchControlVisibilityScreen : public UITwoPaneBaseDialogScreen {
|
||||
public:
|
||||
TouchControlVisibilityScreen(const Path &gamePath) : UITabbedBaseDialogScreen(gamePath) {}
|
||||
void CreateTabs() override;
|
||||
TouchControlVisibilityScreen(const Path &gamePath) : UITwoPaneBaseDialogScreen(gamePath, TwoPaneFlags::SettingsInContextMenu | TwoPaneFlags::ContentsCanScroll) {}
|
||||
void CreateContentViews(UI::ViewGroup *parent) override;
|
||||
void CreateSettingsViews(UI::ViewGroup *parent) override;
|
||||
void onFinish(DialogResult result) override;
|
||||
|
||||
const char *tag() const override { return "TouchControlVisibility"; }
|
||||
|
||||
protected:
|
||||
bool ShowSearchControls() const override { return false; }
|
||||
void CreateVisibilityTab(UI::LinearLayout *contents);
|
||||
|
||||
std::string_view GetTitle() const override;
|
||||
private:
|
||||
std::vector<TouchButtonToggle> toggles_;
|
||||
bool nextToggleAll_ = true;
|
||||
};
|
||||
|
||||
class RightAnalogMappingScreen : public UIBaseDialogScreen {
|
||||
class RightAnalogMappingScreen : public UISimpleBaseDialogScreen {
|
||||
public:
|
||||
RightAnalogMappingScreen(const Path &gamePath) : UIBaseDialogScreen(gamePath) {}
|
||||
void CreateViews() override;
|
||||
RightAnalogMappingScreen(const Path &gamePath) : UISimpleBaseDialogScreen(gamePath, SimpleDialogFlags::ContentsCanScroll) {}
|
||||
void CreateDialogViews(UI::ViewGroup *parent) override;
|
||||
std::string_view GetTitle() const override;
|
||||
|
||||
const char *tag() const override { return "RightAnalogMapping"; }
|
||||
};
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
#include "UI/UploadScreen.h"
|
||||
#include "UI/MiscViews.h"
|
||||
|
||||
UploadScreen::UploadScreen(const Path &targetFolder) : targetFolder_(targetFolder) {
|
||||
UploadScreen::UploadScreen(const Path &targetFolder) : UISimpleBaseDialogScreen(Path(), SimpleDialogFlags::Default), targetFolder_(targetFolder) {
|
||||
std::vector<std::string> ips;
|
||||
net::GetLocalIP4List(ips);
|
||||
localIPs_.clear();
|
||||
|
||||
Reference in New Issue
Block a user