mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-01 12:07:31 +01:00
Any tabbed screen can now add tabs described by a SettingsPage with AddSettingsTab, and gets the search tab that shows matching settings with arrows to jump to them. The game settings screen is the first to use it. Screens without settings tabs keep the old filter for now. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
97 lines
3.2 KiB
C++
97 lines
3.2 KiB
C++
#pragma once
|
|
|
|
#include "ppsspp_config.h"
|
|
#include <functional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "Common/Data/Text/I18n.h"
|
|
#include "Common/UI/UIScreen.h"
|
|
#include "Common/Render/TextureAtlas.h"
|
|
#include "Common/System/System.h"
|
|
#include "Core/ConfigValues.h"
|
|
#include "UI/BaseScreens.h"
|
|
|
|
namespace UI {
|
|
class TabHolder;
|
|
}
|
|
|
|
class SettingsPage;
|
|
|
|
enum class TabDialogFlags {
|
|
Default = 0,
|
|
HorizontalOnlyIcons = 1,
|
|
VerticalShowIcons = 2,
|
|
AddAutoTitles = 4,
|
|
ContextMenuInPortrait = 8,
|
|
};
|
|
ENUM_CLASS_BITOPS(TabDialogFlags);
|
|
|
|
enum class TabFlags {
|
|
Default = 0,
|
|
NonScrollable = 1,
|
|
};
|
|
ENUM_CLASS_BITOPS(TabFlags);
|
|
|
|
class UITabbedBaseDialogScreen : public UIBaseDialogScreen {
|
|
public:
|
|
// currentTabSetting can be null if you don't want to persist the current tab.
|
|
UITabbedBaseDialogScreen(const Path &gamePath, int *currentTabSetting = nullptr, TabDialogFlags flags = TabDialogFlags::Default);
|
|
void AddTab(const char *tag, std::string_view title, ImageID imageId, std::function<void(UI::LinearLayout *)> createCallback, TabFlags flags = TabFlags::Default);
|
|
void AddTab(const char *tag, std::string_view title, std::function<void(UI::LinearLayout *)> createCallback, TabFlags flags = TabFlags::Default) {
|
|
AddTab(tag, title, ImageID::invalid(), createCallback, flags);
|
|
}
|
|
// A tab described by a SettingsPage, whose settings show up in search. createHeader can add views above
|
|
// the page, like a title bar. build may be called at any time (also for search), so it shouldn't create views.
|
|
void AddSettingsTab(const char *tag, std::string_view title, ImageID imageId, I18NCat cat, std::function<void(SettingsPage &)> build, std::function<void(UI::LinearLayout *)> createHeader = nullptr);
|
|
void CreateViews() override;
|
|
void update() override;
|
|
|
|
protected:
|
|
// Load data and define your tabs here.
|
|
virtual void PreCreateViews() {}
|
|
virtual void CreateTabs() = 0;
|
|
virtual void CreateExtraButtons(UI::ViewGroup *verticalLayout, int margins) {}
|
|
virtual bool ShowSearchControls() const { return true; }
|
|
virtual void EnsureTabs();
|
|
virtual bool UsePopupMenuInPortrait() const { return false; }
|
|
virtual bool ForceHorizontalTabs() const { return false; }
|
|
|
|
int GetCurrentTab() const;
|
|
void SetCurrentTab(int tab);
|
|
// Whether there's room and a way to type a search.
|
|
static bool CanShowSearch();
|
|
|
|
void sendMessage(UIMessage message, const char *value) override;
|
|
|
|
private:
|
|
void ApplySearchFilter();
|
|
void CreateSearchTab(UI::LinearLayout *parent);
|
|
void GoToSetting(int settingsTab, int itemIndex);
|
|
|
|
struct SettingsTab {
|
|
int tabIndex;
|
|
std::string title;
|
|
I18NCat cat;
|
|
std::function<void(SettingsPage &)> build;
|
|
std::vector<UI::View *> views; // One per page item, filled in when the tab is created.
|
|
};
|
|
std::vector<SettingsTab> settingsTabs_;
|
|
std::string searchText_;
|
|
// Highlighted and scrolled to once laid out.
|
|
UI::View *pendingFocusView_ = nullptr;
|
|
|
|
UI::TabHolder *tabHolder_ = nullptr;
|
|
UI::TextView *filterNotice_ = nullptr;
|
|
UI::Choice *clearSearchChoice_ = nullptr;
|
|
UI::TextView *noSearchResults_ = nullptr;
|
|
|
|
// If we recreate the views while this is active we show it again
|
|
std::string oldSettingInfo_;
|
|
std::string searchFilter_;
|
|
|
|
int *currentTabSetting_ = nullptr;
|
|
|
|
TabDialogFlags flags_ = TabDialogFlags::Default;
|
|
};
|