Add new TwoPane screen type, use for tilt controls. Adapts to portrait/landscape nicely.

This commit is contained in:
Henrik Rydgård committed 2025-10-29 10:14:19 +01:00
1 parent 89b3abbe7b
commit 37462a0c5f
4 files changed
+82 -38

No files matched your search

+39
View File
@@ -1,4 +1,5 @@
#include "Common/UI/ScrollView.h"
#include "Common/Data/Text/I18n.h"
#include "UI/SimpleDialogScreen.h"
#include "UI/MiscViews.h"
@@ -25,3 +26,41 @@ void UISimpleBaseDialogScreen::CreateViews() {
}
}
void UITwoPaneBaseDialogScreen::CreateViews() {
using namespace UI;
const bool portrait = UsePortraitLayout();
auto di = GetI18NCategory(I18NCat::DIALOG);
if (portrait) {
// Portrait layout is just a vertical stack.
ignoreBottomInset_ = true;
LinearLayout *root = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT));
root->Add(new TopBar(*screenManager()->getUIContext(), portrait, GetTitle()));
root->SetSpacing(0);
CreateContentViews(root);
ScrollView *settingsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT, 1.0f));
LinearLayout *settingsPane = new LinearLayout(ORIENT_VERTICAL);
settingsScroll->Add(settingsPane);
CreateSettingsViews(settingsPane);
root->Add(settingsScroll);
root_ = root;
} else {
ignoreBottomInset_ = false;
LinearLayout *root = new LinearLayout(ORIENT_HORIZONTAL, new LayoutParams(FILL_PARENT, FILL_PARENT));
// root_->Add(new TopBar(*screenManager()->getUIContext(), portrait, GetTitle(), new LayoutParams(FILL_PARENT, FILL_PARENT)));
LinearLayout *settingsPane = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(400.0f, FILL_PARENT));
settingsPane->SetSpacing(0);
CreateSettingsViews(settingsPane);
settingsPane->Add(new BorderView(BORDER_BOTTOM, BorderStyle::HEADER_FG, 2.0f, new LayoutParams(FILL_PARENT, 40.0f)));
settingsPane->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK")))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
root->Add(settingsPane);
CreateContentViews(root);
root_ = root;
}
}
+20
View File
@@ -23,3 +23,23 @@ protected:
private:
void CreateViews() override;
};
// A two-pane version of the above, where settings are meant to go in the settings pane,
// and contents in the content pane. Will generate nice layouts for portrait and landscape.
// but with a consistent portrait-compatible back button and title.
// The settings pane is scrollable while the other is not.
class UITwoPaneBaseDialogScreen : public UIBaseDialogScreen {
public:
UITwoPaneBaseDialogScreen(const Path &gamePath = Path()) : UIBaseDialogScreen(gamePath) {
// We need to check CanScroll before we know whether to ignore
// bottom inset. Can't do that here, we do it in CreateViews
}
// Override this, don't override CreateViews. And don't touch root_ directly.
virtual void CreateSettingsViews(UI::LinearLayout *parent) = 0;
virtual void CreateContentViews(UI::LinearLayout *parent) = 0;
virtual std::string_view GetTitle() const { return ""; }
private:
void CreateViews() override;
};
+15 -33
View File
@@ -78,42 +78,29 @@ void TiltAnalogSettingsScreen::CreateCalibrationView(UI::ViewGroup *parent, UI::
}
}
void TiltAnalogSettingsScreen::CreateViews() {
using namespace UI;
std::string_view TiltAnalogSettingsScreen::GetTitle() const {
auto co = GetI18NCategory(I18NCat::CONTROLS);
auto di = GetI18NCategory(I18NCat::DIALOG);
return co->T("Tilt control setup");
}
void TiltAnalogSettingsScreen::CreateContentViews(UI::LinearLayout *parent) {
using namespace UI;
CreateCalibrationView(parent, new LinearLayoutParams(300.0f, 300.0f, 1.0f, G_CENTER));
}
void TiltAnalogSettingsScreen::CreateSettingsViews(UI::LinearLayout *settings) {
using namespace UI;
auto co = GetI18NCategory(I18NCat::CONTROLS);
GamepadUpdateOpacity(1.0f);
bool portrait = UsePortraitLayout();
root_ = new LinearLayout(portrait ? ORIENT_VERTICAL : ORIENT_HORIZONTAL);
root_->SetTag("TiltAnalogSettings");
LinearLayout *settings = new LinearLayoutList(ORIENT_VERTICAL);
if (portrait) {
LinearLayout *topBar = root_->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
topBar->Add(new Choice(ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams(64, WRAP_CONTENT)))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
CreateCalibrationView(root_, new LinearLayoutParams(250, 250, 0.0f, UI::G_HCENTER));
ViewGroup *menuRoot = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f));
menuRoot->Add(settings);
root_->Add(menuRoot);
} else {
ViewGroup *menuRoot = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(600, FILL_PARENT));
root_->Add(menuRoot);
menuRoot->Add(settings);
CreateCalibrationView(root_, new LinearLayoutParams(1.0));
}
auto enabledFunc = [=]() -> bool {
return g_Config.iTiltInputType != 0;
};
settings->SetSpacing(0);
settings->Add(new ItemHeader(co->T("Tilt control setup")));
settings->Add(new PopupMultiChoice(&g_Config.iTiltInputType, co->T("Tilt Input Type"), g_tiltTypes, 0, g_numTiltTypes, I18NCat::CONTROLS, screenManager()))->OnChoice.Add(
[=](UI::EventParams &p) {
[this](UI::EventParams &p) {
//when the tilt event type is modified, we need to reset all tilt settings.
//refer to the ResetTiltEvents() function for a detailed explanation.
TiltEventProcessor::ResetTiltEvents();
@@ -141,11 +128,6 @@ void TiltAnalogSettingsScreen::CreateViews() {
settings->Add(new ItemHeader(co->T("Invert Axes")));
settings->Add(new CheckBox(&g_Config.bInvertTiltX, co->T("Invert Tilt along X axis")))->SetEnabledFunc(enabledFunc);
settings->Add(new CheckBox(&g_Config.bInvertTiltY, co->T("Invert Tilt along Y axis")))->SetEnabledFunc(enabledFunc);
if (!portrait) {
settings->Add(new BorderView(BORDER_BOTTOM, BorderStyle::HEADER_FG, 2.0f, new LayoutParams(FILL_PARENT, 40.0f)));
settings->Add(new Choice(di->T("Back")))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
}
}
void TiltAnalogSettingsScreen::OnCalibrate(UI::EventParams &e) {
@@ -153,7 +135,7 @@ void TiltAnalogSettingsScreen::OnCalibrate(UI::EventParams &e) {
}
void TiltAnalogSettingsScreen::update() {
UIBaseDialogScreen::update();
UITwoPaneBaseDialogScreen::update();
if (tilt_) {
tilt_->SetXY(
Clamp(TiltEventProcessor::rawTiltAnalogX, -1.0f, 1.0f),
+8 -5
View File
@@ -19,23 +19,26 @@
#include "Common/Math/math_util.h"
#include "Common/UI/View.h"
#include "BaseScreens.h"
#include "SimpleDialogScreen.h"
class JoystickHistoryView;
class GamepadView;
class TiltAnalogSettingsScreen : public UIBaseDialogScreen {
class TiltAnalogSettingsScreen : public UITwoPaneBaseDialogScreen {
public:
TiltAnalogSettingsScreen(const Path &gamePath) : UIBaseDialogScreen(gamePath) {}
TiltAnalogSettingsScreen(const Path &gamePath) : UITwoPaneBaseDialogScreen(gamePath) {}
void CreateSettingsViews(UI::LinearLayout *parent) override;
void CreateContentViews(UI::LinearLayout *parent) override;
std::string_view GetTitle() const override;
void CreateViews() override;
void update() override;
const char *tag() const override { return "TiltAnalogSettings"; }
private:
void OnCalibrate(UI::EventParams &e);
void CreateCalibrationView(UI::ViewGroup *parent, UI::LayoutParams *layoutParams);
Lin::Vec3 down_{};
JoystickHistoryView *tilt_ = nullptr;
};