started conversion to new navi drawer

This commit is contained in:
izzy2lost
2025-09-10 09:24:01 -04:00
parent 1735141404
commit 1c676f1250
17 changed files with 831 additions and 369 deletions
+1 -1
View File
@@ -82,7 +82,7 @@ android {
dependencies {
implementation 'androidx.appcompat:appcompat:1.7.1'
implementation 'com.google.android.material:material:1.12.0'
implementation 'com.google.android.material:material:1.14.0-alpha04'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
implementation 'androidx.documentfile:documentfile:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.4.0'
@@ -26,6 +26,9 @@ import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.PagerSnapHelper;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.button.MaterialButtonToggleGroup;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import androidx.core.view.GravityCompat;
import java.util.Locale;
import java.util.ArrayList;
import java.util.Arrays;
@@ -374,13 +377,93 @@ public class GamesCoverDialogFragment extends DialogFragment {
});
View btnHome = root.findViewById(R.id.btn_home);
if (btnHome != null) btnHome.setOnClickListener(v -> dismissAllowingStateLoss());
if (btnHome != null) btnHome.setOnClickListener(v -> {
try {
androidx.drawerlayout.widget.DrawerLayout drawer = root.findViewById(R.id.dlg_drawer_layout);
if (drawer != null) drawer.openDrawer(GravityCompat.START);
} catch (Throwable ignored) {}
});
// Wire in-dialog navigation header actions to mirror main drawer
try {
com.google.android.material.navigation.NavigationView nav = root.findViewById(R.id.dialog_nav_view);
if (nav != null) {
View header = (nav.getHeaderCount() > 0) ? nav.getHeaderView(0) : nav.inflateHeaderView(R.layout.drawer_header_settings);
if (header != null) {
View btnPower = header.findViewById(R.id.drawer_btn_power);
if (btnPower != null) {
btnPower.setOnClickListener(v -> {
new MaterialAlertDialogBuilder(requireContext(),
com.google.android.material.R.style.ThemeOverlay_Material3_MaterialAlertDialog)
.setTitle("Power Off")
.setMessage("Quit the app?")
.setNegativeButton("Cancel", null)
.setPositiveButton("Quit", (d,w) -> { try { NativeApp.shutdown(); } catch (Throwable ignored) {} if (getActivity()!=null){ getActivity().finishAffinity(); getActivity().finishAndRemoveTask(); } System.exit(0); })
.show();
});
}
View btnReboot = header.findViewById(R.id.drawer_btn_reboot);
if (btnReboot != null) {
btnReboot.setOnClickListener(v -> {
new MaterialAlertDialogBuilder(requireContext(),
com.google.android.material.R.style.ThemeOverlay_Material3_MaterialAlertDialog)
.setTitle("Reboot")
.setMessage("Restart the current game?")
.setNegativeButton("Cancel", null)
.setPositiveButton("Reboot", (d,w) -> { if (getActivity() instanceof MainActivity) { ((MainActivity) getActivity()).rebootEmu(); } })
.show();
});
}
MaterialButtonToggleGroup tg = header.findViewById(R.id.drawer_tg_renderer);
View tbAt = header.findViewById(R.id.drawer_tb_at);
View tbVk = header.findViewById(R.id.drawer_tb_vk);
View tbGl = header.findViewById(R.id.drawer_tb_gl);
View tbSw = header.findViewById(R.id.drawer_tb_sw);
if (tg != null) {
int current = -1;
try { current = NativeApp.getCurrentRenderer(); } catch (Throwable ignored) {}
if (current == 14 && tbVk != null) tg.check(tbVk.getId());
else if (current == 12 && tbGl != null) tg.check(tbGl.getId());
else if (current == 13 && tbSw != null) tg.check(tbSw.getId());
else if (tbAt != null) tg.check(tbAt.getId());
tg.addOnButtonCheckedListener((group, checkedId, isChecked) -> {
if (!isChecked) return;
int r = -1;
if (checkedId == (tbVk != null ? tbVk.getId() : -2)) r = 14;
else if (checkedId == (tbGl != null ? tbGl.getId() : -2)) r = 12;
else if (checkedId == (tbSw != null ? tbSw.getId() : -2)) r = 13;
else r = -1;
try {
requireContext().getSharedPreferences("app_prefs", Context.MODE_PRIVATE).edit().putInt("renderer", r).apply();
NativeApp.renderGpu(r);
} catch (Throwable ignored) {}
});
}
View btnGameState = header.findViewById(R.id.drawer_btn_game_state);
if (btnGameState != null) {
btnGameState.setOnClickListener(v -> {
try { new SavesDialogFragment().show(getParentFragmentManager(), "saves_dialog"); } catch (Throwable ignored) {}
});
}
}
}
} catch (Throwable ignored) {}
View btnDownload = root.findViewById(R.id.btn_download);
if (btnDownload != null) btnDownload.setOnClickListener(v -> startDownloadCovers());
return root;
}
// Public API to open the in-dialog navigation drawer from other components
public void openDialogDrawer() {
try {
View root = getView();
if (root == null) return;
androidx.drawerlayout.widget.DrawerLayout drawer = root.findViewById(R.id.dlg_drawer_layout);
if (drawer != null) drawer.openDrawer(androidx.core.view.GravityCompat.START);
} catch (Throwable ignored) {}
}
private void buildLettersAndBind() {
letters.clear();
boolean hasHash = false;
@@ -38,6 +38,8 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.documentfile.provider.DocumentFile;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.core.view.GravityCompat;
import androidx.activity.OnBackPressedCallback;
import com.google.android.material.button.MaterialButton;
@@ -50,6 +52,8 @@ import android.provider.OpenableColumns;
import org.json.JSONArray;
import org.json.JSONException;
import androidx.fragment.app.FragmentManager;
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.button.MaterialButtonToggleGroup;
import java.util.List;
import java.util.Locale;
@@ -99,7 +103,7 @@ public class MainActivity extends AppCompatActivity implements GamesCoverDialogF
// Views present in both layouts
View quick = findViewById(R.id.ll_quick_actions);
View btnSettings = findViewById(R.id.btn_settings);
View btnControls = findViewById(R.id.btn_toggle_controls);
// Visibility toggle removed; no dependency on it for constraints
View llJoy = findViewById(R.id.ll_pad_joy);
View llDpad = findViewById(R.id.ll_pad_dpad);
View llRight = findViewById(R.id.ll_pad_right_buttons);
@@ -107,17 +111,16 @@ public class MainActivity extends AppCompatActivity implements GamesCoverDialogF
// Use helper dp()
if (quick != null && btnSettings != null && btnControls != null) {
if (quick != null && btnSettings != null) {
ConstraintLayout.LayoutParams lp = safeCLP(quick);
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
// Between settings and controls, top-aligned
// Top-aligned row stretching from settings to end
lp.width = 0; // chain between start/end
lp.topToTop = btnSettings.getId();
lp.topToBottom = ConstraintLayout.LayoutParams.UNSET;
lp.startToEnd = btnSettings.getId();
lp.endToStart = btnControls.getId();
lp.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
lp.startToStart = ConstraintLayout.LayoutParams.UNSET;
lp.endToEnd = ConstraintLayout.LayoutParams.UNSET;
lp.topMargin = dp(0);
lp.horizontalChainStyle = ConstraintLayout.LayoutParams.CHAIN_PACKED;
} else {
@@ -423,6 +426,21 @@ public class MainActivity extends AppCompatActivity implements GamesCoverDialogF
}
updateUiForControllerPresence();
// After initial BIOS auto-boot, gently open the Games dialog
// Only when setup is complete and this is app launch (not rotation)
if (getSharedPreferences("app_prefs", MODE_PRIVATE).getBoolean("first_run_done", false)) {
try {
final View decor = (getWindow() != null) ? getWindow().getDecorView() : null;
if (decor != null) {
decor.postDelayed(() -> {
if (!isFinishing() && !mSetupWizardActive) {
openGamesDialog();
}
}, 1600); // small delay to let BIOS boot briefly
}
} catch (Throwable ignored) {}
}
// Show first-run setup wizard if needed
if (!getSharedPreferences("app_prefs", MODE_PRIVATE).getBoolean("first_run_done", false)) {
SetupWizardDialogFragment f = SetupWizardDialogFragment.newInstance();
@@ -457,86 +475,85 @@ public class MainActivity extends AppCompatActivity implements GamesCoverDialogF
}
private void makeButtonTouch() {
MaterialButton btn_file = findViewById(R.id.btn_file);
if(btn_file != null) {
// Tap: show games list (from persisted folder). If none, prompt to pick folder.
btn_file.setOnClickListener(v -> {
SharedPreferences prefs = getSharedPreferences("app_prefs", MODE_PRIVATE);
String folderUri = prefs.getString("games_folder_uri", null);
if (TextUtils.isEmpty(folderUri)) {
pickGamesFolder();
return;
}
showGamesListOrReselect(Uri.parse(folderUri));
});
// Long-press: reselect games folder
btn_file.setOnLongClickListener(v -> {
pickGamesFolder();
return true;
});
}
// SAVES button removed from main UI; access Save States via drawer or Quick Actions
// Combined saves dialog
MaterialButton btn_saves = findViewById(R.id.btn_saves);
if(btn_saves != null) {
btn_saves.setOnClickListener(v -> {
SavesDialogFragment dialog = new SavesDialogFragment();
dialog.show(getSupportFragmentManager(), "saves_dialog");
});
// Long-press: choose SAF data folder for app files (covers/resources/etc)
btn_saves.setOnLongClickListener(v -> {
pickDataRootFolder();
return true;
});
}
// BIOS button repurposed: short tap toggles renderer, long-press picks BIOS folder
MaterialButton btn_bios = findViewById(R.id.btn_bios);
if (btn_bios != null) {
btn_bios.setOnClickListener(v -> {
int current = getCurrentRendererPref();
int next;
// Cycle: AUTO(-1) -> VK(14) -> OGL(12) -> SW(13) -> AUTO
if (current == -1) next = 14;
else if (current == 14) next = 12;
else if (current == 12) next = 13;
else next = -1;
setRendererAndSave(next);
});
btn_bios.setOnLongClickListener(v -> {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
| Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
startActivityResultBiosFolderPick.launch(intent);
return true;
});
}
// Settings button opens dialog
// Menu button opens left drawer
MaterialButton btn_settings = findViewById(R.id.btn_settings);
if (btn_settings != null) {
btn_settings.setOnClickListener(v -> {
FragmentManager fm = getSupportFragmentManager();
SettingsDialogFragment dialog = new SettingsDialogFragment();
dialog.show(fm, "settings_dialog");
});
// Long-press to open Cheats manager
btn_settings.setOnLongClickListener(v -> {
FragmentManager fm2 = getSupportFragmentManager();
CheatsDialogFragment cd = new CheatsDialogFragment();
cd.show(fm2, "cheats_dialog");
return true;
});
}
// Toggle all UI visibility (including controls)
MaterialButton btnToggleControls = findViewById(R.id.btn_toggle_controls);
if (btnToggleControls != null) {
btnToggleControls.setOnClickListener(v -> {
toggleAllUIVisibility();
try {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (drawer != null) drawer.openDrawer(androidx.core.view.GravityCompat.START);
} catch (Throwable ignored) {}
});
}
// Wire left drawer header controls (title/power/reboot/renderer)
try {
NavigationView nav = findViewById(R.id.nav_view);
if (nav != null) {
View header = (nav.getHeaderCount() > 0) ? nav.getHeaderView(0) : nav.inflateHeaderView(R.layout.drawer_header_settings);
if (header != null) {
View btnPower = header.findViewById(R.id.drawer_btn_power);
if (btnPower != null) {
btnPower.setOnClickListener(v -> {
new MaterialAlertDialogBuilder(this)
.setTitle("Power Off")
.setMessage("Quit the app?")
.setNegativeButton("Cancel", null)
.setPositiveButton("Quit", (d,w) -> { try { NativeApp.shutdown(); } catch (Throwable ignored) {} finishAffinity(); finishAndRemoveTask(); System.exit(0); })
.show();
});
}
View btnReboot = header.findViewById(R.id.drawer_btn_reboot);
if (btnReboot != null) {
btnReboot.setOnClickListener(v -> {
new MaterialAlertDialogBuilder(this)
.setTitle("Reboot")
.setMessage("Restart the current game?")
.setNegativeButton("Cancel", null)
.setPositiveButton("Reboot", (d,w) -> rebootEmu())
.show();
});
}
MaterialButtonToggleGroup tg = header.findViewById(R.id.drawer_tg_renderer);
View btnGameState = header.findViewById(R.id.drawer_btn_game_state);
View tbAt = header.findViewById(R.id.drawer_tb_at);
View tbVk = header.findViewById(R.id.drawer_tb_vk);
View tbGl = header.findViewById(R.id.drawer_tb_gl);
View tbSw = header.findViewById(R.id.drawer_tb_sw);
if (tg != null) {
int current = -1;
try { current = NativeApp.getCurrentRenderer(); } catch (Throwable ignored) {}
if (current == 14 && tbVk != null) tg.check(tbVk.getId());
else if (current == 12 && tbGl != null) tg.check(tbGl.getId());
else if (current == 13 && tbSw != null) tg.check(tbSw.getId());
else if (tbAt != null) tg.check(tbAt.getId());
tg.addOnButtonCheckedListener((group, checkedId, isChecked) -> {
if (!isChecked) return;
int r = -1;
if (checkedId == (tbVk != null ? tbVk.getId() : -2)) r = 14;
else if (checkedId == (tbGl != null ? tbGl.getId() : -2)) r = 12;
else if (checkedId == (tbSw != null ? tbSw.getId() : -2)) r = 13;
else r = -1;
try {
getSharedPreferences("app_prefs", MODE_PRIVATE).edit().putInt("renderer", r).apply();
NativeApp.renderGpu(r);
} catch (Throwable ignored) {}
});
}
if (btnGameState != null) {
btnGameState.setOnClickListener(v -> {
try {
SavesDialogFragment dialog = new SavesDialogFragment();
dialog.show(getSupportFragmentManager(), "saves_dialog");
} catch (Throwable ignored) {}
});
}
}
}
} catch (Throwable ignored) {}
// Visibility toggle removed
// PAD
MaterialButton btn_pad_select = findViewById(R.id.btn_pad_select);
@@ -711,7 +728,7 @@ public class MainActivity extends AppCompatActivity implements GamesCoverDialogF
}
}
private boolean allUIHidden = false;
// Visibility toggle removed; no global hidden state flag
private void setControlsVisible(boolean visible) {
int vis = visible ? View.VISIBLE : View.GONE;
@@ -726,43 +743,7 @@ public class MainActivity extends AppCompatActivity implements GamesCoverDialogF
if (llJoy != null) llJoy.setVisibility(vis);
}
private void toggleAllUIVisibility() {
allUIHidden = !allUIHidden;
int vis = allUIHidden ? View.GONE : View.VISIBLE;
boolean hasController = isAnyControllerConnected();
// Hide/show all UI elements except the toggle button itself
View btnSettings = findViewById(R.id.btn_settings);
MaterialButton btnToggleControls = findViewById(R.id.btn_toggle_controls);
View btnFile = findViewById(R.id.btn_file);
View btnBios = findViewById(R.id.btn_bios);
View btnSaves = findViewById(R.id.btn_saves);
View llQuickActions = findViewById(R.id.ll_quick_actions);
if (btnSettings != null) btnSettings.setVisibility(vis);
// Keep toggle button visible but change its icon
if (btnToggleControls != null) {
// Change icon based on visibility state
int iconRes = allUIHidden ? R.drawable.visibility_off_24px : R.drawable.visibility_24px;
btnToggleControls.setIcon(ContextCompat.getDrawable(this, iconRes));
}
if (btnFile != null) btnFile.setVisibility(vis);
if (btnBios != null) btnBios.setVisibility(vis);
if (btnSaves != null) btnSaves.setVisibility(vis);
if (llQuickActions != null) llQuickActions.setVisibility(vis);
// Hide/show on-screen controls
if (!allUIHidden) {
// When showing with a controller connected, keep touch controls hidden
setControlsVisible(!hasController);
} else {
// When hiding all UI, also hide controls
setControlsVisible(false);
}
// Update renderer label when UI toggled back on
if (!allUIHidden) updateRendererButtonLabel();
}
// Removed visibility toggle function
// --- Controller presence handling ---
private final InputManager.InputDeviceListener mInputDeviceListener = new InputManager.InputDeviceListener() {
@@ -820,24 +801,11 @@ public class MainActivity extends AppCompatActivity implements GamesCoverDialogF
int vis = hasController ? View.GONE : View.VISIBLE;
View btnSettings = findViewById(R.id.btn_settings);
View btnFile = findViewById(R.id.btn_file);
View btnBios = findViewById(R.id.btn_bios);
View btnSaves = findViewById(R.id.btn_saves);
MaterialButton btnToggle = findViewById(R.id.btn_toggle_controls);
View llQuickActions = findViewById(R.id.ll_quick_actions);
if (btnSettings != null) btnSettings.setVisibility(vis);
if (btnFile != null) btnFile.setVisibility(vis);
if (btnBios != null) btnBios.setVisibility(vis);
if (btnSaves != null) btnSaves.setVisibility(vis);
// Keep menu (settings) button visible even when a controller is connected
if (btnSettings != null) btnSettings.setVisibility(View.VISIBLE);
if (llQuickActions != null) llQuickActions.setVisibility(vis);
if (btnToggle != null) btnToggle.setVisibility(View.VISIBLE); // always visible
// Set toggle icon and internal state
if (btnToggle != null) {
int iconRes = hasController ? R.drawable.visibility_off_24px : R.drawable.visibility_24px;
btnToggle.setIcon(ContextCompat.getDrawable(this, iconRes));
}
allUIHidden = hasController;
// Hide on-screen touch controls when a physical controller is connected
setControlsVisible(!hasController);
@@ -858,22 +826,10 @@ public class MainActivity extends AppCompatActivity implements GamesCoverDialogF
private void updateRendererButtonLabel() {
MaterialButton btn_bios = findViewById(R.id.btn_bios);
if (btn_bios != null) {
int current = getCurrentRendererPref();
try {
// Prefer runtime renderer from core to reflect per-game overrides
int runtime = NativeApp.getCurrentRenderer();
// Only accept expected values
if (runtime == -1 || runtime == 12 || runtime == 13 || runtime == 14) {
current = runtime;
}
} catch (Throwable ignored) {}
btn_bios.setText(rendererShortLabel(current));
}
}
// No-op: renderer label now handled in drawer
}
// Public minimal UI refresh hook for dialogs
// Public minimal UI refresh hook for dialogs
public void refreshQuickUi() {
updateRendererButtonLabel();
}
@@ -1750,3 +1706,8 @@ public class MainActivity extends AppCompatActivity implements GamesCoverDialogF
}
}
@@ -11,6 +11,9 @@ import androidx.fragment.app.DialogFragment;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.materialswitch.MaterialSwitch;
import android.widget.Spinner;
import android.widget.ArrayAdapter;
public class QuickActionsDialogFragment extends DialogFragment {
@@ -19,15 +22,156 @@ public class QuickActionsDialogFragment extends DialogFragment {
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
View view = getLayoutInflater().inflate(R.layout.dialog_quick_actions, null, false);
MaterialButton btnOpenGames = view.findViewById(R.id.btn_open_games);
MaterialButton btnExitToMenu = view.findViewById(R.id.btn_exit_to_menu);
MaterialButton btnRestartGame = view.findViewById(R.id.btn_restart_game);
MaterialButton btnQuitApp = view.findViewById(R.id.btn_quit_app);
MaterialButton btnPower = view.findViewById(R.id.btn_quick_power);
MaterialButton btnReboot = view.findViewById(R.id.btn_quick_reboot);
com.google.android.material.button.MaterialButtonToggleGroup tgRenderer = view.findViewById(R.id.qa_tg_renderer);
View tbAt = view.findViewById(R.id.qa_tb_at);
View tbVk = view.findViewById(R.id.qa_tb_vk);
View tbGl = view.findViewById(R.id.qa_tb_gl);
View tbSw = view.findViewById(R.id.qa_tb_sw);
MaterialButton btnGames = view.findViewById(R.id.btn_quick_games);
MaterialButton btnSaves = view.findViewById(R.id.btn_quick_saves);
MaterialButton btnCancel = view.findViewById(R.id.btn_cancel);
Spinner spAspect = view.findViewById(R.id.qa_sp_aspect_ratio);
Spinner spBlending = view.findViewById(R.id.qa_sp_blending_accuracy);
MaterialSwitch swWide = view.findViewById(R.id.qa_sw_widescreen);
MaterialSwitch swNoInt = view.findViewById(R.id.qa_sw_no_interlacing);
MaterialSwitch swLoadTex = view.findViewById(R.id.qa_sw_load_textures);
MaterialSwitch swAsyncTex = view.findViewById(R.id.qa_sw_async_textures);
MaterialSwitch swPrecache = view.findViewById(R.id.qa_sw_precache_textures);
// Open Games/Covers dialog
if (btnOpenGames != null) {
btnOpenGames.setOnClickListener(v -> {
// Power (Quit App)
if (btnPower != null) {
btnPower.setOnClickListener(v -> new MaterialAlertDialogBuilder(requireContext(),
com.google.android.material.R.style.ThemeOverlay_Material3_MaterialAlertDialog)
.setCustomTitle(UiUtils.centeredDialogTitle(requireContext(), "Power Off"))
.setMessage("Quit PSX2?")
.setNegativeButton("Cancel", null)
.setPositiveButton("Quit", (d, w) -> { quitApp(); dismissAllowingStateLoss(); })
.show());
}
// Reboot game
if (btnReboot != null) {
btnReboot.setOnClickListener(v -> new MaterialAlertDialogBuilder(requireContext(),
com.google.android.material.R.style.ThemeOverlay_Material3_MaterialAlertDialog)
.setCustomTitle(UiUtils.centeredDialogTitle(requireContext(), "Reboot"))
.setMessage("Restart the current game?")
.setNegativeButton("Cancel", null)
.setPositiveButton("Reboot", (d, w) -> {
if (requireActivity() instanceof MainActivity) {
((MainActivity) requireActivity()).rebootEmu();
} else { NativeApp.shutdown(); }
dismissAllowingStateLoss();
})
.show());
}
// Renderer toggle: set current and handle changes
if (tgRenderer != null) {
int current = -1;
try { current = NativeApp.getCurrentRenderer(); } catch (Throwable ignored) {}
if (current == 14 && tbVk != null) tgRenderer.check(tbVk.getId());
else if (current == 12 && tbGl != null) tgRenderer.check(tbGl.getId());
else if (current == 13 && tbSw != null) tgRenderer.check(tbSw.getId());
else if (tbAt != null) tgRenderer.check(tbAt.getId());
tgRenderer.addOnButtonCheckedListener((group, checkedId, isChecked) -> {
if (!isChecked) return;
int r = -1;
if (checkedId == (tbVk != null ? tbVk.getId() : -2)) r = 14;
else if (checkedId == (tbGl != null ? tbGl.getId() : -2)) r = 12;
else if (checkedId == (tbSw != null ? tbSw.getId() : -2)) r = 13;
else r = -1;
try {
requireContext().getSharedPreferences("app_prefs", android.content.Context.MODE_PRIVATE)
.edit().putInt("renderer", r).apply();
NativeApp.renderGpu(r);
} catch (Throwable ignored) {}
});
}
// Aspect Ratio spinner
if (spAspect != null) {
ArrayAdapter<CharSequence> aspectAdapter = ArrayAdapter.createFromResource(requireContext(),
R.array.aspect_ratio_entries, android.R.layout.simple_spinner_item);
aspectAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spAspect.setAdapter(aspectAdapter);
int savedAspect = requireContext().getSharedPreferences("app_prefs", android.content.Context.MODE_PRIVATE)
.getInt("aspect_ratio", 1);
if (savedAspect < 0 || savedAspect >= aspectAdapter.getCount()) savedAspect = 1;
spAspect.setSelection(savedAspect);
spAspect.setOnItemSelectedListener(new android.widget.AdapterView.OnItemSelectedListener() {
@Override public void onItemSelected(android.widget.AdapterView<?> parent, View view1, int position, long id) {
requireContext().getSharedPreferences("app_prefs", android.content.Context.MODE_PRIVATE)
.edit().putInt("aspect_ratio", position).apply();
try { NativeApp.setAspectRatio(position); } catch (Throwable ignored) {}
}
@Override public void onNothingSelected(android.widget.AdapterView<?> parent) {}
});
}
// Blending Accuracy spinner
if (spBlending != null) {
ArrayAdapter<CharSequence> blendAdapter = ArrayAdapter.createFromResource(requireContext(),
R.array.blending_accuracy_entries, android.R.layout.simple_spinner_item);
blendAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spBlending.setAdapter(blendAdapter);
int savedBlend = requireContext().getSharedPreferences("app_prefs", android.content.Context.MODE_PRIVATE)
.getInt("blending_accuracy", 1);
if (savedBlend < 0 || savedBlend >= blendAdapter.getCount()) savedBlend = 1;
spBlending.setSelection(savedBlend);
spBlending.setOnItemSelectedListener(new android.widget.AdapterView.OnItemSelectedListener() {
@Override public void onItemSelected(android.widget.AdapterView<?> parent, View view12, int position, long id) {
requireContext().getSharedPreferences("app_prefs", android.content.Context.MODE_PRIVATE)
.edit().putInt("blending_accuracy", position).apply();
try { NativeApp.setBlendingAccuracy(position); } catch (Throwable ignored) {}
}
@Override public void onNothingSelected(android.widget.AdapterView<?> parent) {}
});
}
// Switches: widescreen, no interlacing, textures
final android.content.SharedPreferences prefs = requireContext().getSharedPreferences("app_prefs", android.content.Context.MODE_PRIVATE);
if (swWide != null) {
swWide.setChecked(prefs.getBoolean("widescreen_patches", true));
swWide.setOnCheckedChangeListener((buttonView, isChecked) -> {
prefs.edit().putBoolean("widescreen_patches", isChecked).apply();
try { NativeApp.setWidescreenPatches(isChecked); } catch (Throwable ignored) {}
});
}
if (swNoInt != null) {
swNoInt.setChecked(prefs.getBoolean("no_interlacing_patches", true));
swNoInt.setOnCheckedChangeListener((buttonView, isChecked) -> {
prefs.edit().putBoolean("no_interlacing_patches", isChecked).apply();
try { NativeApp.setNoInterlacingPatches(isChecked); } catch (Throwable ignored) {}
});
}
if (swLoadTex != null) {
swLoadTex.setChecked(prefs.getBoolean("load_textures", false));
swLoadTex.setOnCheckedChangeListener((buttonView, isChecked) -> {
prefs.edit().putBoolean("load_textures", isChecked).apply();
try { NativeApp.setLoadTextures(isChecked); } catch (Throwable ignored) {}
});
}
if (swAsyncTex != null) {
swAsyncTex.setChecked(prefs.getBoolean("async_texture_loading", true));
swAsyncTex.setOnCheckedChangeListener((buttonView, isChecked) -> {
prefs.edit().putBoolean("async_texture_loading", isChecked).apply();
try { NativeApp.setAsyncTextureLoading(isChecked); } catch (Throwable ignored) {}
});
}
if (swPrecache != null) {
swPrecache.setChecked(prefs.getBoolean("precache_textures", false));
swPrecache.setOnCheckedChangeListener((buttonView, isChecked) -> {
prefs.edit().putBoolean("precache_textures", isChecked).apply();
try { NativeApp.setPrecacheTextureReplacements(isChecked); } catch (Throwable ignored) {}
});
}
// Games: open covers dialog
if (btnGames != null) {
btnGames.setOnClickListener(v -> {
if (requireActivity() instanceof MainActivity) {
((MainActivity) requireActivity()).openGamesDialog();
}
@@ -35,62 +179,16 @@ public class QuickActionsDialogFragment extends DialogFragment {
});
}
// Exit to Menu - not implemented yet, show placeholder
if (btnExitToMenu != null) {
btnExitToMenu.setOnClickListener(v -> {
new MaterialAlertDialogBuilder(requireContext(),
com.google.android.material.R.style.ThemeOverlay_Material3_MaterialAlertDialog)
.setCustomTitle(UiUtils.centeredDialogTitle(requireContext(), "Exit to Menu"))
.setMessage("This feature is not implemented yet. Would you like to quit the app instead?")
.setNegativeButton("Cancel", null)
.setPositiveButton("Quit App", (d, w) -> {
quitApp();
dismissAllowingStateLoss();
})
.show();
});
}
// Restart Game - use existing reboot functionality
if (btnRestartGame != null) {
btnRestartGame.setOnClickListener(v -> {
new MaterialAlertDialogBuilder(requireContext(),
com.google.android.material.R.style.ThemeOverlay_Material3_MaterialAlertDialog)
.setCustomTitle(UiUtils.centeredDialogTitle(requireContext(), "Restart Game"))
.setMessage("Restart the current game?")
.setNegativeButton("Cancel", null)
.setPositiveButton("Restart", (d, w) -> {
if (requireActivity() instanceof MainActivity) {
((MainActivity) requireActivity()).rebootEmu();
} else {
NativeApp.shutdown();
}
dismissAllowingStateLoss();
})
.show();
});
}
// Quit App - use existing power functionality
if (btnQuitApp != null) {
btnQuitApp.setOnClickListener(v -> {
new MaterialAlertDialogBuilder(requireContext(),
com.google.android.material.R.style.ThemeOverlay_Material3_MaterialAlertDialog)
.setCustomTitle(UiUtils.centeredDialogTitle(requireContext(), "Quit App"))
.setMessage("Quit PSX2?")
.setNegativeButton("Cancel", null)
.setPositiveButton("Quit", (d, w) -> {
quitApp();
dismissAllowingStateLoss();
})
.show();
// Saves: open save states dialog
if (btnSaves != null) {
btnSaves.setOnClickListener(v -> {
try { new SavesDialogFragment().show(getParentFragmentManager(), "saves_dialog"); } catch (Throwable ignored) {}
dismissAllowingStateLoss();
});
}
// Cancel button
if (btnCancel != null) {
btnCancel.setOnClickListener(v -> dismissAllowingStateLoss());
}
if (btnCancel != null) btnCancel.setOnClickListener(v -> dismissAllowingStateLoss());
return new MaterialAlertDialogBuilder(requireContext(),
com.google.android.material.R.style.ThemeOverlay_Material3_MaterialAlertDialog)
@@ -118,8 +118,19 @@ public class SetupWizardDialogFragment extends DialogFragment {
if (isDataFolderPicked() && isGamesFolderPicked() && isBiosPresent()) {
requireContext().getSharedPreferences("app_prefs", android.content.Context.MODE_PRIVATE)
.edit().putBoolean("first_run_done", true).apply();
try { ((MainActivity) requireActivity()).setSetupWizardActive(false); } catch (Throwable ignored) {}
MainActivity a = null;
try { a = (MainActivity) requireActivity(); a.setSetupWizardActive(false); } catch (Throwable ignored) {}
dismissAllowingStateLoss();
if (a != null) {
// Open the games dialog just like the old GAMES button
final MainActivity act = a;
View decor = act.getWindow() != null ? act.getWindow().getDecorView() : null;
if (decor != null) {
decor.postDelayed(act::openGamesDialog, 150);
} else {
act.runOnUiThread(act::openGamesDialog);
}
}
}
});
LinearLayout.LayoutParams lp4 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+11
View File
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/md_theme_onSurface"
android:pathData="M3,6h18v2H3zM3,11h18v2H3zM3,16h18v2H3z"/>
</vector>
+10
View File
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M840,280L840,760Q840,793 816.5,816.5Q793,840 760,840L200,840Q167,840 143.5,816.5Q120,793 120,760L120,200Q120,167 143.5,143.5Q167,120 200,120L680,120L840,280ZM760,314L646,200L200,200Q200,200 200,200Q200,200 200,200L200,760Q200,760 200,760Q200,760 200,760L760,760Q760,760 760,760Q760,760 760,760L760,314ZM480,720Q530,720 565,685Q600,650 600,600Q600,550 565,515Q530,480 480,480Q430,480 395,515Q360,550 360,600Q360,650 395,685Q430,720 480,720ZM240,400L600,400L600,240L240,240L240,400ZM200,314L200,760Q200,760 200,760Q200,760 200,760L200,760Q200,760 200,760Q200,760 200,760L200,200Q200,200 200,200Q200,200 200,200L200,200L200,314Z"/>
</vector>
File diff suppressed because one or more lines are too long
+34 -58
View File
@@ -1,18 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
tools:context=".MainActivity">
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/fl_board"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Settings button in top left corner -->
<!-- Menu button in top left corner -->
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_settings"
style="@style/PSX2.ElevatedTransparentButton"
@@ -24,7 +29,7 @@
android:insetBottom="0dp"
android:gravity="center"
android:text=""
app:icon="@drawable/settings_24px"
app:icon="@drawable/menu_24px"
app:iconTint="@color/md_theme_tertiary"
app:iconGravity="textStart"
app:iconSize="24dp"
@@ -34,27 +39,7 @@
app:layout_constraintStart_toStartOf="parent"
android:layout_margin="12dp"/>
<!-- Visibility toggle button in upper right corner -->
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_toggle_controls"
style="@style/PSX2.ElevatedTransparentButton"
android:layout_width="40dp"
android:layout_height="40dp"
android:insetLeft="0dp"
android:insetRight="0dp"
android:insetTop="0dp"
android:insetBottom="0dp"
android:gravity="center"
android:text=""
app:icon="@drawable/visibility_24px"
app:iconTint="@color/md_theme_tertiary"
app:iconGravity="textStart"
app:iconSize="24dp"
app:iconPadding="0dp"
app:rippleColor="#80cdcdcd"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_margin="12dp"/>
<!-- Visibility toggle removed -->
<!-- Top center menu row -->
<LinearLayout
@@ -66,39 +51,12 @@
android:orientation="horizontal"
app:layout_constraintTop_toTopOf="@id/btn_settings"
app:layout_constraintStart_toEndOf="@id/btn_settings"
app:layout_constraintEnd_toStartOf="@id/btn_toggle_controls"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_chainStyle="packed">
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_file"
style="@style/PSX2.ElevatedTransparentButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:text="GAMES"
app:rippleColor="#80cdcdcd" />
<!-- GAMES button removed; games dialog now opens after setup wizard and from drawer -->
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_bios"
style="@style/PSX2.ElevatedTransparentButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp"
android:text="bios"
app:rippleColor="#80cdcdcd" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_saves"
style="@style/PSX2.ElevatedTransparentButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:text="saves"
app:rippleColor="#80cdcdcd" />
<!-- SAVES button removed; use drawer or Quick Actions for save states -->
</LinearLayout>
@@ -445,5 +403,23 @@
android:layout_column="2" />
</GridLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Left drawer (NavigationView) -->
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="320dp"
android:layout_height="match_parent"
android:layout_gravity="start"
app:itemIconTint="@color/md_theme_onSurface"
app:itemTextColor="@color/md_theme_onSurface"
app:headerLayout="@layout/drawer_header_settings" />
<!-- Right drawer (empty content for future use) -->
<FrameLayout
android:id="@+id/end_drawer"
android:layout_width="320dp"
android:layout_height="match_parent"
android:layout_gravity="end" />
</androidx.drawerlayout.widget.DrawerLayout>
@@ -1,10 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/dlg_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_covers_gradient_blue"
android:orientation="vertical">
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_covers_gradient_blue"
android:orientation="vertical">
<LinearLayout
android:id="@+id/toolbar_row"
@@ -22,9 +27,9 @@
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@android:color/transparent"
android:contentDescription="Home"
android:contentDescription="Menu"
android:padding="4dp"
android:src="@drawable/home_24px"
android:src="@drawable/menu_24px"
app:tint="@color/brand_primary" />
<View
@@ -119,4 +124,16 @@
app:iconPadding="20dp"
app:iconSize="24dp" />
</LinearLayout>
</LinearLayout>
<!-- In-dialog navigation drawer to mirror main drawer -->
<com.google.android.material.navigation.NavigationView
android:id="@+id/dialog_nav_view"
android:layout_width="320dp"
android:layout_height="match_parent"
android:layout_gravity="start"
app:itemIconTint="@color/md_theme_onSurface"
app:itemTextColor="@color/md_theme_onSurface"
app:headerLayout="@layout/drawer_header_settings" />
</androidx.drawerlayout.widget.DrawerLayout>
+33 -57
View File
@@ -1,18 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
tools:context=".MainActivity">
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/fl_board"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Settings button in top left corner -->
<!-- Menu button in top left corner -->
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_settings"
style="@style/PSX2.ElevatedTransparentButton"
@@ -24,7 +29,7 @@
android:insetBottom="0dp"
android:gravity="center"
android:text=""
app:icon="@drawable/settings_24px"
app:icon="@drawable/menu_24px"
app:iconTint="@color/md_theme_tertiary"
app:iconGravity="textStart"
app:iconSize="24dp"
@@ -34,27 +39,7 @@
app:layout_constraintStart_toStartOf="parent"
android:layout_margin="12dp"/>
<!-- Visibility toggle button in upper right corner -->
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_toggle_controls"
style="@style/PSX2.ElevatedTransparentButton"
android:layout_width="40dp"
android:layout_height="40dp"
android:insetLeft="0dp"
android:insetRight="0dp"
android:insetTop="0dp"
android:insetBottom="0dp"
android:gravity="center"
android:text=""
app:icon="@drawable/visibility_24px"
app:iconTint="@color/md_theme_tertiary"
app:iconGravity="textStart"
app:iconSize="24dp"
app:iconPadding="0dp"
app:rippleColor="#80cdcdcd"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_margin="12dp"/>
<!-- Visibility toggle removed -->
<LinearLayout
android:id="@+id/ll_quick_actions"
@@ -67,36 +52,9 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_settings">
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_file"
style="@style/PSX2.ElevatedTransparentButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:text="GAMES"
app:rippleColor="#80cdcdcd" />
<!-- GAMES button removed; games dialog now opens after setup wizard and from drawer -->
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_bios"
style="@style/PSX2.ElevatedTransparentButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp"
android:text="bios"
app:rippleColor="#80cdcdcd" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_saves"
style="@style/PSX2.ElevatedTransparentButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:text="saves"
app:rippleColor="#80cdcdcd" />
<!-- SAVES button removed; use drawer or Quick Actions for save states -->
</LinearLayout>
@@ -438,5 +396,23 @@
android:layout_column="2" />
</GridLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Left drawer (NavigationView) -->
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="320dp"
android:layout_height="match_parent"
android:layout_gravity="start"
app:itemIconTint="@color/md_theme_onSurface"
app:itemTextColor="@color/md_theme_onSurface"
app:headerLayout="@layout/drawer_header_settings" />
<!-- Right drawer (empty content for future use) -->
<FrameLayout
android:id="@+id/end_drawer"
android:layout_width="320dp"
android:layout_height="match_parent"
android:layout_gravity="end" />
</androidx.drawerlayout.widget.DrawerLayout>
@@ -1,10 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/dlg_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_covers_gradient_blue"
android:orientation="vertical">
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_covers_gradient_blue"
android:orientation="vertical">
<LinearLayout
android:id="@+id/toolbar_row"
@@ -22,9 +27,9 @@
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@android:color/transparent"
android:contentDescription="Home"
android:contentDescription="Menu"
android:padding="4dp"
android:src="@drawable/home_24px"
android:src="@drawable/menu_24px"
app:tint="@color/brand_primary" />
<View
@@ -119,4 +124,16 @@
app:iconPadding="20dp"
app:iconSize="34dp" />
</LinearLayout>
</LinearLayout>
<!-- In-dialog navigation drawer to mirror main drawer -->
<com.google.android.material.navigation.NavigationView
android:id="@+id/dialog_nav_view"
android:layout_width="320dp"
android:layout_height="match_parent"
android:layout_gravity="start"
app:itemIconTint="@color/md_theme_onSurface"
app:itemTextColor="@color/md_theme_onSurface"
app:headerLayout="@layout/drawer_header_settings" />
</androidx.drawerlayout.widget.DrawerLayout>
+190 -29
View File
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
@@ -14,47 +15,207 @@
android:layout_marginBottom="16dp"
android:textColor="?android:attr/textColorPrimary" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_open_games"
style="@style/Widget.Material3.Button.OutlinedButton"
<!-- Row 1: Power + Reboot -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Games"
android:textAllCaps="false"
android:layout_marginBottom="8dp" />
android:orientation="horizontal"
android:layout_marginBottom="8dp">
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_exit_to_menu"
style="@style/Widget.Material3.Button.OutlinedButton"
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_quick_power"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Power"
android:textAllCaps="false"
android:drawableStart="@drawable/ic_power"
android:drawablePadding="8dp" />
<View
android:layout_width="8dp"
android:layout_height="0dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_quick_reboot"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Reboot"
android:textAllCaps="false"
android:drawableStart="@drawable/ic_reboot"
android:drawablePadding="8dp" />
</LinearLayout>
<!-- Row 2: Renderer toggle buttons -->
<com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/qa_tg_renderer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Exit to Menu"
android:textAllCaps="false"
android:layout_marginBottom="8dp"
android:drawableStart="@drawable/ic_home"
android:drawablePadding="8dp" />
app:singleSelection="true"
app:selectionRequired="true">
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_restart_game"
style="@style/Widget.Material3.Button.OutlinedButton"
<com.google.android.material.button.MaterialButton
android:id="@+id/qa_tb_at"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="AT"
android:checkable="true" />
<com.google.android.material.button.MaterialButton
android:id="@+id/qa_tb_vk"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="VK"
android:checkable="true" />
<com.google.android.material.button.MaterialButton
android:id="@+id/qa_tb_gl"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="GL"
android:checkable="true" />
<com.google.android.material.button.MaterialButton
android:id="@+id/qa_tb_sw"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="SW"
android:checkable="true" />
</com.google.android.material.button.MaterialButtonToggleGroup>
<!-- Row 3: Games + Saves -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Restart Game"
android:textAllCaps="false"
android:layout_marginBottom="8dp"
android:drawableStart="@drawable/ic_reboot"
android:drawablePadding="8dp" />
android:orientation="horizontal"
android:layout_marginBottom="16dp">
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_quit_app"
style="@style/Widget.Material3.Button.OutlinedButton"
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_quick_games"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="GAMES"
android:textAllCaps="true"
android:drawableStart="@drawable/stadia_controller_24px"
android:drawablePadding="8dp" />
<View
android:layout_width="8dp"
android:layout_height="0dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_quick_saves"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="SAVES"
android:textAllCaps="true"
android:drawableStart="@drawable/save_24px"
android:drawablePadding="8dp" />
</LinearLayout>
<!-- Row 4: Aspect Ratio -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Aspect Ratio"
android:textStyle="bold"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/qa_sp_aspect_ratio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Quit App"
android:textAllCaps="false"
android:layout_marginBottom="16dp"
android:drawableStart="@drawable/ic_power"
android:drawablePadding="8dp" />
android:layout_marginBottom="8dp"/>
<!-- Row 5: Blending Accuracy -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Blending Accuracy"
android:textStyle="bold"
android:layout_marginBottom="4dp"/>
<Spinner
android:id="@+id/qa_sp_blending_accuracy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"/>
<!-- Row 6: Widescreen + No Interlacing -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="8dp">
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/qa_sw_widescreen"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Widescreen Patches"/>
<View
android:layout_width="8dp"
android:layout_height="0dp" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/qa_sw_no_interlacing"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="No Interlacing"/>
</LinearLayout>
<!-- Row 7: Textures toggles -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="8dp">
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/qa_sw_load_textures"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Load Textures"/>
<View
android:layout_width="8dp"
android:layout_height="0dp" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/qa_sw_async_textures"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Async Textures"/>
</LinearLayout>
<!-- Row 8: Precache textures (single) -->
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/qa_sw_precache_textures"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Precache Texture Replacements"
android:layout_marginBottom="8dp"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_cancel"
@@ -63,18 +63,21 @@
android:id="@+id/rb_renderer_auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="0dp"
android:text="AUTO"/>
<RadioButton
android:id="@+id/rb_renderer_vk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="0dp"
android:text="VK"/>
<RadioButton
android:id="@+id/rb_renderer_gl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="0dp"
android:text="OGL"
android:layout_marginStart="16dp"/>
@@ -82,6 +85,7 @@
android:id="@+id/rb_renderer_sw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="0dp"
android:text="SW"
android:layout_marginStart="16dp"/>
</RadioGroup>
@@ -0,0 +1,127 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingBottom="16dp"
android:paddingTop="32dp">
<TextView
android:id="@+id/drawer_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Settings"
android:textStyle="bold"
android:textSize="20sp"
android:gravity="center"
android:paddingBottom="12dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:paddingBottom="8dp">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/drawer_btn_reboot"
style="?attr/floatingActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="Reboot"
app:srcCompat="@drawable/ic_reboot"
app:materialThemeOverlay="@style/ThemeOverlay.Material3Expressive.FloatingActionButton.Secondary"
android:layout_marginEnd="12dp" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/drawer_btn_power"
style="?attr/floatingActionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="Power"
app:srcCompat="@drawable/ic_power"
app:materialThemeOverlay="@style/ThemeOverlay.Material3Expressive.FloatingActionButton.Tertiary" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Renderer"
android:textStyle="bold"
android:paddingTop="8dp"
android:paddingBottom="4dp" />
<com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/drawer_tg_renderer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:singleSelection="true"
app:selectionRequired="true"
android:layout_marginBottom="8dp">
<com.google.android.material.button.MaterialButton
android:id="@+id/drawer_tb_at"
style="@style/Widget.Material3Expressive.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minWidth="0dp"
android:text="AT"
android:checkable="true" />
<com.google.android.material.button.MaterialButton
android:id="@+id/drawer_tb_vk"
style="@style/Widget.Material3Expressive.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minWidth="0dp"
android:text="VK"
android:checkable="true" />
<com.google.android.material.button.MaterialButton
android:id="@+id/drawer_tb_gl"
style="@style/Widget.Material3Expressive.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minWidth="0dp"
android:text="GL"
android:checkable="true" />
<com.google.android.material.button.MaterialButton
android:id="@+id/drawer_tb_sw"
style="@style/Widget.Material3Expressive.Button.OutlinedButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minWidth="0dp"
android:text="SW"
android:checkable="true" />
</com.google.android.material.button.MaterialButtonToggleGroup>
<!-- Save/Load game state shortcut -->
<com.google.android.material.button.MaterialButton
android:id="@+id/drawer_btn_game_state"
style="@style/Widget.Material3Expressive.Button.OutlinedButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Game State"
android:textAllCaps="false"
app:icon="@drawable/save_24px"
app:iconGravity="textStart"
app:iconPadding="8dp"
app:iconSize="20dp"
android:layout_marginTop="8dp" />
</LinearLayout>
</ScrollView>
+2 -2
View File
@@ -1,4 +1,4 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '8.7.3' apply false
}
id 'com.android.application' version '8.11.1' apply false
}
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME