mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-12 17:19:28 +01:00
Misc UI and cmdline parse work
This commit is contained in:
1 parent
7b2860ec42
commit
9e78ef5677
12 files changed
+109
-57
No files matched your search
@@ -174,3 +174,16 @@ bool HitAnyAsserts() {
|
||||
void ResetHitAnyAsserts() {
|
||||
hitAnyAsserts = false;
|
||||
}
|
||||
|
||||
void ShowMessageDialog(const char *title, const char *message, bool isError) {
|
||||
#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP)
|
||||
const int msgBoxStyle = MB_ICONINFORMATION | MB_OK;
|
||||
std::string text = message;
|
||||
const char *caption = title;
|
||||
std::wstring wcaption = ConvertUTF8ToWString(std::string(caption));
|
||||
MessageBox(g_dialogParent, ConvertUTF8ToWString(text).c_str(), wcaption.c_str(), msgBoxStyle);
|
||||
#else
|
||||
// Just printf.
|
||||
fprintf(stderr, "%s: %s\n", title, message);
|
||||
#endif
|
||||
}
|
||||
@@ -154,6 +154,7 @@ void SetAssertCancelCallback(AssertNoCallbackFunc callback, void *userdata);
|
||||
void SetCleanExitOnAssert();
|
||||
void BreakIntoPSPDebugger(const char *reason = "(userbreak)");
|
||||
void SetAssertDialogParent(void *handle); // HWND on windows. Ignored on other platforms.
|
||||
void ShowMessageDialog(const char *title, const char *message, bool isError = false);
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
// Tricky macro to get the basename, that also works if *built* on Win32.
|
||||
|
||||
@@ -193,7 +193,7 @@ void PopupScreen::CreateViews() {
|
||||
box_->SetRadiusFactor(1.44f);
|
||||
// Since we scale a bit, make the dropshadow bleed past the edges.
|
||||
box_->SetDropShadowExpand(std::max(g_display.dp_xres, g_display.dp_yres));
|
||||
box_->SetSpacing(0.0f);
|
||||
box_->SetSpacing(12.0f);
|
||||
box_->SetPadding(Margins(12));
|
||||
|
||||
if (!title_.empty()) {
|
||||
|
||||
+53
-37
@@ -641,6 +641,59 @@ std::string ItemHeader::DescribeText() const {
|
||||
return ApplySafeSubstitutions(u->T("%1 heading"), text_);
|
||||
}
|
||||
|
||||
PopupHeader::PopupHeader(std::string_view text, LayoutParams *layoutParams)
|
||||
: Item(layoutParams), text_(text) {
|
||||
layoutParams_->width = FILL_PARENT;
|
||||
layoutParams_->height = 44;
|
||||
}
|
||||
|
||||
void PopupHeader::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const {
|
||||
float availWidth = layoutParams_->width;
|
||||
if (availWidth < 0) {
|
||||
// If there's no size, let's grow as big as we want.
|
||||
availWidth = horiz.size == 0 ? MAX_ITEM_SIZE : horiz.size;
|
||||
}
|
||||
ApplyBoundBySpec(availWidth, horiz);
|
||||
dc.MeasureTextRect(dc.GetTheme().uiFontBig, 1.0f, 1.0f, text_, availWidth, &w, &h, ALIGN_LEFT | ALIGN_VCENTER);
|
||||
}
|
||||
|
||||
void PopupHeader::Draw(UIContext &dc) {
|
||||
const float availableWidth = bounds_.w;
|
||||
|
||||
float tw, th;
|
||||
dc.SetFontStyle(dc.GetTheme().uiFontBig);
|
||||
dc.MeasureText(dc.GetFontStyle(), 1.0f, 1.0f, text_, &tw, &th, 0);
|
||||
|
||||
float sineWidth = std::max(0.0f, (tw - availableWidth)) / 2.0f;
|
||||
|
||||
float tx = 0;
|
||||
if (availableWidth < tw) {
|
||||
float overageRatio = 1.5f * availableWidth * 1.0f / tw;
|
||||
tx -= (1.0f + sin(time_now_d() * overageRatio)) * sineWidth;
|
||||
Bounds tb = bounds_;
|
||||
tb.x = bounds_.x;
|
||||
tb.w = bounds_.w;
|
||||
dc.PushScissor(tb);
|
||||
}
|
||||
|
||||
// Header background
|
||||
dc.FillRoundRect(dc.GetTheme().popupTitleStyle.background, bounds_, dc.GetTheme().choiceRoundRadius, roundCorners_);
|
||||
// Header title text
|
||||
dc.DrawText(text_, bounds_.x + tx, bounds_.centerY(), dc.GetTheme().popupTitleStyle.fgColor, ALIGN_LEFT | ALIGN_VCENTER);
|
||||
|
||||
// Underline. Skipping it with the new style.
|
||||
// dc.Draw()->DrawImageCenterTexel(dc.GetTheme().whiteImage, bounds_.x, bounds_.y2()-2, bounds_.x2(), bounds_.y2(), dc.GetTheme().popupTitleStyle.fgColor);
|
||||
|
||||
if (availableWidth < tw) {
|
||||
dc.PopScissor();
|
||||
}
|
||||
}
|
||||
|
||||
std::string PopupHeader::DescribeText() const {
|
||||
auto u = GetI18NCategory(I18NCat::UI_ELEMENTS);
|
||||
return ApplySafeSubstitutions(u->T("%1 heading"), text_);
|
||||
}
|
||||
|
||||
CollapsibleHeader::CollapsibleHeader(bool *toggle, std::string_view text, LayoutParams *layoutParams)
|
||||
: CheckBox(toggle, text, "", layoutParams) {
|
||||
layoutParams_->width = FILL_PARENT;
|
||||
@@ -713,43 +766,6 @@ void BorderView::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec hor
|
||||
h = (borderFlags_ & BORDER_HORIZ) != 0 ? bounds.h : 0;
|
||||
}
|
||||
|
||||
void PopupHeader::Draw(UIContext &dc) {
|
||||
const float availableWidth = bounds_.w;
|
||||
|
||||
float tw, th;
|
||||
dc.SetFontStyle(dc.GetTheme().uiFontBig);
|
||||
dc.MeasureText(dc.GetFontStyle(), 1.0f, 1.0f, text_, &tw, &th, 0);
|
||||
|
||||
float sineWidth = std::max(0.0f, (tw - availableWidth)) / 2.0f;
|
||||
|
||||
float tx = 0;
|
||||
if (availableWidth < tw) {
|
||||
float overageRatio = 1.5f * availableWidth * 1.0f / tw;
|
||||
tx -= (1.0f + sin(time_now_d() * overageRatio)) * sineWidth;
|
||||
Bounds tb = bounds_;
|
||||
tb.x = bounds_.x;
|
||||
tb.w = bounds_.w;
|
||||
dc.PushScissor(tb);
|
||||
}
|
||||
|
||||
// Header background
|
||||
dc.FillRoundRect(dc.GetTheme().popupTitleStyle.background, bounds_, dc.GetTheme().choiceRoundRadius, roundCorners_);
|
||||
// Header title text
|
||||
dc.DrawText(text_, bounds_.x + tx, bounds_.centerY(), dc.GetTheme().popupTitleStyle.fgColor, ALIGN_LEFT | ALIGN_VCENTER);
|
||||
|
||||
// Underline. Skipping it with the new style.
|
||||
// dc.Draw()->DrawImageCenterTexel(dc.GetTheme().whiteImage, bounds_.x, bounds_.y2()-2, bounds_.x2(), bounds_.y2(), dc.GetTheme().popupTitleStyle.fgColor);
|
||||
|
||||
if (availableWidth < tw) {
|
||||
dc.PopScissor();
|
||||
}
|
||||
}
|
||||
|
||||
std::string PopupHeader::DescribeText() const {
|
||||
auto u = GetI18NCategory(I18NCat::UI_ELEMENTS);
|
||||
return ApplySafeSubstitutions(u->T("%1 heading"), text_);
|
||||
}
|
||||
|
||||
void CheckBox::Toggle() {
|
||||
if (toggle_) {
|
||||
*toggle_ = !(*toggle_);
|
||||
|
||||
+2
-5
@@ -939,12 +939,9 @@ private:
|
||||
|
||||
class PopupHeader : public Item {
|
||||
public:
|
||||
PopupHeader(std::string_view text, LayoutParams *layoutParams = 0)
|
||||
: Item(layoutParams), text_(text) {
|
||||
layoutParams_->width = FILL_PARENT;
|
||||
layoutParams_->height = 64;
|
||||
}
|
||||
PopupHeader(std::string_view text, LayoutParams *layoutParams = 0);
|
||||
void Draw(UIContext &dc) override;
|
||||
void GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const override;
|
||||
std::string DescribeText() const override;
|
||||
|
||||
private:
|
||||
|
||||
+1
-1
@@ -145,7 +145,7 @@ static void LaunchFile(ScreenManager *screenManager, Screen *currentScreen, cons
|
||||
// Show the savedata popup, why not?
|
||||
waitForParamSFO();
|
||||
std::string title = SanitizeString(info->GetTitle(), StringRestriction::NoLineBreaksOrSpecials, 0, 200);
|
||||
screenManager->push(new SavedataPopupScreen(Path(), path, title));
|
||||
screenManager->push(new SavedataPopupScreen(Path(), path, true, title));
|
||||
return;
|
||||
}
|
||||
case IdentifiedFileType::PSP_PBP:
|
||||
|
||||
@@ -192,7 +192,7 @@ void MemStickScreen::CreateViews() {
|
||||
ViewGroup *leftColumn = new LinearLayoutList(ORIENT_VERTICAL, new LinearLayoutParams(1.0));
|
||||
subColumns->Add(leftColumn);
|
||||
|
||||
ViewGroup *rightColumnItems = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(250, FILL_PARENT, actionMenuMargins));
|
||||
LinearLayout *rightColumnItems = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(250, FILL_PARENT, actionMenuMargins));
|
||||
subColumns->Add(rightColumnItems);
|
||||
|
||||
// For legacy Android systems, so you can switch back to the old ways if you move to SD or something.
|
||||
@@ -276,6 +276,8 @@ void MemStickScreen::CreateViews() {
|
||||
rightColumnItems->Add(new UI::Choice(ms->T("WhatsThis", "What's this?"), ImageID("I_LINK_OUT_QUESTION")))->OnClick.Handle<MemStickScreen>(this, &MemStickScreen::OnHelp);
|
||||
}
|
||||
|
||||
rightColumnItems->ApplyRoundCorners();
|
||||
|
||||
INFO_LOG(Log::System, "MemStickScreen: initialSetup=%d", (int)initialSetup_);
|
||||
}
|
||||
|
||||
|
||||
@@ -167,3 +167,15 @@ private:
|
||||
int width_ = 0;
|
||||
int height_ = 0;
|
||||
};
|
||||
|
||||
class HintView : public UI::TextView {
|
||||
public:
|
||||
HintView(std::string_view str, UI::LayoutParams *layoutParams = nullptr) : TextView(str, FLAG_WRAP_TEXT, false, layoutParams) {
|
||||
using namespace UI;
|
||||
layoutParams_->width = FILL_PARENT;
|
||||
layoutParams_->height = WRAP_CONTENT;
|
||||
SetTextSize(TextSize::Small);
|
||||
SetPadding(Margins(12));
|
||||
SetFrame(true);
|
||||
}
|
||||
};
|
||||
@@ -904,6 +904,9 @@ void NativeInit(int argc, const char *argv[], const CommandLineOptions &cmdLineO
|
||||
} else if (equals(cmdLineOptions.startScreen.value(), "firmware")) {
|
||||
g_screenManager->switchScreen(new MainScreen());
|
||||
g_screenManager->push(new FirmwareScreen(Path()));
|
||||
} else if (equals(cmdLineOptions.startScreen.value(), "memsticksetup")) {
|
||||
g_screenManager->switchScreen(new MainScreen());
|
||||
g_screenManager->push(new MemStickScreen(true));
|
||||
} else {
|
||||
WARN_LOG(Log::System, "Unknown start screen '%s'", cmdLineOptions.startScreen.value().c_str());
|
||||
g_screenManager->switchScreen(new LogoScreen(AfterLogoScreen::DEFAULT));
|
||||
|
||||
+3
-3
@@ -497,14 +497,14 @@ void GamePauseScreen::CreateSavestateControls(UI::LinearLayout *leftColumnItems,
|
||||
|
||||
LinearLayout *buttonRow = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(Margins(10, 0, 0, 10)));
|
||||
if (g_Config.bEnableStateUndo && !Achievements::HardcoreModeActive() && NetworkAllowSaveState()) {
|
||||
UI::Choice *saveUndoButton = buttonRow->Add(new Choice(pa->T("Undo last save"), ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT)));
|
||||
UI::Button *saveUndoButton = buttonRow->Add(new Button(pa->T("Undo last save"), ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams(WRAP_CONTENT, ITEM_HEIGHT)));
|
||||
saveUndoButton->SetEnabled(SaveState::HasUndoLastSave(saveStatePrefix_));
|
||||
saveUndoButton->OnClick.Add([this](UI::EventParams &e) {
|
||||
SaveState::UndoLastSave(saveStatePrefix_);
|
||||
RecreateViews();
|
||||
});
|
||||
|
||||
UI::Choice *loadUndoButton = buttonRow->Add(new Choice(pa->T("Undo last load"), ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT)));
|
||||
UI::Button *loadUndoButton = buttonRow->Add(new Button(pa->T("Undo last load"), ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams(WRAP_CONTENT, ITEM_HEIGHT)));
|
||||
loadUndoButton->SetEnabled(SaveState::HasUndoLoad(saveStatePrefix_));
|
||||
loadUndoButton->OnClick.Add([this](UI::EventParams &e) {
|
||||
CloseAfterStateLoad([this](SaveState::Callback callback) {
|
||||
@@ -514,7 +514,7 @@ void GamePauseScreen::CreateSavestateControls(UI::LinearLayout *leftColumnItems,
|
||||
}
|
||||
|
||||
if (g_Config.iRewindSnapshotInterval > 0 && !Achievements::HardcoreModeActive() && NetworkAllowSaveState()) {
|
||||
UI::Choice *rewindButton = buttonRow->Add(new Choice(pa->T("Rewind"), ImageID("I_REWIND"), new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT)));
|
||||
UI::Button *rewindButton = buttonRow->Add(new Button(pa->T("Rewind"), ImageID("I_REWIND"), new LinearLayoutParams(WRAP_CONTENT, ITEM_HEIGHT)));
|
||||
rewindButton->SetEnabled(SaveState::CanRewind());
|
||||
rewindButton->OnClick.Add([this](UI::EventParams &e) {
|
||||
CloseAfterStateLoad([](SaveState::Callback callback) {
|
||||
|
||||
+15
-8
@@ -132,7 +132,7 @@ SavedataView::SavedataView(UIContext &dc, GameInfo *ginfo, IdentifiedFileType ty
|
||||
}
|
||||
}
|
||||
|
||||
SavedataPopupScreen::SavedataPopupScreen(Path gamePath, Path savePath, std::string_view title) : PopupScreen(StripSpaces(title)), savePath_(savePath), gamePath_(gamePath) {}
|
||||
SavedataPopupScreen::SavedataPopupScreen(Path gamePath, Path savePath, bool showHint, std::string_view title) : PopupScreen(StripSpaces(title)), savePath_(savePath), gamePath_(gamePath), showHint_(showHint) {}
|
||||
|
||||
void SavedataPopupScreen::update() {
|
||||
PopupScreen::update();
|
||||
@@ -158,17 +158,23 @@ void SavedataPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
ScrollView *contentScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 1.0f, UI::Margins(0, 3)));
|
||||
parent->Add(contentScroll);
|
||||
|
||||
LinearLayout *content = contentScroll->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
|
||||
if (showHint_) {
|
||||
auto g = GetI18NCategory(I18NCat::GAME);
|
||||
content->Add(new HintView(g->T("SaveData")));
|
||||
}
|
||||
|
||||
// TODO: If the game info wasn't already loaded, we'll get a bogus fileType here.
|
||||
savedataView_ = contentScroll->Add(new SavedataView(dc, ginfo.get(), ginfo->fileType, true));
|
||||
savedataView_ = content->Add(new SavedataView(dc, ginfo.get(), ginfo->fileType, true));
|
||||
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
|
||||
LinearLayout *buttonRow = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
|
||||
buttonRow->SetSpacing(0);
|
||||
Margins buttonMargins(5, 5, 5, 13); // not sure why we need more at the bottom to make it look right
|
||||
buttonRow->SetSpacing(12);
|
||||
|
||||
buttonRow->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
|
||||
buttonRow->Add(new Choice(di->T("Delete"), ImageID("I_TRASHCAN"), new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Add([this](UI::EventParams &e) {
|
||||
buttonRow->Add(new Choice(di->T("Back"), ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams(1.0f)))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
|
||||
buttonRow->Add(new Choice(di->T("Delete"), ImageID("I_TRASHCAN"), new LinearLayoutParams(1.0f)))->OnClick.Add([this](UI::EventParams &e) {
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
std::shared_ptr<GameInfo> ginfo = g_gameInfoCache->GetInfo(nullptr, savePath_, GameInfoFlags::PARAM_SFO);
|
||||
|
||||
@@ -183,10 +189,11 @@ void SavedataPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
}));
|
||||
});
|
||||
if (System_GetPropertyBool(SYSPROP_CAN_SHOW_FILE)) {
|
||||
buttonRow->Add(new Choice(di->T("Show in folder"), ImageID("I_FOLDER"), new LinearLayoutParams(1.0f, buttonMargins)))->OnClick.Add([this](UI::EventParams &e) {
|
||||
buttonRow->Add(new Choice(di->T("Show in folder"), ImageID("I_FOLDER"), new LinearLayoutParams(1.0f)))->OnClick.Add([this](UI::EventParams &e) {
|
||||
System_ShowFileInFolder(savePath_);
|
||||
});
|
||||
}
|
||||
buttonRow->ApplyRoundCorners();
|
||||
parent->Add(buttonRow);
|
||||
}
|
||||
|
||||
@@ -690,7 +697,7 @@ void SavedataScreen::OnSavedataButtonClick(UI::EventParams &e) {
|
||||
|
||||
// Sanitize the title.
|
||||
std::string title = SanitizeString(ginfo->GetTitle(), StringRestriction::NoLineBreaksOrSpecials, 0, 200);
|
||||
SavedataPopupScreen *popupScreen = new SavedataPopupScreen(gamePath_, Path(e.s), title);
|
||||
SavedataPopupScreen *popupScreen = new SavedataPopupScreen(gamePath_, Path(e.s), false, title);
|
||||
if (e.v) {
|
||||
popupScreen->SetPopupOrigin(e.v);
|
||||
}
|
||||
|
||||
+2
-1
@@ -71,7 +71,7 @@ class SavedataView;
|
||||
|
||||
class SavedataPopupScreen : public UI::PopupScreen {
|
||||
public:
|
||||
SavedataPopupScreen(Path gamePath, Path savePath, std::string_view title);
|
||||
SavedataPopupScreen(Path gamePath, Path savePath, bool showHint, std::string_view title);
|
||||
|
||||
const char *tag() const override { return "SavedataPopup"; }
|
||||
void update() override;
|
||||
@@ -84,6 +84,7 @@ private:
|
||||
SavedataView *savedataView_ = nullptr;
|
||||
Path savePath_;
|
||||
Path gamePath_;
|
||||
bool showHint_ = false;
|
||||
};
|
||||
|
||||
class SavedataScreen : public UITabbedBaseDialogScreen {
|
||||
|
||||
Reference in new issue
Block a user