mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-01 12:07:31 +01:00
Each tab is now a SettingsPage: a list of items (headers, settings, buttons, hints, links to other pages) that a function builds and views are created from. Settings are added with page->Setting(&g_Config.x), which takes the label, the kind of view, the range or choices, units, labels for special values and the default from the config. The pages keep what depends on the UI (which settings to show and when, enable rules, and behavior that needs the screen), and reach the screen through the page's SettingsPageHost. A page can link to other pages, which open on top of it in the same tab, under a bar showing where you are, like Tools > Developer tools > Graphics, where the earlier pages can be clicked to go back to them. The bar has back, search and help buttons, and the back key also goes back a page (or out of a search) before leaving the screen. Each page remembers its scroll position. In portrait there's no tab strip: a page links to the tabs, and the bar shows just the current page's title. Rotating keeps showing the same page. Moving between pages only focuses an item when navigating with a keyboard or controller. The developer tools are now pages linked from the Tools tab, instead of a screen of their own. The in-game developer menu and --start-screen=developertools open the settings on that page. The toggles of live state (the remote debugger and the MIPS tracer) show and change it through functions, and pretending to be in-game for the notification tests is a flag on the OSD. The memory map and memstick tests, only reachable from commented-out code, are removed. Search lists the matching settings from all tabs and the pages they link to, grouped by where they are. Each result goes to the setting on its page, scrolled to and highlighted (outlined, when picked with a mouse or touch), or for a page, opens it. This replaces the search tab and the old filter that hid the views that didn't match, and with them ShowSearchControls. Changing tabs leaves the search. The pages, the bar and search are in SettingsPagesDialogScreen, between the tabbed dialog screen and the settings screen, so the other tabbed screens keep plain tabs. Other visible changes: - Reset buttons that went to the wrong value now go to the real default: the touch control auto-hide delay (was 20 seconds instead of 8), the mouse wheel delay (1 ms, below its own range, instead of 80) and the UI size (0 instead of -1 on desktop). The alternative speeds get a reset button. - Units are shown on more sliders (frames, MHz, seconds, Hz), and popups no longer spell out what 0 means in the units, since the zero label does. Units of up to three characters (%, x, ms, MHz) aren't translated. - The Android HW scaler hides the scales the display is too small for, instead of cutting the list short. - Choices are translated in the setting's own section. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
168 lines
4.9 KiB
C++
168 lines
4.9 KiB
C++
#pragma once
|
|
|
|
#include "Common/Common.h"
|
|
#include "Common/UI/View.h"
|
|
#include "UI/ViewGroup.h"
|
|
#include "UI/GameInfoCache.h"
|
|
|
|
// Compound view, showing a text with an icon.
|
|
class TextWithImage : public UI::LinearLayout {
|
|
public:
|
|
TextWithImage(ImageID imageID, std::string_view text, UI::LinearLayoutParams *layoutParams = nullptr);
|
|
};
|
|
|
|
// Compound view, showing a copyable string.
|
|
class CopyableText : public UI::LinearLayout {
|
|
public:
|
|
CopyableText(ImageID imageID, std::string_view text, UI::LinearLayoutParams *layoutParams = nullptr);
|
|
};
|
|
|
|
enum class TopBarFlags {
|
|
Default = 0,
|
|
Portrait = 1,
|
|
ContextMenuButton = 2,
|
|
NoBackButton = 4,
|
|
};
|
|
ENUM_CLASS_BITOPS(TopBarFlags);
|
|
|
|
class TopBar : public UI::LinearLayout {
|
|
public:
|
|
// The context is needed to get the theme for the background.
|
|
TopBar(const UIContext &ctx, TopBarFlags flags, std::string_view title, UI::LayoutParams *layoutParams = nullptr);
|
|
UI::View *GetBackButton() const { return backButton_; }
|
|
UI::View *GetContextMenuButton() const { return contextMenuButton_; }
|
|
|
|
UI::Event OnContextMenuClick;
|
|
|
|
private:
|
|
UI::Choice *backButton_ = nullptr;
|
|
UI::Choice *contextMenuButton_ = nullptr;
|
|
};
|
|
|
|
class ShinyIcon : public UI::ImageView {
|
|
public:
|
|
ShinyIcon(ImageID atlasImage, UI::LayoutParams *layoutParams = 0) : UI::ImageView(atlasImage, "", layoutParams) {}
|
|
void Draw(UIContext &dc) override;
|
|
void SetAnimated(bool anim) { animated_ = anim; }
|
|
private:
|
|
bool animated_ = true;
|
|
};
|
|
|
|
// The icon of the game, for showing that settings are game-specific.
|
|
UI::View *CreateGameIconView(const Path &gamePath, UI::LayoutParams *layoutParams);
|
|
|
|
// Title at the top of a scrolling pane of settings. May later include a back button, but currently doesn't.
|
|
// The gamePath_ is used to draw the icon of the game who's settings are currently being edited.
|
|
// settingsCategory is used to build the help URL.
|
|
class PaneTitleBar : public UI::LinearLayout {
|
|
public:
|
|
PaneTitleBar(const Path &gamePath, std::string_view title, const std::string_view settingsCategory, UI::LayoutParams *layoutParams = nullptr);
|
|
|
|
private:
|
|
Path gamePath_;
|
|
};
|
|
|
|
class GameImageView : public UI::InertView {
|
|
public:
|
|
GameImageView(const Path &gamePath, GameInfoFlags image, float scale, UI::LayoutParams *layoutParams = 0)
|
|
: InertView(layoutParams), image_(image), gamePath_(gamePath), scale_(scale) {
|
|
}
|
|
|
|
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
|
|
void Draw(UIContext &dc) override;
|
|
std::string DescribeText() const override { return ""; }
|
|
|
|
private:
|
|
GameInfoTex *GetTex(std::shared_ptr<GameInfo> info) const;
|
|
|
|
Path gamePath_;
|
|
GameInfoFlags image_;
|
|
float scale_ = 1.0f;
|
|
};
|
|
|
|
class GameInfoBGView : public UI::InertView {
|
|
public:
|
|
GameInfoBGView(const Path &gamePath, UI::LayoutParams *layoutParams) : InertView(layoutParams), gamePath_(gamePath) {}
|
|
|
|
void Draw(UIContext &dc) override;
|
|
std::string DescribeText() const override { return ""; }
|
|
void SetColor(uint32_t c) { color_ = c; }
|
|
|
|
protected:
|
|
Path gamePath_;
|
|
uint32_t color_ = 0xFFC0C0C0;
|
|
};
|
|
|
|
class SettingHint : public UI::TextView {
|
|
public:
|
|
// If setting is null, it's a "global hint", used outside of ChoiceGroups, usually after one.
|
|
SettingHint(std::string_view text, UI::View *setting);
|
|
std::string DescribeText() const override { return setting_ ? setting_->DescribeText() : ""; } // So that descriptions show up in searches under their parent views
|
|
void Draw(UIContext &dc) override;
|
|
private:
|
|
UI::View *setting_;
|
|
};
|
|
|
|
void AddRotationPicker(ScreenManager *screenManager, UI::ViewGroup *parent, bool text);
|
|
|
|
class SearchBar : public UI::InertView {
|
|
public:
|
|
SearchBar(UI::LayoutParams *params);
|
|
void Draw(UIContext &dc) override;
|
|
|
|
bool Touch(const TouchInput &input) override;
|
|
void SetSearchFilter(std::string_view filter) {
|
|
searchFilter_ = filter;
|
|
}
|
|
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
|
|
|
|
UI::Event OnCancel;
|
|
private:
|
|
std::string searchFilter_ = "N/A";
|
|
};
|
|
|
|
enum class SearchState {
|
|
MATCH,
|
|
MISMATCH,
|
|
PENDING,
|
|
};
|
|
|
|
struct ViewSearch {
|
|
SearchBar *searchBar;
|
|
std::string searchFilter;
|
|
std::vector<SearchState> searchStates;
|
|
bool searchPending;
|
|
|
|
void ApplySearchFilter(UI::ViewGroup *viewGroup, bool setKeyboardFocus);
|
|
bool Key(UI::ViewGroup *viewGroup, const KeyInput &input);
|
|
};
|
|
|
|
struct PMFPlayer;
|
|
namespace Draw {
|
|
class DrawContext;
|
|
class Texture;
|
|
}
|
|
|
|
// Decodes a PMF video (like a game's ICON1.PMF) into a texture, looping.
|
|
class PMFVideoTexture {
|
|
public:
|
|
explicit PMFVideoTexture(std::string data);
|
|
~PMFVideoTexture();
|
|
|
|
bool IsValid() const { return player_ != nullptr; }
|
|
int Width() const { return width_; }
|
|
int Height() const { return height_; }
|
|
|
|
// Returns the frame to show at the given time, or nullptr if none is decoded yet.
|
|
Draw::Texture *Update(Draw::DrawContext *draw, double timeSeconds);
|
|
void DeviceLost();
|
|
|
|
private:
|
|
std::string data_;
|
|
std::vector<u8> frame_;
|
|
Draw::Texture *curFrame_ = nullptr;
|
|
PMFPlayer *player_ = nullptr;
|
|
int width_ = 0;
|
|
int height_ = 0;
|
|
};
|