mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-27 12:18:35 +01:00
Merge pull request #21295 from hrydgard/assorted-fixes
Assorted UI fixes
This commit is contained in:
13 files changed
+161
-89
No files matched your search
@@ -55,6 +55,9 @@ void ScrollView::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec ver
|
||||
if (layoutParams_->height == WRAP_CONTENT)
|
||||
MeasureBySpec(layoutParams_->height, views_[0]->GetMeasuredHeight(), vert, &measuredHeight_);
|
||||
}
|
||||
|
||||
// The below seems misguided and leads to wrong sized scrollviews. Need to investigate if it's needed somewhere...
|
||||
/*
|
||||
if (orientation_ == ORIENT_VERTICAL && vert.type != EXACTLY) {
|
||||
float bestHeight = std::max(views_[0]->GetMeasuredHeight(), views_[0]->GetBounds().h);
|
||||
if (vert.type == AT_MOST)
|
||||
@@ -63,7 +66,7 @@ void ScrollView::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec ver
|
||||
if (measuredHeight_ < bestHeight && layoutParams_->height < 0.0f) {
|
||||
measuredHeight_ = bestHeight;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,8 +279,8 @@ void ScrollView::Draw(UIContext &dc) {
|
||||
// If not anchored at the top of the screen exactly, and not scrolled to the top,
|
||||
// draw a subtle drop shadow to indicate scrollability.
|
||||
|
||||
const float darkness = 0.4f;
|
||||
if (bounds_.y > 0.0f && orientation_ == ORIENT_VERTICAL) {
|
||||
constexpr float darkness = 0.4f;
|
||||
if (shadows_ && bounds_.y > 0.0f && orientation_ == ORIENT_VERTICAL) {
|
||||
float radius = 20.0f;
|
||||
|
||||
Bounds shadowBounds = bounds_;
|
||||
@@ -292,8 +295,8 @@ void ScrollView::Draw(UIContext &dc) {
|
||||
}
|
||||
|
||||
// Same at the bottom.
|
||||
float y2 = dc.GetLayoutBounds().y2();
|
||||
if (bounds_.y2() < y2 && orientation_ == ORIENT_VERTICAL) {
|
||||
const float y2 = dc.GetLayoutBounds().y2();
|
||||
if (shadows_ && bounds_.y2() < y2 && orientation_ == ORIENT_VERTICAL) {
|
||||
float radius = 20.0f;
|
||||
|
||||
Bounds shadowBounds = bounds_;
|
||||
@@ -483,10 +486,10 @@ float ScrollView::ClampedScrollPos(float pos) {
|
||||
float maxPull = bounds_.h * 0.1f;
|
||||
if (pos < 0.0f) {
|
||||
float dist = std::min(-pos * (1.0f / bounds_.h), 1.0f);
|
||||
pull_ = -(sqrt(dist) * maxPull);
|
||||
pull_ = -(sqrtf(dist) * maxPull);
|
||||
} else if (pos > scrollMax) {
|
||||
float dist = std::min((pos - scrollMax) * (1.0f / bounds_.h), 1.0f);
|
||||
pull_ = sqrt(dist) * maxPull;
|
||||
pull_ = sqrtf(dist) * maxPull;
|
||||
} else {
|
||||
pull_ = 0.0f;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,10 @@ public:
|
||||
alignOpposite_ = alignOpposite;
|
||||
}
|
||||
|
||||
void SetShadows(bool shadows) {
|
||||
shadows_ = shadows;
|
||||
}
|
||||
|
||||
NeighborResult FindScrollNeighbor(View *view, const Point2D &target, FocusDirection direction, NeighborResult best) override;
|
||||
|
||||
private:
|
||||
@@ -81,6 +85,7 @@ private:
|
||||
bool alignOpposite_ = false;
|
||||
bool draggingBob_ = false;
|
||||
bool mouseHover_ = false;
|
||||
bool shadows_ = true;
|
||||
|
||||
float barDragStart_ = 0.0f;
|
||||
float barDragOffset_ = 0.0f;
|
||||
|
||||
@@ -636,6 +636,9 @@ bool PSP_InitStart(const CoreParameter &coreParam) {
|
||||
}
|
||||
}
|
||||
|
||||
// Use this to test exit-during-boot and other exceptional cases.
|
||||
// sleep_ms(6000, "test");
|
||||
|
||||
g_CoreParameter.fileType = fileType;
|
||||
|
||||
// TODO: The reason we pass in g_CoreParameter.errorString here is that it's persistent -
|
||||
@@ -720,6 +723,10 @@ BootState PSP_Init(const CoreParameter &coreParam, std::string *error_string) {
|
||||
}
|
||||
}
|
||||
|
||||
BootState PollBootState() {
|
||||
return g_bootState;
|
||||
}
|
||||
|
||||
void PSP_Shutdown(bool success) {
|
||||
// Reduce the risk for weird races with the Windows GE debugger.
|
||||
gpuDebug = nullptr;
|
||||
|
||||
@@ -75,6 +75,9 @@ BootState PSP_InitUpdate(std::string *error_string);
|
||||
// Returns either BootState::Complete or BootState::Failed.
|
||||
BootState PSP_Init(const CoreParameter &coreParam, std::string *error_string);
|
||||
|
||||
// The main thread needs to block on this in some situations, like losing the surface.
|
||||
BootState PollBootState();
|
||||
|
||||
void PSP_Shutdown(bool success);
|
||||
|
||||
FileLoader *PSP_LoadedFile();
|
||||
|
||||
@@ -2874,7 +2874,7 @@ void FramebufferManagerCommon::NotifyRenderResized(const DisplayLayoutConfig &co
|
||||
PSP_CoreParameter().renderHeight = h;
|
||||
PSP_CoreParameter().renderScaleFactor = scaleFactor;
|
||||
|
||||
if (UpdateRenderSize(msaaLevel)) {
|
||||
if (draw_ && UpdateRenderSize(msaaLevel)) {
|
||||
draw_->StopThreads();
|
||||
DestroyAllFBOs();
|
||||
draw_->StartThreads();
|
||||
|
||||
+25
-7
@@ -460,13 +460,20 @@ EmuScreen::~EmuScreen() {
|
||||
std::string gameID = g_paramSFO.GetValueString("DISC_ID");
|
||||
g_Config.TimeTracker().Stop(gameID);
|
||||
|
||||
// Should not be able to quit during boot, as boot can't be cancelled.
|
||||
_dbg_assert_(!bootPending_);
|
||||
if (!bootPending_) {
|
||||
Achievements::UnloadGame();
|
||||
PSP_Shutdown(true);
|
||||
if (bootPending_) {
|
||||
// We probably quit during boot, got blocked in lostdevice, and then didn't end up in update again to call PSP_InitUpdate.
|
||||
// So we need to finish and join the boot thread before we can exit.
|
||||
_dbg_assert_(PollBootState() != BootState::Booting);
|
||||
// Make sure we join the boot thread, by calling PSP_InitUpdate.
|
||||
std::string error_string = "(unknown error)";
|
||||
PSP_InitUpdate(&error_string);
|
||||
ERROR_LOG(Log::G3D, "Quit during boot, not good. %s", error_string.c_str());
|
||||
bootPending_ = false;
|
||||
}
|
||||
|
||||
Achievements::UnloadGame();
|
||||
PSP_Shutdown(true);
|
||||
|
||||
// If achievements are disabled in the global config, let's shut it down here.
|
||||
if (!g_Config.bAchievementsEnable) {
|
||||
Achievements::Shutdown();
|
||||
@@ -1368,6 +1375,13 @@ void EmuScreen::CreateViews() {
|
||||
}
|
||||
|
||||
void EmuScreen::deviceLost() {
|
||||
// If we are currently in the middle of boot, we have to block here!
|
||||
// Otherwise the boot thread will encounter draw_ == nullptr and weird stuff like that.
|
||||
// We're doing this in a very ugly way for now.
|
||||
while (PollBootState() == BootState::Booting) {
|
||||
sleep_ms(100, "device-lost-during-boot");
|
||||
}
|
||||
|
||||
UIScreen::deviceLost();
|
||||
|
||||
if (imguiInited_) {
|
||||
@@ -1634,11 +1648,15 @@ ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) {
|
||||
|
||||
const DeviceOrientation orientation = GetDeviceOrientation();
|
||||
const DisplayLayoutConfig &displayLayoutConfig = g_Config.GetDisplayLayoutConfig(orientation);
|
||||
// We might have a bad viewport after RunEmulation, reset.
|
||||
Viewport viewport{0.0f, 0.0f, (float)g_display.pixel_xres, (float)g_display.pixel_yres, 0.0f, 1.0f};
|
||||
|
||||
if (!skipBufferEffects_ && !ShouldRunEmulation(mode)) {
|
||||
if (gpu) {
|
||||
gpu->CopyDisplayToOutput(displayLayoutConfig);
|
||||
}
|
||||
draw->SetViewport(viewport);
|
||||
draw->SetScissorRect(0, 0, g_display.pixel_xres, g_display.pixel_yres);
|
||||
darken();
|
||||
return screenRenderFlags;
|
||||
}
|
||||
@@ -1649,6 +1667,8 @@ ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) {
|
||||
if (mode & ScreenRenderMode::TOP) {
|
||||
checkPowerDown();
|
||||
}
|
||||
draw->SetViewport(viewport);
|
||||
draw->SetScissorRect(0, 0, g_display.pixel_xres, g_display.pixel_yres);
|
||||
renderUI();
|
||||
return screenRenderFlags;
|
||||
}
|
||||
@@ -1658,8 +1678,6 @@ ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) {
|
||||
screenRenderFlags = RunEmulation(true);
|
||||
}
|
||||
|
||||
// We might have a bad viewport after RunEmulation, reset.
|
||||
Viewport viewport{0.0f, 0.0f, (float)g_display.pixel_xres, (float)g_display.pixel_yres, 0.0f, 1.0f};
|
||||
draw->SetViewport(viewport);
|
||||
|
||||
ProcessQueuedVKeys();
|
||||
|
||||
@@ -1744,9 +1744,19 @@ void TriggerRestart(const char *why, bool editThenRestore, const Path &gamePath)
|
||||
System_RestartApp(param);
|
||||
}
|
||||
|
||||
// From PauseScreen
|
||||
std::string GetConfirmExitMessage();
|
||||
|
||||
void GameSettingsScreen::TriggerRestartOrDo(std::function<void()> callback) {
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
screenManager()->push(new UI::MessagePopupScreen(di->T("Restart"), di->T("Changing this setting requires PPSSPP to restart."), di->T("Restart"), di->T("Cancel"), [=](bool yes) {
|
||||
|
||||
std::string confirmExitMessage = GetConfirmExitMessage();
|
||||
if (!confirmExitMessage.empty()) {
|
||||
confirmExitMessage = "\n\n" + confirmExitMessage;
|
||||
}
|
||||
confirmExitMessage = std::string(di->T("Changing this setting requires PPSSPP to restart.")) + confirmExitMessage;
|
||||
|
||||
screenManager()->push(new UI::MessagePopupScreen(di->T("Restart"), confirmExitMessage, di->T("Restart"), di->T("Cancel"), [=](bool yes) {
|
||||
if (yes) {
|
||||
TriggerRestart("GameSettingsScreen::RenderingBackendYes", editGameSpecificThenRestore_, gamePath_);
|
||||
} else {
|
||||
|
||||
+39
-30
@@ -380,7 +380,7 @@ void GamePauseScreen::OnVKey(VirtKey virtualKeyCode, bool down) {
|
||||
}
|
||||
}
|
||||
|
||||
void GamePauseScreen::CreateSavestateControls(UI::LinearLayout *leftColumnItems) {
|
||||
void GamePauseScreen::CreateSavestateControls(UI::LinearLayout *leftColumnItems, UI::LinearLayout **extraRow) {
|
||||
auto pa = GetI18NCategory(I18NCat::PAUSE);
|
||||
|
||||
using namespace UI;
|
||||
@@ -407,23 +407,39 @@ void GamePauseScreen::CreateSavestateControls(UI::LinearLayout *leftColumnItems)
|
||||
RecreateViews();
|
||||
});
|
||||
}
|
||||
leftColumnItems->Add(new Spacer(0.0));
|
||||
|
||||
LinearLayout *buttonRow = leftColumnItems->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(Margins(10, 0, 0, 0))));
|
||||
*extraRow = nullptr;
|
||||
|
||||
LinearLayout *buttonRow = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(Margins(10, 0, 0, 0)));
|
||||
if (g_Config.bEnableStateUndo && !Achievements::HardcoreModeActive() && NetworkAllowSaveState()) {
|
||||
UI::Choice *loadUndoButton = buttonRow->Add(new Choice(pa->T("Undo last load"), ImageID("I_NAVIGATE_BACK")));
|
||||
UI::Choice *loadUndoButton = buttonRow->Add(new Choice(pa->T("Undo last load"), ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT)));
|
||||
loadUndoButton->SetEnabled(SaveState::HasUndoLoad(saveStatePrefix_));
|
||||
loadUndoButton->OnClick.Handle(this, &GamePauseScreen::OnLoadUndo);
|
||||
loadUndoButton->OnClick.Add([this](UI::EventParams &e) {
|
||||
SaveState::UndoLoad(saveStatePrefix_, &AfterSaveStateAction);
|
||||
TriggerFinish(DR_CANCEL);
|
||||
});
|
||||
|
||||
UI::Choice *saveUndoButton = buttonRow->Add(new Choice(pa->T("Undo last save"), ImageID("I_NAVIGATE_BACK")));
|
||||
UI::Choice *saveUndoButton = buttonRow->Add(new Choice(pa->T("Undo last save"), ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT)));
|
||||
saveUndoButton->SetEnabled(SaveState::HasUndoLastSave(saveStatePrefix_));
|
||||
saveUndoButton->OnClick.Handle(this, &GamePauseScreen::OnLastSaveUndo);
|
||||
saveUndoButton->OnClick.Add([this](UI::EventParams &e) {
|
||||
SaveState::UndoLastSave(saveStatePrefix_);
|
||||
RecreateViews();
|
||||
});
|
||||
}
|
||||
|
||||
if (g_Config.iRewindSnapshotInterval > 0 && !Achievements::HardcoreModeActive() && NetworkAllowSaveState()) {
|
||||
UI::Choice *rewindButton = buttonRow->Add(new Choice(pa->T("Rewind"), ImageID("I_REWIND")));
|
||||
UI::Choice *rewindButton = buttonRow->Add(new Choice(pa->T("Rewind"), ImageID("I_REWIND"), new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT)));
|
||||
rewindButton->SetEnabled(SaveState::CanRewind());
|
||||
rewindButton->OnClick.Handle(this, &GamePauseScreen::OnRewind);
|
||||
rewindButton->OnClick.Add([this](UI::EventParams &e) {
|
||||
SaveState::Rewind(&AfterSaveStateAction);
|
||||
TriggerFinish(DR_CANCEL);
|
||||
});
|
||||
}
|
||||
|
||||
if (buttonRow->GetNumSubviews() == 0) {
|
||||
delete buttonRow;
|
||||
} else {
|
||||
*extraRow = buttonRow;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -476,8 +492,11 @@ void GamePauseScreen::CreateViews() {
|
||||
});
|
||||
}
|
||||
|
||||
ViewGroup *saveStateScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f, scrollMargins));
|
||||
root_->Add(saveStateScroll);
|
||||
ViewGroup *saveScrollContainer = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f, scrollMargins));
|
||||
root_->Add(saveScrollContainer);
|
||||
|
||||
ScrollView *saveStateScroll = saveScrollContainer->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT, 1.0f)));
|
||||
saveStateScroll->SetShadows(false);
|
||||
|
||||
LinearLayout *saveDataScrollItems = new LinearLayoutList(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT));
|
||||
saveStateScroll->Add(saveDataScrollItems);
|
||||
@@ -547,7 +566,11 @@ void GamePauseScreen::CreateViews() {
|
||||
System_LaunchUrl(LaunchUrlType::BROWSER_URL, "https://www.ppsspp.org/docs/troubleshooting/save-state-time-warps");
|
||||
});
|
||||
}
|
||||
CreateSavestateControls(saveDataScrollItems);
|
||||
LinearLayout *extraRow = nullptr;
|
||||
CreateSavestateControls(saveDataScrollItems, &extraRow);
|
||||
if (extraRow) {
|
||||
saveScrollContainer->Add(extraRow);
|
||||
}
|
||||
} else {
|
||||
// Let's show the active challenges.
|
||||
std::set<uint32_t> ids = Achievements::GetActiveChallengeIDs();
|
||||
@@ -782,6 +805,10 @@ int GetUnsavedProgressSeconds() {
|
||||
std::string GetConfirmExitMessage() {
|
||||
std::string confirmMessage;
|
||||
|
||||
if (!PSP_IsInited()) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
int unsavedSeconds = GetUnsavedProgressSeconds();
|
||||
|
||||
// If RAIntegration has dirty info, ask for confirmation.
|
||||
@@ -842,24 +869,6 @@ void GamePauseScreen::OnReportFeedback(UI::EventParams &e) {
|
||||
screenManager()->push(new ReportScreen(gamePath_));
|
||||
}
|
||||
|
||||
void GamePauseScreen::OnRewind(UI::EventParams &e) {
|
||||
SaveState::Rewind(&AfterSaveStateAction);
|
||||
|
||||
TriggerFinish(DR_CANCEL);
|
||||
}
|
||||
|
||||
void GamePauseScreen::OnLoadUndo(UI::EventParams &e) {
|
||||
SaveState::UndoLoad(saveStatePrefix_, &AfterSaveStateAction);
|
||||
|
||||
TriggerFinish(DR_CANCEL);
|
||||
}
|
||||
|
||||
void GamePauseScreen::OnLastSaveUndo(UI::EventParams &e) {
|
||||
SaveState::UndoLastSave(saveStatePrefix_);
|
||||
|
||||
RecreateViews();
|
||||
}
|
||||
|
||||
void GamePauseScreen::OnCreateConfig(UI::EventParams &e) {
|
||||
std::shared_ptr<GameInfo> info = g_gameInfoCache->GetInfo(NULL, gamePath_, GameInfoFlags::PARAM_SFO);
|
||||
if (info->Ready(GameInfoFlags::PARAM_SFO)) {
|
||||
|
||||
+1
-5
@@ -49,16 +49,12 @@ protected:
|
||||
void OnVKey(VirtKey virtualKeyCode, bool down) override;
|
||||
|
||||
private:
|
||||
void CreateSavestateControls(UI::LinearLayout *viewGroup);
|
||||
void CreateSavestateControls(UI::LinearLayout *viewGroup, UI::LinearLayout **extraRow);
|
||||
|
||||
void OnGameSettings(UI::EventParams &e);
|
||||
void OnExit(UI::EventParams &e);
|
||||
void OnReportFeedback(UI::EventParams &e);
|
||||
|
||||
void OnRewind(UI::EventParams &e);
|
||||
void OnLoadUndo(UI::EventParams &e);
|
||||
void OnLastSaveUndo(UI::EventParams &e);
|
||||
|
||||
void OnCreateConfig(UI::EventParams &e);
|
||||
void OnDeleteConfig(UI::EventParams &e);
|
||||
|
||||
|
||||
+14
-11
@@ -88,29 +88,32 @@ static void LoadThemeInfo(const std::vector<Path> &directories) {
|
||||
themeInfos.push_back(info);
|
||||
};
|
||||
|
||||
for (size_t d = 0; d < directories.size(); d++) {
|
||||
for (const auto &d : directories) {
|
||||
std::vector<File::FileInfo> fileInfo;
|
||||
g_VFS.GetFileListing(directories[d].c_str(), &fileInfo, "ini:");
|
||||
g_VFS.GetFileListing(d.c_str(), &fileInfo, "ini:");
|
||||
|
||||
if (fileInfo.empty()) {
|
||||
File::GetFilesInDir(directories[d], &fileInfo, "ini:");
|
||||
File::GetFilesInDir(d, &fileInfo, "ini:");
|
||||
}
|
||||
|
||||
for (size_t f = 0; f < fileInfo.size(); f++) {
|
||||
for (const auto &f : fileInfo) {
|
||||
IniFile ini;
|
||||
bool success = false;
|
||||
if (fileInfo[f].isDirectory)
|
||||
if (f.isDirectory) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Path name = fileInfo[f].fullName;
|
||||
Path path = directories[d];
|
||||
Path name(f.fullName);
|
||||
Path path = d;
|
||||
// Hack around Android VFS path bug. really need to redesign this.
|
||||
if (name.ToString().substr(0, 7) == "assets/")
|
||||
if (name.ToString().substr(0, 7) == "assets/") {
|
||||
name = Path(name.ToString().substr(7));
|
||||
if (path.ToString().substr(0, 7) == "assets/")
|
||||
}
|
||||
if (path.ToString().substr(0, 7) == "assets/") {
|
||||
path = Path(path.ToString().substr(7));
|
||||
}
|
||||
|
||||
if (ini.LoadFromVFS(g_VFS, name.ToString()) || ini.Load(fileInfo[f].fullName)) {
|
||||
if (ini.LoadFromVFS(g_VFS, name.ToString()) || ini.Load(f.fullName)) {
|
||||
success = true;
|
||||
}
|
||||
|
||||
@@ -245,7 +248,7 @@ void UpdateTheme() {
|
||||
ui_theme.popupSliderFocusedColor = themeInfo.uPopupSliderFocusedColor;
|
||||
}
|
||||
|
||||
UI::Theme *GetTheme() {
|
||||
const UI::Theme *GetTheme() {
|
||||
return &ui_theme;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -27,4 +27,4 @@ void ReloadAllThemeInfo();
|
||||
|
||||
std::vector<std::string> GetThemeInfoNames();
|
||||
void UpdateTheme();
|
||||
UI::Theme *GetTheme();
|
||||
const UI::Theme *GetTheme();
|
||||
@@ -48,6 +48,7 @@ import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
@@ -1501,26 +1502,24 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList
|
||||
}
|
||||
|
||||
private AlertDialog.Builder createDialogBuilderWithDeviceThemeAndUiVisibility() {
|
||||
AlertDialog.Builder bld = new AlertDialog.Builder(this, AlertDialog.THEME_DEVICE_DEFAULT_DARK);
|
||||
bld.setOnDismissListener(dialog -> updateSystemUiVisibility());
|
||||
return bld;
|
||||
return new AlertDialog.Builder(this, AlertDialog.THEME_DEVICE_DEFAULT_DARK);
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.M)
|
||||
private AlertDialog.Builder createDialogBuilderNew() {
|
||||
AlertDialog.Builder bld = new AlertDialog.Builder(this, android.R.style.Theme_DeviceDefault_Dialog_Alert);
|
||||
bld.setOnDismissListener(dialog -> updateSystemUiVisibility());
|
||||
return bld;
|
||||
return new AlertDialog.Builder(this, android.R.style.Theme_DeviceDefault_Dialog_Alert);
|
||||
}
|
||||
|
||||
private AlertDialog.Builder createDialogBuilder() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
return createDialogBuilderNew();
|
||||
} else {
|
||||
return createDialogBuilderWithDeviceThemeAndUiVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
// The return value is sent to C++ via requestID.
|
||||
public void inputBox(final int requestId, final String title, String defaultText, String defaultAction) {
|
||||
// Workaround for issue #13363 to fix Split/Second game start
|
||||
if (isVRDevice()) {
|
||||
NativeApp.sendRequestResult(requestId, false, defaultText, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
final FrameLayout fl = new FrameLayout(this);
|
||||
final EditText input = new EditText(this);
|
||||
input.setGravity(Gravity.CENTER);
|
||||
@@ -1530,39 +1529,52 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList
|
||||
fl.addView(input, editBoxLayout);
|
||||
|
||||
input.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
input.setImeOptions(EditorInfo.IME_ACTION_DONE);
|
||||
input.setText(defaultText);
|
||||
input.setFocusableInTouchMode(true);
|
||||
input.requestFocus();
|
||||
|
||||
input.selectAll();
|
||||
//input.setSelection(input.getText().length());
|
||||
|
||||
AlertDialog.Builder bld;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
bld = createDialogBuilderNew();
|
||||
} else {
|
||||
bld = createDialogBuilderWithDeviceThemeAndUiVisibility();
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = bld
|
||||
AlertDialog.Builder builder = createDialogBuilder()
|
||||
.setView(fl)
|
||||
.setTitle(title)
|
||||
.setPositiveButton(defaultAction, (d, which) -> {
|
||||
Log.i(TAG, "input box successful");
|
||||
NativeApp.sendRequestResult(requestId, true, input.getText().toString(), 0);
|
||||
d.dismiss(); // It's OK that this will cause an extra dismiss message. It'll be ignored since the request number has already been processed.
|
||||
// Dismiss happens automatically.
|
||||
})
|
||||
.setNegativeButton("Cancel", (d, which) -> {
|
||||
Log.i(TAG, "input box cancelled");
|
||||
NativeApp.sendRequestResult(requestId, false, "", 0);
|
||||
d.cancel();
|
||||
});
|
||||
builder.setOnDismissListener(d -> {
|
||||
builder.setOnDismissListener( d -> {
|
||||
Log.i(TAG, "input box dismissed");
|
||||
// This will be ignored if we already sent a success.
|
||||
NativeApp.sendRequestResult(requestId, false, "", 0);
|
||||
updateSystemUiVisibility();
|
||||
});
|
||||
AlertDialog dlg = builder.create();
|
||||
|
||||
AlertDialog dlg = builder.create();
|
||||
input.setOnEditorActionListener((v, actionId, event) -> {
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||
Log.i(TAG, "input box successful via Keyboard Done");
|
||||
NativeApp.sendRequestResult(requestId, true, input.getText().toString(), 0);
|
||||
|
||||
// We must dismiss the dialog manually here
|
||||
dlg.dismiss();
|
||||
return true; // Consume the event
|
||||
}
|
||||
return false;
|
||||
});
|
||||
dlg.setCancelable(true);
|
||||
Window wnd = dlg.getWindow();
|
||||
if (wnd != null) {
|
||||
wnd.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
|
||||
}
|
||||
try {
|
||||
dlg.show();
|
||||
input.requestFocus();
|
||||
} catch (Exception e) {
|
||||
NativeApp.reportException(e, "AlertDialog");
|
||||
}
|
||||
@@ -1711,6 +1723,12 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList
|
||||
title = param[1];
|
||||
if (param.length > 2)
|
||||
defString = param[2];
|
||||
// Workaround for issue #13363 to fix Split/Second game start - it requires text input
|
||||
// but we don't support it on VR devices.
|
||||
if (isVRDevice()) {
|
||||
NativeApp.sendRequestResult(requestID, false, defString, 0);
|
||||
return true;
|
||||
}
|
||||
Log.i(TAG, "Launching inputbox: #" + requestID + " " + title + " " + defString);
|
||||
inputBox(requestID, title, defString, "OK");
|
||||
return true;
|
||||
|
||||
+1
-1
Submodule ext/libchdr updated: 8bba7745d7...7891cbee2e.
Reference in new issue
Block a user