mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 03:24:56 +08:00
android: reformat codebase
This commit is contained in:
@@ -8,22 +8,22 @@ plugins {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "su.xash.engine"
|
||||
namespace = "su.xash.engine"
|
||||
ndkVersion = "28.0.13004108"
|
||||
compileSdk = 35
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "su.xash.engine"
|
||||
versionName = "0.21"
|
||||
versionCode = getBuildNum()
|
||||
minSdk = 21
|
||||
targetSdk = 35
|
||||
}
|
||||
defaultConfig {
|
||||
applicationId = "su.xash.engine"
|
||||
versionName = "0.21"
|
||||
versionCode = getBuildNum()
|
||||
minSdk = 21
|
||||
targetSdk = 35
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = "11"
|
||||
@@ -73,23 +73,23 @@ android {
|
||||
)
|
||||
}
|
||||
|
||||
release {
|
||||
isMinifyEnabled = true
|
||||
isShrinkResources = true
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
release {
|
||||
isMinifyEnabled = true
|
||||
isShrinkResources = true
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
|
||||
register("asan") {
|
||||
initWith(getByName("debug"))
|
||||
}
|
||||
register("asan") {
|
||||
initWith(getByName("debug"))
|
||||
}
|
||||
|
||||
register("continuous") {
|
||||
initWith(getByName("release"))
|
||||
applicationIdSuffix = ".test"
|
||||
}
|
||||
}
|
||||
register("continuous") {
|
||||
initWith(getByName("release"))
|
||||
applicationIdSuffix = ".test"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -102,13 +102,13 @@ dependencies {
|
||||
implementation(libs.preference.ktx)
|
||||
implementation(libs.swiperefreshlayout)
|
||||
|
||||
implementation(libs.acra.http)
|
||||
implementation(libs.acra.http)
|
||||
}
|
||||
|
||||
fun getBuildNum(): Int {
|
||||
val now = LocalDateTime.now()
|
||||
val releaseDate = LocalDateTime.of(2015, Month.APRIL, 1, 0, 0, 0)
|
||||
val qBuildNum = releaseDate.until(now, ChronoUnit.DAYS)
|
||||
val minuteOfDay = now.hour * 60 + now.minute
|
||||
return (qBuildNum * 10000 + minuteOfDay).toInt()
|
||||
val now = LocalDateTime.now()
|
||||
val releaseDate = LocalDateTime.of(2015, Month.APRIL, 1, 0, 0, 0)
|
||||
val qBuildNum = releaseDate.until(now, ChronoUnit.DAYS)
|
||||
val minuteOfDay = now.hour * 60 + now.minute
|
||||
return (qBuildNum * 10000 + minuteOfDay).toInt()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name" translatable="false">Xash3D FWGS (Test)</string>
|
||||
<string name="app_name" translatable="false">Xash3D FWGS (Test)</string>
|
||||
</resources>
|
||||
|
||||
@@ -6,44 +6,44 @@ import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
public class AndroidBug5497Workaround {
|
||||
// For more information, see https://code.google.com/p/android/issues/detail?id=5497
|
||||
// To use this class, simply invoke assistActivity() on an Activity that already has its content view set.
|
||||
// For more information, see https://code.google.com/p/android/issues/detail?id=5497
|
||||
// To use this class, simply invoke assistActivity() on an Activity that already has its content view set.
|
||||
|
||||
public static void assistActivity(Activity activity) {
|
||||
new AndroidBug5497Workaround(activity);
|
||||
}
|
||||
public static void assistActivity(Activity activity) {
|
||||
new AndroidBug5497Workaround(activity);
|
||||
}
|
||||
|
||||
private View mChildOfContent;
|
||||
private int usableHeightPrevious;
|
||||
private FrameLayout.LayoutParams frameLayoutParams;
|
||||
private View mChildOfContent;
|
||||
private int usableHeightPrevious;
|
||||
private FrameLayout.LayoutParams frameLayoutParams;
|
||||
|
||||
private AndroidBug5497Workaround(Activity activity) {
|
||||
FrameLayout content = activity.findViewById(android.R.id.content);
|
||||
mChildOfContent = content.getChildAt(0);
|
||||
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(this::possiblyResizeChildOfContent);
|
||||
frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
|
||||
}
|
||||
private AndroidBug5497Workaround(Activity activity) {
|
||||
FrameLayout content = activity.findViewById(android.R.id.content);
|
||||
mChildOfContent = content.getChildAt(0);
|
||||
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(this::possiblyResizeChildOfContent);
|
||||
frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
|
||||
}
|
||||
|
||||
private void possiblyResizeChildOfContent() {
|
||||
int usableHeightNow = computeUsableHeight();
|
||||
if (usableHeightNow != usableHeightPrevious) {
|
||||
int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
|
||||
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
|
||||
if (heightDifference > (usableHeightSansKeyboard / 4)) {
|
||||
// keyboard probably just became visible
|
||||
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
|
||||
} else {
|
||||
// keyboard probably just became hidden
|
||||
frameLayoutParams.height = usableHeightSansKeyboard;
|
||||
}
|
||||
mChildOfContent.requestLayout();
|
||||
usableHeightPrevious = usableHeightNow;
|
||||
}
|
||||
}
|
||||
private void possiblyResizeChildOfContent() {
|
||||
int usableHeightNow = computeUsableHeight();
|
||||
if (usableHeightNow != usableHeightPrevious) {
|
||||
int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
|
||||
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
|
||||
if (heightDifference > (usableHeightSansKeyboard / 4)) {
|
||||
// keyboard probably just became visible
|
||||
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
|
||||
} else {
|
||||
// keyboard probably just became hidden
|
||||
frameLayoutParams.height = usableHeightSansKeyboard;
|
||||
}
|
||||
mChildOfContent.requestLayout();
|
||||
usableHeightPrevious = usableHeightNow;
|
||||
}
|
||||
}
|
||||
|
||||
private int computeUsableHeight() {
|
||||
Rect r = new Rect();
|
||||
mChildOfContent.getWindowVisibleDisplayFrame(r);
|
||||
return (r.bottom - r.top);
|
||||
}
|
||||
}
|
||||
private int computeUsableHeight() {
|
||||
Rect r = new Rect();
|
||||
mChildOfContent.getWindowVisibleDisplayFrame(r);
|
||||
return (r.bottom - r.top);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import android.app.Service
|
||||
import android.content.Intent
|
||||
import android.os.IBinder
|
||||
|
||||
class DedicatedService: Service() {
|
||||
override fun onBind(intent: Intent?): IBinder? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
class DedicatedService : Service() {
|
||||
override fun onBind(intent: Intent?): IBinder? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,26 +10,26 @@ import androidx.navigation.ui.setupActionBarWithNavController
|
||||
import su.xash.engine.databinding.ActivityMainBinding
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityMainBinding
|
||||
private lateinit var appBarConfiguration: AppBarConfiguration
|
||||
private lateinit var navController: NavController
|
||||
private lateinit var binding: ActivityMainBinding
|
||||
private lateinit var appBarConfiguration: AppBarConfiguration
|
||||
private lateinit var navController: NavController
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
setSupportActionBar(binding.toolbar)
|
||||
setSupportActionBar(binding.toolbar)
|
||||
|
||||
val navHostFragment =
|
||||
supportFragmentManager.findFragmentById(R.id.fragmentContainerView) as NavHostFragment
|
||||
navController = navHostFragment.navController
|
||||
appBarConfiguration = AppBarConfiguration(navController.graph)
|
||||
setupActionBarWithNavController(navController, appBarConfiguration)
|
||||
}
|
||||
val navHostFragment =
|
||||
supportFragmentManager.findFragmentById(R.id.fragmentContainerView) as NavHostFragment
|
||||
navController = navHostFragment.navController
|
||||
appBarConfiguration = AppBarConfiguration(navController.graph)
|
||||
setupActionBarWithNavController(navController, appBarConfiguration)
|
||||
}
|
||||
|
||||
override fun onSupportNavigateUp(): Boolean {
|
||||
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
|
||||
}
|
||||
override fun onSupportNavigateUp(): Boolean {
|
||||
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,21 +8,21 @@ import org.acra.data.StringFormat
|
||||
import org.acra.ktx.initAcra
|
||||
|
||||
class MainApplication : Application() {
|
||||
override fun attachBaseContext(base: Context?) {
|
||||
super.attachBaseContext(base)
|
||||
override fun attachBaseContext(base: Context?) {
|
||||
super.attachBaseContext(base)
|
||||
|
||||
if (!BuildConfig.DEBUG) {
|
||||
initAcra {
|
||||
buildConfigClass = BuildConfig::class.java
|
||||
reportFormat = StringFormat.JSON
|
||||
if (!BuildConfig.DEBUG) {
|
||||
initAcra {
|
||||
buildConfigClass = BuildConfig::class.java
|
||||
reportFormat = StringFormat.JSON
|
||||
|
||||
httpSender {
|
||||
uri = "http://bodis.pp.ua:5000/report"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// enable strict mode to detect memory leaks etc.
|
||||
StrictMode.enableDefaults();
|
||||
}
|
||||
}
|
||||
}
|
||||
httpSender {
|
||||
uri = "http://bodis.pp.ua:5000/report"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// enable strict mode to detect memory leaks etc.
|
||||
StrictMode.enableDefaults();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,136 +13,135 @@ import android.view.WindowManager;
|
||||
import org.libsdl.app.SDLActivity;
|
||||
|
||||
public class XashActivity extends SDLActivity {
|
||||
private boolean mUseVolumeKeys;
|
||||
private String mPackageName;
|
||||
private static final String TAG = "XashActivity";
|
||||
private boolean mUseVolumeKeys;
|
||||
private String mPackageName;
|
||||
private static final String TAG = "XashActivity";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
//getWindow().addFlags(WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES);
|
||||
getWindow().getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
|
||||
}
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
//getWindow().addFlags(WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES);
|
||||
getWindow().getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
|
||||
}
|
||||
|
||||
AndroidBug5497Workaround.assistActivity(this);
|
||||
}
|
||||
AndroidBug5497Workaround.assistActivity(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy()
|
||||
{
|
||||
super.onDestroy();
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
// Now that we don't exit from native code, we need to exit here, resetting
|
||||
// application state (actually global variables that we don't cleanup on exit)
|
||||
//
|
||||
// When the issue with global variables will be resolved, remove that exit() call
|
||||
System.exit(0);
|
||||
}
|
||||
// Now that we don't exit from native code, we need to exit here, resetting
|
||||
// application state (actually global variables that we don't cleanup on exit)
|
||||
//
|
||||
// When the issue with global variables will be resolved, remove that exit() call
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getLibraries() {
|
||||
return new String[]{"SDL2", "xash"};
|
||||
}
|
||||
@Override
|
||||
protected String[] getLibraries() {
|
||||
return new String[]{"SDL2", "xash"};
|
||||
}
|
||||
|
||||
@SuppressLint("HardwareIds")
|
||||
private String getAndroidID() {
|
||||
return Secure.getString(getContentResolver(), Secure.ANDROID_ID);
|
||||
}
|
||||
@SuppressLint("HardwareIds")
|
||||
private String getAndroidID() {
|
||||
return Secure.getString(getContentResolver(), Secure.ANDROID_ID);
|
||||
}
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
private void saveAndroidID(String id) {
|
||||
getSharedPreferences("xash_preferences", MODE_PRIVATE).edit().putString("xash_id", id).commit();
|
||||
}
|
||||
@SuppressLint("ApplySharedPref")
|
||||
private void saveAndroidID(String id) {
|
||||
getSharedPreferences("xash_preferences", MODE_PRIVATE).edit().putString("xash_id", id).commit();
|
||||
}
|
||||
|
||||
private String loadAndroidID() {
|
||||
return getSharedPreferences("xash_preferences", MODE_PRIVATE).getString("xash_id", "");
|
||||
}
|
||||
private String loadAndroidID() {
|
||||
return getSharedPreferences("xash_preferences", MODE_PRIVATE).getString("xash_id", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCallingPackage() {
|
||||
if (mPackageName != null) {
|
||||
return mPackageName;
|
||||
}
|
||||
@Override
|
||||
public String getCallingPackage() {
|
||||
if (mPackageName != null) {
|
||||
return mPackageName;
|
||||
}
|
||||
|
||||
return super.getCallingPackage();
|
||||
}
|
||||
return super.getCallingPackage();
|
||||
}
|
||||
|
||||
private AssetManager getAssets(boolean isEngine) {
|
||||
AssetManager am = null;
|
||||
private AssetManager getAssets(boolean isEngine) {
|
||||
AssetManager am = null;
|
||||
|
||||
if (isEngine) {
|
||||
am = getAssets();
|
||||
} else {
|
||||
try {
|
||||
am = getPackageManager().getResourcesForApplication(getCallingPackage()).getAssets();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Unable to load mod assets!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (isEngine) {
|
||||
am = getAssets();
|
||||
} else {
|
||||
try {
|
||||
am = getPackageManager().getResourcesForApplication(getCallingPackage()).getAssets();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Unable to load mod assets!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return am;
|
||||
}
|
||||
return am;
|
||||
}
|
||||
|
||||
private String[] getAssetsList(boolean isEngine, String path) {
|
||||
AssetManager am = getAssets(isEngine);
|
||||
private String[] getAssetsList(boolean isEngine, String path) {
|
||||
AssetManager am = getAssets(isEngine);
|
||||
|
||||
try {
|
||||
return am.list(path);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
return am.list(path);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return new String[]{};
|
||||
}
|
||||
return new String[]{};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(KeyEvent event) {
|
||||
if (SDLActivity.mBrokenLibraries) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(KeyEvent event) {
|
||||
if (SDLActivity.mBrokenLibraries) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int keyCode = event.getKeyCode();
|
||||
if (!mUseVolumeKeys) {
|
||||
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ||
|
||||
keyCode == KeyEvent.KEYCODE_VOLUME_UP ||
|
||||
keyCode == KeyEvent.KEYCODE_CAMERA ||
|
||||
keyCode == KeyEvent.KEYCODE_ZOOM_IN ||
|
||||
keyCode == KeyEvent.KEYCODE_ZOOM_OUT) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
int keyCode = event.getKeyCode();
|
||||
if (!mUseVolumeKeys) {
|
||||
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ||
|
||||
keyCode == KeyEvent.KEYCODE_VOLUME_UP ||
|
||||
keyCode == KeyEvent.KEYCODE_CAMERA ||
|
||||
keyCode == KeyEvent.KEYCODE_ZOOM_IN ||
|
||||
keyCode == KeyEvent.KEYCODE_ZOOM_OUT) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return getWindow().superDispatchKeyEvent(event);
|
||||
}
|
||||
return getWindow().superDispatchKeyEvent(event);
|
||||
}
|
||||
|
||||
// TODO: REMOVE LATER, temporary launchers support?
|
||||
@Override
|
||||
protected String[] getArguments() {
|
||||
String gamedir = getIntent().getStringExtra("gamedir");
|
||||
if (gamedir == null) gamedir = "valve";
|
||||
nativeSetenv("XASH3D_GAME", gamedir);
|
||||
// TODO: REMOVE LATER, temporary launchers support?
|
||||
@Override
|
||||
protected String[] getArguments() {
|
||||
String gamedir = getIntent().getStringExtra("gamedir");
|
||||
if (gamedir == null) gamedir = "valve";
|
||||
nativeSetenv("XASH3D_GAME", gamedir);
|
||||
|
||||
String gamelibdir = getIntent().getStringExtra("gamelibdir");
|
||||
if (gamelibdir != null) nativeSetenv("XASH3D_GAMELIBDIR", gamelibdir);
|
||||
String gamelibdir = getIntent().getStringExtra("gamelibdir");
|
||||
if (gamelibdir != null) nativeSetenv("XASH3D_GAMELIBDIR", gamelibdir);
|
||||
|
||||
String pakfile = getIntent().getStringExtra("pakfile");
|
||||
if (pakfile != null) nativeSetenv("XASH3D_EXTRAS_PAK2", pakfile);
|
||||
String pakfile = getIntent().getStringExtra("pakfile");
|
||||
if (pakfile != null) nativeSetenv("XASH3D_EXTRAS_PAK2", pakfile);
|
||||
|
||||
mUseVolumeKeys = getIntent().getBooleanExtra("usevolume", false);
|
||||
mPackageName = getIntent().getStringExtra("package");
|
||||
mUseVolumeKeys = getIntent().getBooleanExtra("usevolume", false);
|
||||
mPackageName = getIntent().getStringExtra("package");
|
||||
|
||||
String[] env = getIntent().getStringArrayExtra("env");
|
||||
if (env != null) {
|
||||
for (int i = 0; i < env.length; i += 2)
|
||||
nativeSetenv(env[i], env[i + 1]);
|
||||
}
|
||||
String[] env = getIntent().getStringArrayExtra("env");
|
||||
if (env != null) {
|
||||
for (int i = 0; i < env.length; i += 2)
|
||||
nativeSetenv(env[i], env[i + 1]);
|
||||
}
|
||||
|
||||
String argv = getIntent().getStringExtra("argv");
|
||||
if (argv == null) argv = "-console -log";
|
||||
return argv.split(" ");
|
||||
}
|
||||
String argv = getIntent().getStringExtra("argv");
|
||||
if (argv == null) argv = "-console -log";
|
||||
return argv.split(" ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,64 +14,64 @@ import su.xash.engine.ui.library.LibraryViewModel
|
||||
|
||||
|
||||
class GameAdapter(private val libraryViewModel: LibraryViewModel) :
|
||||
ListAdapter<Game, GameAdapter.GameViewHolder>(DiffCallback()) {
|
||||
ListAdapter<Game, GameAdapter.GameViewHolder>(DiffCallback()) {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GameAdapter.GameViewHolder {
|
||||
val binding = CardGameBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return GameViewHolder(binding)
|
||||
}
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GameAdapter.GameViewHolder {
|
||||
val binding = CardGameBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return GameViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: GameAdapter.GameViewHolder, position: Int) {
|
||||
return holder.bind(getItem(position))
|
||||
}
|
||||
override fun onBindViewHolder(holder: GameAdapter.GameViewHolder, position: Int) {
|
||||
return holder.bind(getItem(position))
|
||||
}
|
||||
|
||||
private class DiffCallback : DiffUtil.ItemCallback<Game>() {
|
||||
override fun areItemsTheSame(oldItem: Game, newItem: Game): Boolean {
|
||||
return oldItem.basedir.name == newItem.basedir.name
|
||||
}
|
||||
private class DiffCallback : DiffUtil.ItemCallback<Game>() {
|
||||
override fun areItemsTheSame(oldItem: Game, newItem: Game): Boolean {
|
||||
return oldItem.basedir.name == newItem.basedir.name
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: Game, newItem: Game): Boolean {
|
||||
return oldItem.basedir.name == newItem.basedir.name && oldItem.installed == newItem.installed
|
||||
}
|
||||
override fun areContentsTheSame(oldItem: Game, newItem: Game): Boolean {
|
||||
return oldItem.basedir.name == newItem.basedir.name && oldItem.installed == newItem.installed
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
inner class GameViewHolder(val binding: CardGameBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
fun bind(game: Game) {
|
||||
binding.apply {
|
||||
gameTitle.text = game.title
|
||||
inner class GameViewHolder(val binding: CardGameBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
fun bind(game: Game) {
|
||||
binding.apply {
|
||||
gameTitle.text = game.title
|
||||
|
||||
if (game.icon != null) {
|
||||
gameIcon.setImageBitmap(game.icon)
|
||||
} else {
|
||||
gameIcon.visibility = View.GONE
|
||||
}
|
||||
if (game.icon != null) {
|
||||
gameIcon.setImageBitmap(game.icon)
|
||||
} else {
|
||||
gameIcon.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (game.cover != null) {
|
||||
gameCover.setImageBitmap(game.cover)
|
||||
} else {
|
||||
gameCover.visibility = View.GONE
|
||||
}
|
||||
if (game.cover != null) {
|
||||
gameCover.setImageBitmap(game.cover)
|
||||
} else {
|
||||
gameCover.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (!game.installed) {
|
||||
launchButton.visibility = View.GONE
|
||||
settingsButton.visibility = View.GONE
|
||||
progressIndicator.visibility = View.VISIBLE
|
||||
return
|
||||
}
|
||||
if (!game.installed) {
|
||||
launchButton.visibility = View.GONE
|
||||
settingsButton.visibility = View.GONE
|
||||
progressIndicator.visibility = View.VISIBLE
|
||||
return
|
||||
}
|
||||
|
||||
settingsButton.setOnClickListener {
|
||||
libraryViewModel.setSelectedGame(game)
|
||||
it.findNavController()
|
||||
.navigate(R.id.action_libraryFragment_to_gameSettingsFragment)
|
||||
}
|
||||
settingsButton.setOnClickListener {
|
||||
libraryViewModel.setSelectedGame(game)
|
||||
it.findNavController()
|
||||
.navigate(R.id.action_libraryFragment_to_gameSettingsFragment)
|
||||
}
|
||||
|
||||
root.setOnClickListener { libraryViewModel.startEngine(it.context, game) }
|
||||
launchButton.setOnClickListener {
|
||||
libraryViewModel.startEngine(it.context, game)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
root.setOnClickListener { libraryViewModel.startEngine(it.context, game) }
|
||||
launchButton.setOnClickListener {
|
||||
libraryViewModel.startEngine(it.context, game)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,81 +9,81 @@ import java.util.Scanner
|
||||
|
||||
|
||||
object BackgroundBitmap {
|
||||
private const val BACKGROUND_ROWS = 3
|
||||
private const val BACKGROUND_COLUMNS = 4
|
||||
private const val BACKGROUND_WIDTH = 800
|
||||
private const val BACKGROUND_HEIGHT = 600
|
||||
private const val BACKGROUND_ROWS = 3
|
||||
private const val BACKGROUND_COLUMNS = 4
|
||||
private const val BACKGROUND_WIDTH = 800
|
||||
private const val BACKGROUND_HEIGHT = 600
|
||||
|
||||
fun createBackground(ctx: Context, file: DocumentFile): Bitmap {
|
||||
var bitmap =
|
||||
Bitmap.createBitmap(BACKGROUND_WIDTH, BACKGROUND_HEIGHT, Bitmap.Config.ARGB_8888)
|
||||
var canvas = Canvas(bitmap)
|
||||
var x: Int
|
||||
var y = 0
|
||||
var width: Int
|
||||
var height = 0
|
||||
fun createBackground(ctx: Context, file: DocumentFile): Bitmap {
|
||||
var bitmap =
|
||||
Bitmap.createBitmap(BACKGROUND_WIDTH, BACKGROUND_HEIGHT, Bitmap.Config.ARGB_8888)
|
||||
var canvas = Canvas(bitmap)
|
||||
var x: Int
|
||||
var y = 0
|
||||
var width: Int
|
||||
var height = 0
|
||||
|
||||
var bgLayout = file.findFile("resource")?.findFile("HD_BackgroundLayout.txt")
|
||||
if (bgLayout == null) {
|
||||
bgLayout = file.findFile("resource")?.findFile("BackgroundLayout.txt")
|
||||
}
|
||||
var bgLayout = file.findFile("resource")?.findFile("HD_BackgroundLayout.txt")
|
||||
if (bgLayout == null) {
|
||||
bgLayout = file.findFile("resource")?.findFile("BackgroundLayout.txt")
|
||||
}
|
||||
|
||||
if (bgLayout == null) {
|
||||
val dir = file.findFile("resource")?.findFile("background")
|
||||
for (i in 0 until BACKGROUND_ROWS) {
|
||||
x = 0
|
||||
for (j in 0 until BACKGROUND_COLUMNS) {
|
||||
val filename = "${BACKGROUND_WIDTH}_${i + 1}_${'a' + j}_loading.tga"
|
||||
val bmpFile = dir?.findFile(filename)
|
||||
val bmpImage = loadTga(ctx, bmpFile!!)
|
||||
if (bgLayout == null) {
|
||||
val dir = file.findFile("resource")?.findFile("background")
|
||||
for (i in 0 until BACKGROUND_ROWS) {
|
||||
x = 0
|
||||
for (j in 0 until BACKGROUND_COLUMNS) {
|
||||
val filename = "${BACKGROUND_WIDTH}_${i + 1}_${'a' + j}_loading.tga"
|
||||
val bmpFile = dir?.findFile(filename)
|
||||
val bmpImage = loadTga(ctx, bmpFile!!)
|
||||
|
||||
canvas.drawBitmap(bmpImage, x.toFloat(), y.toFloat(), null)
|
||||
x += bmpImage.width
|
||||
height = bmpImage.height
|
||||
canvas.drawBitmap(bmpImage, x.toFloat(), y.toFloat(), null)
|
||||
x += bmpImage.width
|
||||
height = bmpImage.height
|
||||
|
||||
}
|
||||
y += height
|
||||
}
|
||||
return bitmap
|
||||
}
|
||||
}
|
||||
y += height
|
||||
}
|
||||
return bitmap
|
||||
}
|
||||
|
||||
ctx.contentResolver.openInputStream(bgLayout.uri).use { inputStream ->
|
||||
Scanner(inputStream).use { scanner ->
|
||||
while (scanner.hasNext()) {
|
||||
when (val str = scanner.next()) {
|
||||
"resolution" -> {
|
||||
width = scanner.nextInt()
|
||||
height = scanner.nextInt()
|
||||
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||
canvas = Canvas(bitmap)
|
||||
}
|
||||
ctx.contentResolver.openInputStream(bgLayout.uri).use { inputStream ->
|
||||
Scanner(inputStream).use { scanner ->
|
||||
while (scanner.hasNext()) {
|
||||
when (val str = scanner.next()) {
|
||||
"resolution" -> {
|
||||
width = scanner.nextInt()
|
||||
height = scanner.nextInt()
|
||||
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||
canvas = Canvas(bitmap)
|
||||
}
|
||||
|
||||
else -> {
|
||||
var bmpFile = file
|
||||
str.split("/").forEach { bmpFile = bmpFile.findFile(it)!! }
|
||||
//skip
|
||||
scanner.next()
|
||||
x = scanner.nextInt()
|
||||
y = scanner.nextInt()
|
||||
val bmp = loadTga(ctx, bmpFile)
|
||||
canvas.drawBitmap(bmp, x.toFloat(), y.toFloat(), null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bitmap
|
||||
}
|
||||
else -> {
|
||||
var bmpFile = file
|
||||
str.split("/").forEach { bmpFile = bmpFile.findFile(it)!! }
|
||||
//skip
|
||||
scanner.next()
|
||||
x = scanner.nextInt()
|
||||
y = scanner.nextInt()
|
||||
val bmp = loadTga(ctx, bmpFile)
|
||||
canvas.drawBitmap(bmp, x.toFloat(), y.toFloat(), null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bitmap
|
||||
}
|
||||
|
||||
private fun loadTga(ctx: Context, file: DocumentFile): Bitmap {
|
||||
ctx.contentResolver.openInputStream(file.uri).use {
|
||||
val buffer = it?.readBytes()
|
||||
val pixels = TGAReader.read(buffer, TGAReader.ARGB)
|
||||
private fun loadTga(ctx: Context, file: DocumentFile): Bitmap {
|
||||
ctx.contentResolver.openInputStream(file.uri).use {
|
||||
val buffer = it?.readBytes()
|
||||
val pixels = TGAReader.read(buffer, TGAReader.ARGB)
|
||||
|
||||
val width = TGAReader.getWidth(buffer)
|
||||
val height = TGAReader.getHeight(buffer)
|
||||
val width = TGAReader.getWidth(buffer)
|
||||
val height = TGAReader.getHeight(buffer)
|
||||
|
||||
return Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_8888)
|
||||
}
|
||||
}
|
||||
}
|
||||
return Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_8888)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,111 +12,111 @@ import su.xash.engine.XashActivity
|
||||
|
||||
|
||||
class Game(val ctx: Context, val basedir: DocumentFile, var installed: Boolean = true) {
|
||||
private var iconName = "game.ico"
|
||||
var title = "Unknown Game"
|
||||
var icon: Bitmap? = null
|
||||
var cover: Bitmap? = null
|
||||
private var iconName = "game.ico"
|
||||
var title = "Unknown Game"
|
||||
var icon: Bitmap? = null
|
||||
var cover: Bitmap? = null
|
||||
|
||||
private val pref = ctx.getSharedPreferences(basedir.name, Context.MODE_PRIVATE)
|
||||
private val pref = ctx.getSharedPreferences(basedir.name, Context.MODE_PRIVATE)
|
||||
|
||||
init {
|
||||
basedir.findFile("gameinfo.txt")?.let {
|
||||
parseGameInfo(it)
|
||||
} ?: basedir.findFile("liblist.gam")?.let { parseGameInfo(it) }
|
||||
init {
|
||||
basedir.findFile("gameinfo.txt")?.let {
|
||||
parseGameInfo(it)
|
||||
} ?: basedir.findFile("liblist.gam")?.let { parseGameInfo(it) }
|
||||
|
||||
basedir.findFile(iconName)
|
||||
?.let { icon = MediaStore.Images.Media.getBitmap(ctx.contentResolver, it.uri) }
|
||||
basedir.findFile(iconName)
|
||||
?.let { icon = MediaStore.Images.Media.getBitmap(ctx.contentResolver, it.uri) }
|
||||
|
||||
try {
|
||||
cover = BackgroundBitmap.createBackground(ctx, basedir)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
try {
|
||||
cover = BackgroundBitmap.createBackground(ctx, basedir)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
fun startEngine(ctx: Context) {
|
||||
ctx.startActivity(Intent(ctx, XashActivity::class.java).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
putExtra("gamedir", basedir.name)
|
||||
putExtra("argv", pref.getString("arguments", "-console -log"))
|
||||
putExtra("usevolume", pref.getBoolean("use_volume_buttons", false))
|
||||
//.putExtra("gamelibdir", getGameLibDir(context))
|
||||
//.putExtra("package", getPackageName()) }
|
||||
})
|
||||
}
|
||||
fun startEngine(ctx: Context) {
|
||||
ctx.startActivity(Intent(ctx, XashActivity::class.java).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
putExtra("gamedir", basedir.name)
|
||||
putExtra("argv", pref.getString("arguments", "-console -log"))
|
||||
putExtra("usevolume", pref.getBoolean("use_volume_buttons", false))
|
||||
//.putExtra("gamelibdir", getGameLibDir(context))
|
||||
//.putExtra("package", getPackageName()) }
|
||||
})
|
||||
}
|
||||
|
||||
private fun parseGameInfo(file: DocumentFile) {
|
||||
ctx.contentResolver.openInputStream(file.uri).use { inputStream ->
|
||||
inputStream?.bufferedReader().use { reader ->
|
||||
reader?.forEachLine {
|
||||
val tokens = it.split("\\s+".toRegex(), limit = 2)
|
||||
if (tokens.size >= 2) {
|
||||
val k = tokens[0]
|
||||
val v = tokens[1].trim('"')
|
||||
private fun parseGameInfo(file: DocumentFile) {
|
||||
ctx.contentResolver.openInputStream(file.uri).use { inputStream ->
|
||||
inputStream?.bufferedReader().use { reader ->
|
||||
reader?.forEachLine {
|
||||
val tokens = it.split("\\s+".toRegex(), limit = 2)
|
||||
if (tokens.size >= 2) {
|
||||
val k = tokens[0]
|
||||
val v = tokens[1].trim('"')
|
||||
|
||||
if (k == "title" || k == "game") title = v
|
||||
if (k == "icon") iconName = v
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (k == "title" || k == "game") title = v
|
||||
if (k == "icon") iconName = v
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPackageName(): String? {
|
||||
private fun getPackageName(): String? {
|
||||
// return if (mDbEntry != null) {
|
||||
// mDbEntry.getPackageName()
|
||||
// } else null
|
||||
return null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getGameLibDir(ctx: Context): String? {
|
||||
val pkgName = getPackageName()
|
||||
if (pkgName != null) {
|
||||
val pkgInfo: PackageInfo = try {
|
||||
ctx.packageManager.getPackageInfo(pkgName, 0)
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
e.printStackTrace()
|
||||
ctx.startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW, Uri.parse("market://details?id=$pkgName")
|
||||
).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||
)
|
||||
return null
|
||||
}
|
||||
return pkgInfo.applicationInfo.nativeLibraryDir
|
||||
}
|
||||
return ctx.applicationInfo.nativeLibraryDir
|
||||
}
|
||||
private fun getGameLibDir(ctx: Context): String? {
|
||||
val pkgName = getPackageName()
|
||||
if (pkgName != null) {
|
||||
val pkgInfo: PackageInfo = try {
|
||||
ctx.packageManager.getPackageInfo(pkgName, 0)
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
e.printStackTrace()
|
||||
ctx.startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW, Uri.parse("market://details?id=$pkgName")
|
||||
).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||
)
|
||||
return null
|
||||
}
|
||||
return pkgInfo.applicationInfo.nativeLibraryDir
|
||||
}
|
||||
return ctx.applicationInfo.nativeLibraryDir
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getGames(ctx: Context, file: DocumentFile): List<Game> {
|
||||
val games = mutableListOf<Game>()
|
||||
companion object {
|
||||
fun getGames(ctx: Context, file: DocumentFile): List<Game> {
|
||||
val games = mutableListOf<Game>()
|
||||
|
||||
if (checkIfGamedir(file)) {
|
||||
games.add(Game(ctx, file))
|
||||
} else {
|
||||
file.listFiles().forEach {
|
||||
if (it.isDirectory) {
|
||||
if (checkIfGamedir(it)) {
|
||||
games.add(Game(ctx, it))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (checkIfGamedir(file)) {
|
||||
games.add(Game(ctx, file))
|
||||
} else {
|
||||
file.listFiles().forEach {
|
||||
if (it.isDirectory) {
|
||||
if (checkIfGamedir(it)) {
|
||||
games.add(Game(ctx, it))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return games
|
||||
}
|
||||
return games
|
||||
}
|
||||
|
||||
fun checkIfGamedir(file: DocumentFile): Boolean {
|
||||
// exclude unfinished downloads
|
||||
if (file.name?.startsWith('.') == true)
|
||||
return false
|
||||
fun checkIfGamedir(file: DocumentFile): Boolean {
|
||||
// exclude unfinished downloads
|
||||
if (file.name?.startsWith('.') == true)
|
||||
return false
|
||||
|
||||
file.findFile("liblist.gam")?.let { return true }
|
||||
file.findFile("gameinfo.txt")?.let { return true }
|
||||
return false
|
||||
}
|
||||
}
|
||||
file.findFile("liblist.gam")?.let { return true }
|
||||
file.findFile("gameinfo.txt")?.let { return true }
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Intent intent = new Intent("su.xash.engine.MOD");
|
||||
|
||||
@@ -5,55 +5,55 @@ import org.json.JSONObject
|
||||
import java.io.InputStream
|
||||
|
||||
class ModDatabase(inputStream: InputStream) {
|
||||
val entries = mutableListOf<Entry>()
|
||||
val entries = mutableListOf<Entry>()
|
||||
|
||||
companion object {
|
||||
const val VERSION = 1
|
||||
companion object {
|
||||
const val VERSION = 1
|
||||
|
||||
fun getFilename(): String {
|
||||
return "v${VERSION}.json"
|
||||
}
|
||||
}
|
||||
fun getFilename(): String {
|
||||
return "v${VERSION}.json"
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
inputStream.bufferedReader().use {
|
||||
val jsonArray = JSONArray(it.readText())
|
||||
init {
|
||||
inputStream.bufferedReader().use {
|
||||
val jsonArray = JSONArray(it.readText())
|
||||
|
||||
for (i in 0..<jsonArray.length()) {
|
||||
entries.add(Entry(jsonArray.getJSONObject(i)))
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i in 0..<jsonArray.length()) {
|
||||
entries.add(Entry(jsonArray.getJSONObject(i)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getByGameDir(gamedir: String): Entry? {
|
||||
return entries.filter { it.gamedir.equals(gamedir) }.firstOrNull()
|
||||
}
|
||||
fun getByGameDir(gamedir: String): Entry? {
|
||||
return entries.filter { it.gamedir.equals(gamedir) }.firstOrNull()
|
||||
}
|
||||
|
||||
|
||||
inner class Entry(jsonObject: JSONObject) {
|
||||
var name: String? = null
|
||||
var appid: Int? = null
|
||||
var gamedir: String? = null
|
||||
inner class Entry(jsonObject: JSONObject) {
|
||||
var name: String? = null
|
||||
var appid: Int? = null
|
||||
var gamedir: String? = null
|
||||
|
||||
// TODO Depots
|
||||
var pkgname: String? = null
|
||||
// TODO Depots
|
||||
var pkgname: String? = null
|
||||
|
||||
init {
|
||||
if (jsonObject.has("name")) {
|
||||
name = jsonObject.getString("name");
|
||||
}
|
||||
init {
|
||||
if (jsonObject.has("name")) {
|
||||
name = jsonObject.getString("name");
|
||||
}
|
||||
|
||||
if (jsonObject.has("app_id")) {
|
||||
appid = jsonObject.getInt("app_id");
|
||||
}
|
||||
if (jsonObject.has("app_id")) {
|
||||
appid = jsonObject.getInt("app_id");
|
||||
}
|
||||
|
||||
if (jsonObject.has("gamedir")) {
|
||||
gamedir = jsonObject.getString("gamedir");
|
||||
}
|
||||
if (jsonObject.has("gamedir")) {
|
||||
gamedir = jsonObject.getString("gamedir");
|
||||
}
|
||||
|
||||
if (jsonObject.has("package_name")) {
|
||||
pkgname = jsonObject.getString("package_name");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (jsonObject.has("package_name")) {
|
||||
pkgname = jsonObject.getString("package_name");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,101 +1,89 @@
|
||||
package su.xash.engine.ui.library
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.core.view.MenuProvider
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import kotlinx.coroutines.launch
|
||||
import su.xash.engine.R
|
||||
import su.xash.engine.adapters.GameAdapter
|
||||
import su.xash.engine.databinding.FragmentLibraryBinding
|
||||
|
||||
class LibraryFragment : Fragment(), MenuProvider {
|
||||
private var _binding: FragmentLibraryBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private var _binding: FragmentLibraryBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val libraryViewModel: LibraryViewModel by activityViewModels()
|
||||
private val libraryViewModel: LibraryViewModel by activityViewModels()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = FragmentLibraryBinding.inflate(inflater, container, false)
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = FragmentLibraryBinding.inflate(inflater, container, false)
|
||||
|
||||
val adapter = GameAdapter(libraryViewModel)
|
||||
binding.gamesList.adapter = adapter
|
||||
val adapter = GameAdapter(libraryViewModel)
|
||||
binding.gamesList.adapter = adapter
|
||||
|
||||
requireActivity().addMenuProvider(this, viewLifecycleOwner, Lifecycle.State.RESUMED)
|
||||
requireActivity().addMenuProvider(this, viewLifecycleOwner, Lifecycle.State.RESUMED)
|
||||
|
||||
return binding.root
|
||||
}
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
binding.swipeRefresh.setOnRefreshListener { libraryViewModel.reloadGames(requireContext()) }
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
binding.swipeRefresh.setOnRefreshListener { libraryViewModel.reloadGames(requireContext()) }
|
||||
|
||||
libraryViewModel.isReloading.observe(viewLifecycleOwner) {
|
||||
binding.swipeRefresh.isRefreshing = it
|
||||
}
|
||||
libraryViewModel.isReloading.observe(viewLifecycleOwner) {
|
||||
binding.swipeRefresh.isRefreshing = it
|
||||
}
|
||||
|
||||
libraryViewModel.installedGames.observe(viewLifecycleOwner) {
|
||||
(binding.gamesList.adapter as GameAdapter).submitList(it)
|
||||
}
|
||||
libraryViewModel.installedGames.observe(viewLifecycleOwner) {
|
||||
(binding.gamesList.adapter as GameAdapter).submitList(it)
|
||||
}
|
||||
|
||||
libraryViewModel.workInfos.observe(viewLifecycleOwner) {
|
||||
libraryViewModel.refreshDownloads(requireContext())
|
||||
}
|
||||
libraryViewModel.workInfos.observe(viewLifecycleOwner) {
|
||||
libraryViewModel.refreshDownloads(requireContext())
|
||||
}
|
||||
|
||||
libraryViewModel.downloads.observe(viewLifecycleOwner) {
|
||||
libraryViewModel.reloadGames(requireContext())
|
||||
}
|
||||
}
|
||||
libraryViewModel.downloads.observe(viewLifecycleOwner) {
|
||||
libraryViewModel.reloadGames(requireContext())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||
menuInflater.inflate(R.menu.menu_library, menu)
|
||||
}
|
||||
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
|
||||
menuInflater.inflate(R.menu.menu_library, menu)
|
||||
}
|
||||
|
||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||
when (menuItem.itemId) {
|
||||
R.id.action_browse -> {
|
||||
try {
|
||||
startActivity(
|
||||
Intent(Intent.ACTION_VIEW).setDataAndType(
|
||||
null, "vnd.android.document/directory"
|
||||
)
|
||||
)
|
||||
}
|
||||
catch(e: ActivityNotFoundException) {
|
||||
Toast.makeText(getActivity(), R.string.library_fragment_no_file_manager, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||
when (menuItem.itemId) {
|
||||
R.id.action_browse -> {
|
||||
startActivity(
|
||||
Intent(Intent.ACTION_VIEW).setDataAndType(
|
||||
null, "vnd.android.document/directory"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
R.id.action_install -> {
|
||||
findNavController().navigate(R.id.action_libraryFragment_to_setupFragment)
|
||||
}
|
||||
R.id.action_install -> {
|
||||
findNavController().navigate(R.id.action_libraryFragment_to_setupFragment)
|
||||
}
|
||||
|
||||
R.id.action_settings -> {
|
||||
findNavController().navigate(R.id.action_libraryFragment_to_appSettingsFragment)
|
||||
}
|
||||
}
|
||||
R.id.action_settings -> {
|
||||
findNavController().navigate(R.id.action_libraryFragment_to_appSettingsFragment)
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,126 +2,118 @@ package su.xash.engine.ui.library
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.net.Uri
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.work.Data
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.OutOfQuotaPolicy
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import su.xash.engine.model.Game
|
||||
import su.xash.engine.model.ModDatabase
|
||||
import su.xash.engine.workers.FileCopyWorker
|
||||
import su.xash.engine.workers.KEY_FILE_URI
|
||||
import java.util.Locale
|
||||
|
||||
const val TAG_INSTALL = "TAG_INSTALL"
|
||||
|
||||
class LibraryViewModel(application: Application) : AndroidViewModel(application) {
|
||||
val installedGames: LiveData<List<Game>> get() = _installedGames
|
||||
private val _installedGames = MutableLiveData(emptyList<Game>())
|
||||
val installedGames: LiveData<List<Game>> get() = _installedGames
|
||||
private val _installedGames = MutableLiveData(emptyList<Game>())
|
||||
|
||||
val downloads: LiveData<List<Game>> get() = _downloads
|
||||
private val _downloads = MutableLiveData(emptyList<Game>())
|
||||
val downloads: LiveData<List<Game>> get() = _downloads
|
||||
private val _downloads = MutableLiveData(emptyList<Game>())
|
||||
|
||||
val isReloading: LiveData<Boolean> get() = _isReloading
|
||||
private val _isReloading = MutableLiveData(false)
|
||||
val isReloading: LiveData<Boolean> get() = _isReloading
|
||||
private val _isReloading = MutableLiveData(false)
|
||||
|
||||
private val workManager = WorkManager.getInstance(application.applicationContext)
|
||||
val workInfos: LiveData<List<WorkInfo>> = workManager.getWorkInfosByTagLiveData(TAG_INSTALL)
|
||||
private val workManager = WorkManager.getInstance(application.applicationContext)
|
||||
val workInfos: LiveData<List<WorkInfo>> = workManager.getWorkInfosByTagLiveData(TAG_INSTALL)
|
||||
|
||||
val selectedItem: LiveData<Game> get() = _selectedItem
|
||||
private val _selectedItem = MutableLiveData<Game>()
|
||||
val selectedItem: LiveData<Game> get() = _selectedItem
|
||||
private val _selectedItem = MutableLiveData<Game>()
|
||||
|
||||
val appPreferences = application.getSharedPreferences("app_preferences", Context.MODE_PRIVATE)
|
||||
val modDb: ModDatabase
|
||||
val appPreferences = application.getSharedPreferences("app_preferences", Context.MODE_PRIVATE)
|
||||
val modDb: ModDatabase
|
||||
|
||||
init {
|
||||
modDb = application.assets.open(ModDatabase.getFilename()).use { ModDatabase(it) }
|
||||
reloadGames(application.applicationContext)
|
||||
}
|
||||
init {
|
||||
modDb = application.assets.open(ModDatabase.getFilename()).use { ModDatabase(it) }
|
||||
reloadGames(application.applicationContext)
|
||||
}
|
||||
|
||||
fun reloadGames(ctx: Context) {
|
||||
if (isReloading.value == true) {
|
||||
return
|
||||
}
|
||||
_isReloading.value = true
|
||||
fun reloadGames(ctx: Context) {
|
||||
if (isReloading.value == true) {
|
||||
return
|
||||
}
|
||||
_isReloading.value = true
|
||||
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
val games = mutableListOf<Game>()
|
||||
val root = DocumentFile.fromFile(ctx.getExternalFilesDir(null)!!)
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
val games = mutableListOf<Game>()
|
||||
val root = DocumentFile.fromFile(ctx.getExternalFilesDir(null)!!)
|
||||
|
||||
val installedGames = Game.getGames(ctx, root)
|
||||
.filter { p -> _downloads.value?.any { p.basedir.name == it.basedir.name } == false }
|
||||
val installedGames = Game.getGames(ctx, root)
|
||||
.filter { p -> _downloads.value?.any { p.basedir.name == it.basedir.name } == false }
|
||||
|
||||
games.addAll(installedGames)
|
||||
downloads.value?.let { games.addAll(it) }
|
||||
games.addAll(installedGames)
|
||||
downloads.value?.let { games.addAll(it) }
|
||||
|
||||
_installedGames.postValue(games)
|
||||
_isReloading.postValue(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
_installedGames.postValue(games)
|
||||
_isReloading.postValue(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun refreshDownloads(ctx: Context) {
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
val games = mutableListOf<Game>()
|
||||
fun refreshDownloads(ctx: Context) {
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
val games = mutableListOf<Game>()
|
||||
|
||||
workInfos.value?.filter {
|
||||
it.state == WorkInfo.State.RUNNING && !it.progress.getString(FileCopyWorker.Input)
|
||||
.isNullOrEmpty()
|
||||
}?.forEach {
|
||||
val uri = Uri.parse(it.progress.getString(FileCopyWorker.Input))
|
||||
val file = DocumentFile.fromTreeUri(ctx, uri)
|
||||
games.addAll(Game.getGames(ctx, file!!))
|
||||
games.forEach { g -> g.installed = false }
|
||||
}
|
||||
workInfos.value?.filter {
|
||||
it.state == WorkInfo.State.RUNNING && !it.progress.getString(FileCopyWorker.Input)
|
||||
.isNullOrEmpty()
|
||||
}?.forEach {
|
||||
val uri = Uri.parse(it.progress.getString(FileCopyWorker.Input))
|
||||
val file = DocumentFile.fromTreeUri(ctx, uri)
|
||||
games.addAll(Game.getGames(ctx, file!!))
|
||||
games.forEach { g -> g.installed = false }
|
||||
}
|
||||
|
||||
_downloads.postValue(games)
|
||||
}
|
||||
}
|
||||
}
|
||||
_downloads.postValue(games)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun installGame(uri: Uri) {
|
||||
val data = Data.Builder().putString(KEY_FILE_URI, uri.toString()).build()
|
||||
val request = OneTimeWorkRequestBuilder<FileCopyWorker>().run {
|
||||
setInputData(data)
|
||||
addTag(TAG_INSTALL)
|
||||
build()
|
||||
}
|
||||
workManager.enqueue(request)
|
||||
}
|
||||
fun installGame(uri: Uri) {
|
||||
val data = Data.Builder().putString(KEY_FILE_URI, uri.toString()).build()
|
||||
val request = OneTimeWorkRequestBuilder<FileCopyWorker>().run {
|
||||
setInputData(data)
|
||||
addTag(TAG_INSTALL)
|
||||
build()
|
||||
}
|
||||
workManager.enqueue(request)
|
||||
}
|
||||
|
||||
fun setSelectedGame(game: Game) {
|
||||
_selectedItem.value = game
|
||||
}
|
||||
fun setSelectedGame(game: Game) {
|
||||
_selectedItem.value = game
|
||||
}
|
||||
|
||||
fun uninstallGame(game: Game) {
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
game.installed = false
|
||||
game.basedir.delete()
|
||||
_installedGames.postValue(_installedGames.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
fun uninstallGame(game: Game) {
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
game.installed = false
|
||||
game.basedir.delete()
|
||||
_installedGames.postValue(_installedGames.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun startEngine(ctx: Context, game: Game) {
|
||||
game.startEngine(ctx)
|
||||
}
|
||||
}
|
||||
fun startEngine(ctx: Context, game: Game) {
|
||||
game.startEngine(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,24 +8,24 @@ import androidx.fragment.app.Fragment
|
||||
import su.xash.engine.databinding.FragmentAppSettingsBinding
|
||||
|
||||
class AppSettingsFragment : Fragment() {
|
||||
private var _binding: FragmentAppSettingsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private var _binding: FragmentAppSettingsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = FragmentAppSettingsBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = FragmentAppSettingsBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
childFragmentManager.beginTransaction()
|
||||
.add(binding.settingsFragment.id, AppSettingsPreferenceFragment()).commit();
|
||||
}
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
childFragmentManager.beginTransaction()
|
||||
.add(binding.settingsFragment.id, AppSettingsPreferenceFragment()).commit();
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import androidx.preference.PreferenceFragmentCompat
|
||||
import su.xash.engine.R
|
||||
|
||||
class AppSettingsPreferenceFragment() : PreferenceFragmentCompat() {
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
preferenceManager.sharedPreferencesName = "app_preferences";
|
||||
setPreferencesFromResource(R.xml.app_preferences, rootKey);
|
||||
}
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
preferenceManager.sharedPreferencesName = "app_preferences";
|
||||
setPreferencesFromResource(R.xml.app_preferences, rootKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,53 +12,53 @@ import su.xash.engine.databinding.FragmentGameSettingsBinding
|
||||
import su.xash.engine.ui.library.LibraryViewModel
|
||||
|
||||
class GameSettingsFragment : Fragment() {
|
||||
private var _binding: FragmentGameSettingsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private var _binding: FragmentGameSettingsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val libraryViewModel: LibraryViewModel by activityViewModels()
|
||||
private val libraryViewModel: LibraryViewModel by activityViewModels()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = FragmentGameSettingsBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = FragmentGameSettingsBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val game = libraryViewModel.selectedItem.value!!
|
||||
val game = libraryViewModel.selectedItem.value!!
|
||||
|
||||
binding.gameCard.apply {
|
||||
gameTitle.text = game.title
|
||||
binding.gameCard.apply {
|
||||
gameTitle.text = game.title
|
||||
|
||||
if (game.icon != null) {
|
||||
gameIcon.setImageBitmap(game.icon)
|
||||
} else {
|
||||
gameIcon.visibility = View.GONE
|
||||
}
|
||||
if (game.icon != null) {
|
||||
gameIcon.setImageBitmap(game.icon)
|
||||
} else {
|
||||
gameIcon.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (game.cover != null) {
|
||||
gameCover.setImageBitmap(game.cover)
|
||||
} else {
|
||||
gameCover.visibility = View.GONE
|
||||
}
|
||||
if (game.cover != null) {
|
||||
gameCover.setImageBitmap(game.cover)
|
||||
} else {
|
||||
gameCover.visibility = View.GONE
|
||||
}
|
||||
|
||||
buttonsContainer.visibility = View.GONE
|
||||
}
|
||||
buttonsContainer.visibility = View.GONE
|
||||
}
|
||||
|
||||
childFragmentManager.beginTransaction()
|
||||
.add(binding.settingsFragment.id, GameSettingsPreferenceFragment(game))
|
||||
.commit();
|
||||
childFragmentManager.beginTransaction()
|
||||
.add(binding.settingsFragment.id, GameSettingsPreferenceFragment(game))
|
||||
.commit();
|
||||
|
||||
binding.bottomNavigation.menu.findItem(R.id.action_uninstall).setOnMenuItemClickListener {
|
||||
libraryViewModel.uninstallGame(game)
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
}
|
||||
binding.bottomNavigation.menu.findItem(R.id.action_uninstall).setOnMenuItemClickListener {
|
||||
libraryViewModel.uninstallGame(game)
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,33 +8,33 @@ import su.xash.engine.R
|
||||
import su.xash.engine.model.Game
|
||||
|
||||
class GameSettingsPreferenceFragment(val game: Game) : PreferenceFragmentCompat() {
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
preferenceManager.sharedPreferencesName = game.basedir.name;
|
||||
setPreferencesFromResource(R.xml.game_preferences, rootKey);
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
preferenceManager.sharedPreferencesName = game.basedir.name;
|
||||
setPreferencesFromResource(R.xml.game_preferences, rootKey);
|
||||
|
||||
val packageList = findPreference<ListPreference>("package_name")!!
|
||||
packageList.entries = arrayOf(getString(R.string.app_name))
|
||||
packageList.entryValues = arrayOf(requireContext().packageName)
|
||||
val packageList = findPreference<ListPreference>("package_name")!!
|
||||
packageList.entries = arrayOf(getString(R.string.app_name))
|
||||
packageList.entryValues = arrayOf(requireContext().packageName)
|
||||
|
||||
if (packageList.value == null) {
|
||||
packageList.setValueIndex(0);
|
||||
}
|
||||
if (packageList.value == null) {
|
||||
packageList.setValueIndex(0);
|
||||
}
|
||||
|
||||
val separatePackages = findPreference<SwitchPreferenceCompat>("separate_libraries")!!
|
||||
val clientPackage = findPreference<ListPreference>("client_package")!!
|
||||
val serverPackage = findPreference<ListPreference>("server_package")!!
|
||||
separatePackages.setOnPreferenceChangeListener { _, newValue ->
|
||||
if (newValue == true) {
|
||||
packageList.isVisible = false
|
||||
clientPackage.isVisible = true
|
||||
serverPackage.isVisible = true
|
||||
} else {
|
||||
packageList.isVisible = true
|
||||
clientPackage.isVisible = false
|
||||
serverPackage.isVisible = false
|
||||
}
|
||||
val separatePackages = findPreference<SwitchPreferenceCompat>("separate_libraries")!!
|
||||
val clientPackage = findPreference<ListPreference>("client_package")!!
|
||||
val serverPackage = findPreference<ListPreference>("server_package")!!
|
||||
separatePackages.setOnPreferenceChangeListener { _, newValue ->
|
||||
if (newValue == true) {
|
||||
packageList.isVisible = false
|
||||
clientPackage.isVisible = true
|
||||
serverPackage.isVisible = true
|
||||
} else {
|
||||
packageList.isVisible = true
|
||||
clientPackage.isVisible = false
|
||||
serverPackage.isVisible = false
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,37 +12,37 @@ import su.xash.engine.ui.setup.pages.LocationPageFragment
|
||||
import su.xash.engine.ui.setup.pages.WelcomePageFragment
|
||||
|
||||
class SetupFragment : Fragment() {
|
||||
private var _binding: FragmentSetupBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private val setupViewModel: SetupViewModel by activityViewModels()
|
||||
private var _binding: FragmentSetupBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private val setupViewModel: SetupViewModel by activityViewModels()
|
||||
|
||||
private lateinit var setupPageAdapter: SetupPageAdapter
|
||||
private lateinit var setupPageAdapter: SetupPageAdapter
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = FragmentSetupBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = FragmentSetupBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
setupPageAdapter = SetupPageAdapter(this)
|
||||
binding.viewPager.isUserInputEnabled = false
|
||||
binding.viewPager.adapter = setupPageAdapter
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
setupPageAdapter = SetupPageAdapter(this)
|
||||
binding.viewPager.isUserInputEnabled = false
|
||||
binding.viewPager.adapter = setupPageAdapter
|
||||
|
||||
setupViewModel.pageNumber.observe(viewLifecycleOwner) {
|
||||
binding.viewPager.setCurrentItem(it, true)
|
||||
}
|
||||
}
|
||||
setupViewModel.pageNumber.observe(viewLifecycleOwner) {
|
||||
binding.viewPager.setCurrentItem(it, true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
||||
class SetupPageAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {
|
||||
val pages = listOf(WelcomePageFragment(), LocationPageFragment())
|
||||
override fun getItemCount(): Int = 2
|
||||
override fun createFragment(position: Int): Fragment = pages[position]
|
||||
val pages = listOf(WelcomePageFragment(), LocationPageFragment())
|
||||
override fun getItemCount(): Int = 2
|
||||
override fun createFragment(position: Int): Fragment = pages[position]
|
||||
}
|
||||
|
||||
@@ -10,16 +10,16 @@ import su.xash.engine.MainApplication
|
||||
import su.xash.engine.model.Game
|
||||
|
||||
class SetupViewModel(application: Application) : AndroidViewModel(application) {
|
||||
val pageNumber: LiveData<Int> get() = _pageNumber
|
||||
private val _pageNumber = MutableLiveData(0)
|
||||
val pageNumber: LiveData<Int> get() = _pageNumber
|
||||
private val _pageNumber = MutableLiveData(0)
|
||||
|
||||
fun checkIfGameDir(uri: Uri): Boolean {
|
||||
val ctx = getApplication<MainApplication>().applicationContext
|
||||
val file = DocumentFile.fromTreeUri(ctx, uri)!!
|
||||
return Game.checkIfGamedir(file)
|
||||
}
|
||||
fun checkIfGameDir(uri: Uri): Boolean {
|
||||
val ctx = getApplication<MainApplication>().applicationContext
|
||||
val file = DocumentFile.fromTreeUri(ctx, uri)!!
|
||||
return Game.checkIfGamedir(file)
|
||||
}
|
||||
|
||||
fun setPageNumber(pos: Int) {
|
||||
_pageNumber.value = pos
|
||||
}
|
||||
fun setPageNumber(pos: Int) {
|
||||
_pageNumber.value = pos
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,44 +16,47 @@ import su.xash.engine.ui.library.LibraryViewModel
|
||||
import su.xash.engine.ui.setup.SetupViewModel
|
||||
|
||||
class LocationPageFragment : Fragment() {
|
||||
private var _binding: PageLocationBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private val setupViewModel: SetupViewModel by activityViewModels()
|
||||
private val libraryViewModel: LibraryViewModel by activityViewModels()
|
||||
private var _binding: PageLocationBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private val setupViewModel: SetupViewModel by activityViewModels()
|
||||
private val libraryViewModel: LibraryViewModel by activityViewModels()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = PageLocationBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = PageLocationBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
binding.pageButton.setOnClickListener {
|
||||
getGamesDirectory.launch(null)
|
||||
}
|
||||
}
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
binding.pageButton.setOnClickListener {
|
||||
getGamesDirectory.launch(null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
private val getGamesDirectory =
|
||||
registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) {
|
||||
it?.let {
|
||||
if (!setupViewModel.checkIfGameDir(it)) {
|
||||
MaterialAlertDialogBuilder(requireContext()).apply {
|
||||
setTitle(R.string.error)
|
||||
setMessage(R.string.setup_location_empty)
|
||||
setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() }
|
||||
show()
|
||||
}
|
||||
} else {
|
||||
requireContext().contentResolver.takePersistableUriPermission(it, Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
libraryViewModel.installGame(it)
|
||||
findNavController().navigate(R.id.action_setupFragment_to_libraryFragment)
|
||||
}
|
||||
}
|
||||
}
|
||||
private val getGamesDirectory =
|
||||
registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) {
|
||||
it?.let {
|
||||
if (!setupViewModel.checkIfGameDir(it)) {
|
||||
MaterialAlertDialogBuilder(requireContext()).apply {
|
||||
setTitle(R.string.error)
|
||||
setMessage(R.string.setup_location_empty)
|
||||
setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() }
|
||||
show()
|
||||
}
|
||||
} else {
|
||||
requireContext().contentResolver.takePersistableUriPermission(
|
||||
it,
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
)
|
||||
libraryViewModel.installGame(it)
|
||||
findNavController().navigate(R.id.action_setupFragment_to_libraryFragment)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,26 +10,26 @@ import su.xash.engine.databinding.PageWelcomeBinding
|
||||
import su.xash.engine.ui.setup.SetupViewModel
|
||||
|
||||
class WelcomePageFragment : Fragment() {
|
||||
private var _binding: PageWelcomeBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private val setupViewModel: SetupViewModel by activityViewModels()
|
||||
private var _binding: PageWelcomeBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private val setupViewModel: SetupViewModel by activityViewModels()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = PageWelcomeBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding = PageWelcomeBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
binding.pageButton.setOnClickListener {
|
||||
setupViewModel.setPageNumber(1)
|
||||
}
|
||||
setupViewModel.setPageNumber(0)
|
||||
}
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
binding.pageButton.setOnClickListener {
|
||||
setupViewModel.setPageNumber(1)
|
||||
}
|
||||
setupViewModel.setPageNumber(0)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,86 +12,87 @@ import kotlinx.coroutines.withContext
|
||||
const val KEY_FILE_URI = "KEY_FILE_URI"
|
||||
|
||||
class FileCopyWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx, params) {
|
||||
companion object {
|
||||
const val Input = "Input"
|
||||
const val Progress = "Progress"
|
||||
}
|
||||
companion object {
|
||||
const val Input = "Input"
|
||||
const val Progress = "Progress"
|
||||
}
|
||||
|
||||
private var fileCount = 0
|
||||
private var fileCopied = 0
|
||||
private var fileCount = 0
|
||||
private var fileCopied = 0
|
||||
|
||||
override suspend fun doWork(): Result {
|
||||
withContext(Dispatchers.IO) {
|
||||
val fileUri = inputData.getString(KEY_FILE_URI)
|
||||
setProgress(workDataOf(Input to fileUri))
|
||||
override suspend fun doWork(): Result {
|
||||
withContext(Dispatchers.IO) {
|
||||
val fileUri = inputData.getString(KEY_FILE_URI)
|
||||
setProgress(workDataOf(Input to fileUri))
|
||||
|
||||
val uri = Uri.parse(fileUri)
|
||||
val source = DocumentFile.fromTreeUri(applicationContext, uri)
|
||||
val uri = Uri.parse(fileUri)
|
||||
val source = DocumentFile.fromTreeUri(applicationContext, uri)
|
||||
|
||||
fileCount = source?.countDirFiles() ?: return@withContext Result.failure()
|
||||
fileCount = source?.countDirFiles() ?: return@withContext Result.failure()
|
||||
|
||||
setProgress(workDataOf(Progress to 0f))
|
||||
setProgress(workDataOf(Progress to 0f))
|
||||
|
||||
val gamedir = source.name!!
|
||||
val externalFilesDir = DocumentFile.fromFile(applicationContext.getExternalFilesDir(null)!!)
|
||||
val gamedir = source.name!!
|
||||
val externalFilesDir =
|
||||
DocumentFile.fromFile(applicationContext.getExternalFilesDir(null)!!)
|
||||
|
||||
// create a directory to store staged files
|
||||
val target = externalFilesDir.createDirectory(".$gamedir")!!
|
||||
// create a directory to store staged files
|
||||
val target = externalFilesDir.createDirectory(".$gamedir")!!
|
||||
|
||||
source.copyDirTo(applicationContext, this@FileCopyWorker, target)
|
||||
source.copyDirTo(applicationContext, this@FileCopyWorker, target)
|
||||
|
||||
target.renameTo(gamedir)
|
||||
target.renameTo(gamedir)
|
||||
|
||||
setProgress(workDataOf(Progress to 1f))
|
||||
}
|
||||
return Result.success()
|
||||
}
|
||||
setProgress(workDataOf(Progress to 1f))
|
||||
}
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
suspend fun fileCopied(count: Int) {
|
||||
if(count == 0)
|
||||
return
|
||||
suspend fun fileCopied(count: Int) {
|
||||
if (count == 0)
|
||||
return
|
||||
|
||||
fileCopied += count
|
||||
val percentage: Float = fileCopied.toFloat() / fileCount.toFloat();
|
||||
setProgress(workDataOf(Progress to percentage))
|
||||
}
|
||||
fileCopied += count
|
||||
val percentage: Float = fileCopied.toFloat() / fileCount.toFloat();
|
||||
setProgress(workDataOf(Progress to percentage))
|
||||
}
|
||||
}
|
||||
|
||||
fun DocumentFile.countDirFiles(): Int {
|
||||
var count: Int = 0
|
||||
var count: Int = 0
|
||||
|
||||
listFiles().forEach {
|
||||
if (it.isDirectory)
|
||||
count += it.countDirFiles()
|
||||
else
|
||||
count++
|
||||
}
|
||||
listFiles().forEach {
|
||||
if (it.isDirectory)
|
||||
count += it.countDirFiles()
|
||||
else
|
||||
count++
|
||||
}
|
||||
|
||||
return count
|
||||
return count
|
||||
}
|
||||
|
||||
fun DocumentFile.copyFileTo(ctx: Context, file: DocumentFile) {
|
||||
val outFile = file.createFile("application", name!!)!!
|
||||
val outFile = file.createFile("application", name!!)!!
|
||||
|
||||
ctx.contentResolver.openOutputStream(outFile.uri).use { os ->
|
||||
ctx.contentResolver.openInputStream(uri).use {
|
||||
it?.copyTo(os!!)
|
||||
}
|
||||
}
|
||||
ctx.contentResolver.openOutputStream(outFile.uri).use { os ->
|
||||
ctx.contentResolver.openInputStream(uri).use {
|
||||
it?.copyTo(os!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun DocumentFile.copyDirTo(ctx: Context, worker: FileCopyWorker, dir: DocumentFile) {
|
||||
var count: Int = 0
|
||||
var count: Int = 0
|
||||
|
||||
listFiles().forEach {
|
||||
if (it.isDirectory) {
|
||||
val outDir = dir.createDirectory(it.name!!)!!
|
||||
it.copyDirTo(ctx, worker, outDir)
|
||||
} else {
|
||||
it.copyFileTo(ctx, dir)
|
||||
count++
|
||||
}
|
||||
}
|
||||
listFiles().forEach {
|
||||
if (it.isDirectory) {
|
||||
val outDir = dir.createDirectory(it.name!!)!!
|
||||
it.copyDirTo(ctx, worker, outDir)
|
||||
} else {
|
||||
it.copyFileTo(ctx, dir)
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
worker.fileCopied(count)
|
||||
worker.fileCopied(count)
|
||||
}
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appBarLayout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appBarLayout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/fragmentContainerView"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:defaultNavHost="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/appBarLayout"
|
||||
app:navGraph="@navigation/nav_graph"
|
||||
tools:layout="@layout/fragment_library"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/fragmentContainerView"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:defaultNavHost="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/appBarLayout"
|
||||
app:navGraph="@navigation/nav_graph"
|
||||
tools:layout="@layout/fragment_library" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -1,111 +1,111 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView 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"
|
||||
style="@style/Widget.Material3.CardView.Filled"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
style="@style/Widget.Material3.CardView.Filled"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="128dp">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="128dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/gameCover"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
tools:src="@android:mipmap/sym_def_app_icon" />
|
||||
<ImageView
|
||||
android:id="@+id/gameCover"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"
|
||||
tools:src="@android:mipmap/sym_def_app_icon" />
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/Widget.Material3.CardView.Filled"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:layout_margin="8dp"
|
||||
app:contentPadding="10dp"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/buttonsContainer"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/Widget.Material3.CardView.Filled"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:layout_margin="8dp"
|
||||
app:contentPadding="10dp"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/buttonsContainer"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/gameIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginRight="8dp"
|
||||
android:adjustViewBounds="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/gameTitle"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@android:mipmap/sym_def_app_icon" />
|
||||
<ImageView
|
||||
android:id="@+id/gameIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginRight="8dp"
|
||||
android:adjustViewBounds="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/gameTitle"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@android:mipmap/sym_def_app_icon" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/gameTitle"
|
||||
style="@style/TextAppearance.Material3.TitleMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:singleLine="true"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/gameIcon"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Game Title" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/gameTitle"
|
||||
style="@style/TextAppearance.Material3.TitleMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:singleLine="true"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/gameIcon"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Game Title" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/buttonsContainer"
|
||||
style="@style/Widget.Material3.CardView.Filled"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/buttonsContainer"
|
||||
style="@style/Widget.Material3.CardView.Filled"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
android:id="@+id/progressIndicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
android:padding="10dp"
|
||||
android:visibility="gone"
|
||||
app:indicatorSize="20dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
android:id="@+id/progressIndicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
android:padding="10dp"
|
||||
android:visibility="gone"
|
||||
app:indicatorSize="20dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/launchButton"
|
||||
style="@style/Widget.Material3.Button.IconButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_baseline_play_arrow_24"
|
||||
app:layout_constraintEnd_toStartOf="@+id/settingsButton" />
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/launchButton"
|
||||
style="@style/Widget.Material3.Button.IconButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_baseline_play_arrow_24"
|
||||
app:layout_constraintEnd_toStartOf="@+id/settingsButton" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/settingsButton"
|
||||
style="@style/Widget.Material3.Button.IconButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_baseline_settings_24"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/settingsButton"
|
||||
style="@style/Widget.Material3.Button.IconButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_baseline_settings_24"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!-- <com.google.android.material.textfield.TextInputLayout-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- app:layout_constraintTop_toTopOf="parent"-->
|
||||
<!-- app:layout_constraintBottom_toBottomOf="parent">-->
|
||||
<!-- <com.google.android.material.textfield.TextInputLayout-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- app:layout_constraintTop_toTopOf="parent"-->
|
||||
<!-- app:layout_constraintBottom_toBottomOf="parent">-->
|
||||
|
||||
<!-- <com.google.android.material.textfield.TextInputEditText-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content" />-->
|
||||
<!-- </com.google.android.material.textfield.TextInputLayout>-->
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"/>
|
||||
<!-- <com.google.android.material.textfield.TextInputEditText-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content" />-->
|
||||
<!-- </com.google.android.material.textfield.TextInputLayout>-->
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleMedium" />
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@android:id/title"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@android:id/title"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingHorizontal="8dp">
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingHorizontal="8dp">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/settingsFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:layout="@android:layout/list_content" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/settingsFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:layout="@android:layout/list_content" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -1,39 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<include
|
||||
android:id="@+id/gameCard"
|
||||
layout="@layout/card_game"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<include
|
||||
android:id="@+id/gameCard"
|
||||
layout="@layout/card_game"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/Widget.Material3.CardView.Filled"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
app:contentPadding="16dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/gameCard">
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/Widget.Material3.CardView.Filled"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
app:contentPadding="16dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/gameCard">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/settingsFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:layout="@android:layout/list_content" />
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/settingsFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:layout="@android:layout/list_content" />
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
android:id="@+id/bottomNavigation"
|
||||
style="@style/Widget.MaterialComponents.BottomNavigationView.Colored"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:menu="@menu/menu_game_settings" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
android:id="@+id/bottomNavigation"
|
||||
style="@style/Widget.MaterialComponents.BottomNavigationView.Colored"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:menu="@menu/menu_game_settings" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout 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:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/swipeRefresh">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/swipeRefresh">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/gamesList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layoutManager="LinearLayoutManager"
|
||||
android:clipToPadding="false"
|
||||
android:paddingHorizontal="8dp"
|
||||
tools:listitem="@layout/card_game" />
|
||||
</RelativeLayout>
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/gamesList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layoutManager="LinearLayoutManager"
|
||||
android:clipToPadding="false"
|
||||
android:paddingHorizontal="8dp"
|
||||
tools:listitem="@layout/card_game" />
|
||||
</RelativeLayout>
|
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/viewPager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/viewPager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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">
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"/>
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@android:id/title"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleMedium" />
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/summary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@android:id/title"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -1,51 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/pagePic"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="64dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:src="@drawable/ic_baseline_folder_open_24"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/pageTitle"/>
|
||||
<ImageView
|
||||
android:id="@+id/pagePic"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="64dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:src="@drawable/ic_baseline_folder_open_24"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/pageTitle" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pageTitle"
|
||||
style="@style/TextAppearance.Material3.TitleLarge"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:text="@string/setup_location_title"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@id/pageMessage"
|
||||
app:layout_constraintTop_toBottomOf="@id/pagePic" />
|
||||
<TextView
|
||||
android:id="@+id/pageTitle"
|
||||
style="@style/TextAppearance.Material3.TitleLarge"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:text="@string/setup_location_title"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@id/pageMessage"
|
||||
app:layout_constraintTop_toBottomOf="@id/pagePic" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pageMessage"
|
||||
style="@style/TextAppearance.Material3.TitleMedium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:text="@string/setup_location_message"
|
||||
app:layout_constraintBottom_toTopOf="@id/pageButton"
|
||||
app:layout_constraintTop_toBottomOf="@id/pageTitle" />
|
||||
<TextView
|
||||
android:id="@+id/pageMessage"
|
||||
style="@style/TextAppearance.Material3.TitleMedium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:text="@string/setup_location_message"
|
||||
app:layout_constraintBottom_toTopOf="@id/pageButton"
|
||||
app:layout_constraintTop_toBottomOf="@id/pageTitle" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/pageButton"
|
||||
android:layout_width="240dp"
|
||||
android:layout_marginBottom="128dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ok"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/pageMessage" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<Button
|
||||
android:id="@+id/pageButton"
|
||||
android:layout_width="240dp"
|
||||
android:layout_marginBottom="128dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ok"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/pageMessage" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -1,51 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/pagePic"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="64dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:src="@mipmap/ic_launcher"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/pageTitle"/>
|
||||
<ImageView
|
||||
android:id="@+id/pagePic"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="64dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:src="@mipmap/ic_launcher"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/pageTitle" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pageTitle"
|
||||
style="@style/TextAppearance.Material3.TitleLarge"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:gravity="center"
|
||||
android:textStyle="bold"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:text="@string/setup_welcome_title"
|
||||
app:layout_constraintBottom_toTopOf="@id/pageMessage"
|
||||
app:layout_constraintTop_toBottomOf="@id/pagePic" />
|
||||
<TextView
|
||||
android:id="@+id/pageTitle"
|
||||
style="@style/TextAppearance.Material3.TitleLarge"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:gravity="center"
|
||||
android:textStyle="bold"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:text="@string/setup_welcome_title"
|
||||
app:layout_constraintBottom_toTopOf="@id/pageMessage"
|
||||
app:layout_constraintTop_toBottomOf="@id/pagePic" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pageMessage"
|
||||
style="@style/TextAppearance.Material3.TitleMedium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:text="@string/setup_welcome_message"
|
||||
app:layout_constraintBottom_toTopOf="@id/pageButton"
|
||||
app:layout_constraintTop_toBottomOf="@id/pageTitle" />
|
||||
<TextView
|
||||
android:id="@+id/pageMessage"
|
||||
style="@style/TextAppearance.Material3.TitleMedium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:text="@string/setup_welcome_message"
|
||||
app:layout_constraintBottom_toTopOf="@id/pageButton"
|
||||
app:layout_constraintTop_toBottomOf="@id/pageTitle" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/pageButton"
|
||||
android:layout_width="240dp"
|
||||
android:layout_marginBottom="128dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/next"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/pageMessage" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<Button
|
||||
android:id="@+id/pageButton"
|
||||
android:layout_width="240dp"
|
||||
android:layout_marginBottom="128dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/next"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/pageMessage" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"/>
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleMedium" />
|
||||
|
||||
<com.google.android.material.materialswitch.MaterialSwitch
|
||||
android:id="@+id/switchWidget"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<com.google.android.material.materialswitch.MaterialSwitch
|
||||
android:id="@+id/switchWidget"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_dedicated"
|
||||
android:icon="@drawable/ic_baseline_terminal_24"
|
||||
android:title="@string/dedicated_server"
|
||||
app:showAsAction="always|withText"
|
||||
android:visible="false"/>
|
||||
<item
|
||||
android:id="@+id/action_uninstall"
|
||||
android:icon="@drawable/ic_baseline_delete_24"
|
||||
android:title="@string/uninstall"
|
||||
app:showAsAction="always|withText" />
|
||||
</menu>
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_dedicated"
|
||||
android:icon="@drawable/ic_baseline_terminal_24"
|
||||
android:title="@string/dedicated_server"
|
||||
app:showAsAction="always|withText"
|
||||
android:visible="false" />
|
||||
<item
|
||||
android:id="@+id/action_uninstall"
|
||||
android:icon="@drawable/ic_baseline_delete_24"
|
||||
android:title="@string/uninstall"
|
||||
app:showAsAction="always|withText" />
|
||||
</menu>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_browse"
|
||||
android:icon="@drawable/ic_baseline_folder_open_24"
|
||||
android:title="@string/browse"
|
||||
app:showAsAction="always|withText" />
|
||||
<item
|
||||
android:id="@+id/action_install"
|
||||
android:icon="@drawable/ic_baseline_add_24"
|
||||
android:title="@string/install"
|
||||
app:showAsAction="always|withText" />
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:icon="@drawable/ic_baseline_settings_24"
|
||||
android:title="@string/app_settings"
|
||||
app:showAsAction="always|withText"
|
||||
android:visible="false"/>
|
||||
</menu>
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_browse"
|
||||
android:icon="@drawable/ic_baseline_folder_open_24"
|
||||
android:title="@string/browse"
|
||||
app:showAsAction="always|withText" />
|
||||
<item
|
||||
android:id="@+id/action_install"
|
||||
android:icon="@drawable/ic_baseline_add_24"
|
||||
android:title="@string/install"
|
||||
app:showAsAction="always|withText" />
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:icon="@drawable/ic_baseline_settings_24"
|
||||
android:title="@string/app_settings"
|
||||
app:showAsAction="always|withText"
|
||||
android:visible="false" />
|
||||
</menu>
|
||||
|
||||
@@ -1,38 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation 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/nav_graph"
|
||||
android:label="@string/library"
|
||||
app:startDestination="@id/libraryFragment">
|
||||
<fragment
|
||||
android:id="@+id/libraryFragment"
|
||||
android:name="su.xash.engine.ui.library.LibraryFragment"
|
||||
android:label="@string/library">
|
||||
<action
|
||||
android:id="@+id/action_libraryFragment_to_setupFragment"
|
||||
app:destination="@id/setupFragment" />
|
||||
<action
|
||||
android:id="@+id/action_libraryFragment_to_gameSettingsFragment"
|
||||
app:destination="@id/gameSettingsFragment" />
|
||||
<action
|
||||
android:id="@+id/action_libraryFragment_to_appSettingsFragment"
|
||||
app:destination="@id/appSettingsFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/setupFragment"
|
||||
android:name="su.xash.engine.ui.setup.SetupFragment"
|
||||
android:label="@string/setup" >
|
||||
<action
|
||||
android:id="@+id/action_setupFragment_to_libraryFragment"
|
||||
app:destination="@id/libraryFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/gameSettingsFragment"
|
||||
android:name="su.xash.engine.ui.settings.GameSettingsFragment"
|
||||
android:label="@string/game_settings" />
|
||||
<fragment
|
||||
android:id="@+id/appSettingsFragment"
|
||||
android:name="su.xash.engine.ui.settings.AppSettingsFragment"
|
||||
android:label="@string/app_settings" />
|
||||
</navigation>
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/nav_graph"
|
||||
android:label="@string/library"
|
||||
app:startDestination="@id/libraryFragment">
|
||||
<fragment
|
||||
android:id="@+id/libraryFragment"
|
||||
android:name="su.xash.engine.ui.library.LibraryFragment"
|
||||
android:label="@string/library">
|
||||
<action
|
||||
android:id="@+id/action_libraryFragment_to_setupFragment"
|
||||
app:destination="@id/setupFragment" />
|
||||
<action
|
||||
android:id="@+id/action_libraryFragment_to_gameSettingsFragment"
|
||||
app:destination="@id/gameSettingsFragment" />
|
||||
<action
|
||||
android:id="@+id/action_libraryFragment_to_appSettingsFragment"
|
||||
app:destination="@id/appSettingsFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/setupFragment"
|
||||
android:name="su.xash.engine.ui.setup.SetupFragment"
|
||||
android:label="@string/setup">
|
||||
<action
|
||||
android:id="@+id/action_setupFragment_to_libraryFragment"
|
||||
app:destination="@id/libraryFragment" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/gameSettingsFragment"
|
||||
android:name="su.xash.engine.ui.settings.GameSettingsFragment"
|
||||
android:label="@string/game_settings" />
|
||||
<fragment
|
||||
android:id="@+id/appSettingsFragment"
|
||||
android:name="su.xash.engine.ui.settings.AppSettingsFragment"
|
||||
android:label="@string/app_settings" />
|
||||
</navigation>
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="ok">Ok</string>
|
||||
<string name="cancel">Cancelar</string>
|
||||
<string name="next">Próximo</string>
|
||||
<string name="browse">Navegar</string>
|
||||
<string name="ok">Ok</string>
|
||||
<string name="cancel">Cancelar</string>
|
||||
<string name="next">Próximo</string>
|
||||
<string name="browse">Navegar</string>
|
||||
<string name="library">Biblioteca</string>
|
||||
<string name="dedicated_server">Dedicado</string>
|
||||
<string name="error">Erro!</string>
|
||||
<string name="setup">Configurar</string>
|
||||
<string name="app_settings">Configurações</string>
|
||||
<string name="game_settings">Configurações do jogo</string>
|
||||
<string name="game_settings_command_line">Argumentos de linha de comando</string>
|
||||
<string name="game_settings_volume_buttons">Usar botões de volume no jogo</string>
|
||||
<string name="setup_welcome_title">Bem vindo ao Xash3D FWGS!</string>
|
||||
<string name="setup_welcome_message">Agora, nós vamos guiá-lo durante o processo de instalação.</string>
|
||||
<string name="setup_location_title">Jogos</string>
|
||||
<string name="setup_location_message">Selecione a pasta onde seus jogos estão localizados.</string>
|
||||
<string name="setup_location_empty">A pasta selecionada não contem nenhum jogo.</string>
|
||||
<string name="setup_location_invalid">A pasta selecionada é invalida.</string>
|
||||
<string name="preferences_package_name">Bibliotecas de pacotes</string>
|
||||
<string name="preferences_separate_libraries">Bibliotecas de pacotes separados</string>
|
||||
<string name="preferences_client_package">Pacotes de Cliente</string>
|
||||
<string name="preferences_server_package">Pacotes de Servidor</string>
|
||||
<string name="preferences_use_icons">Usar ícones ao inves de imagens de fundo</string>
|
||||
<string name="error">Erro!</string>
|
||||
<string name="setup">Configurar</string>
|
||||
<string name="app_settings">Configurações</string>
|
||||
<string name="game_settings">Configurações do jogo</string>
|
||||
<string name="game_settings_command_line">Argumentos de linha de comando</string>
|
||||
<string name="game_settings_volume_buttons">Usar botões de volume no jogo</string>
|
||||
<string name="setup_welcome_title">Bem vindo ao Xash3D FWGS!</string>
|
||||
<string name="setup_welcome_message">Agora, nós vamos guiá-lo durante o processo de instalação.</string>
|
||||
<string name="setup_location_title">Jogos</string>
|
||||
<string name="setup_location_message">Selecione a pasta onde seus jogos estão localizados.</string>
|
||||
<string name="setup_location_empty">A pasta selecionada não contem nenhum jogo.</string>
|
||||
<string name="setup_location_invalid">A pasta selecionada é invalida.</string>
|
||||
<string name="preferences_package_name">Bibliotecas de pacotes</string>
|
||||
<string name="preferences_separate_libraries">Bibliotecas de pacotes separados</string>
|
||||
<string name="preferences_client_package">Pacotes de Cliente</string>
|
||||
<string name="preferences_server_package">Pacotes de Servidor</string>
|
||||
<string name="preferences_use_icons">Usar ícones ao inves de imagens de fundo</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="cancel">Отмена</string>
|
||||
<string name="ok">ОК</string>
|
||||
<string name="next">Далее</string>
|
||||
<string name="browse">Обзор</string>
|
||||
<string name="cancel">Отмена</string>
|
||||
<string name="ok">ОК</string>
|
||||
<string name="next">Далее</string>
|
||||
<string name="browse">Обзор</string>
|
||||
<string name="library">Библиотека</string>
|
||||
<string name="dedicated_server">Выделенный</string>
|
||||
<string name="error">Ошибка!</string>
|
||||
<string name="setup">Установка</string>
|
||||
<string name="app_settings">Настройки</string>
|
||||
<string name="game_settings">Настройки игры</string>
|
||||
<string name="game_settings_command_line">Аргументы командной строки</string>
|
||||
<string name="game_settings_volume_buttons">Использовать кнопки громкости</string>
|
||||
<string name="setup_welcome_title">Добро пожаловать в Xash3D FWGS!</string>
|
||||
<string name="setup_welcome_message">Теперь мы ознакомим вас с процессом установки.</string>
|
||||
<string name="setup_location_title">Игры</string>
|
||||
<string name="setup_location_message">Выберите папку, в которой находятся ваши игры.</string>
|
||||
<string name="setup_location_empty">Выбранный каталог не содержит ни одной игры.</string>
|
||||
<string name="setup_location_invalid">Выбранный каталог недопустим.</string>
|
||||
<string name="preferences_package_name">Пакет библиотек</string>
|
||||
<string name="preferences_separate_libraries">Библиотеки из отдельных пакетов</string>
|
||||
<string name="preferences_client_package">Пакет клиента</string>
|
||||
<string name="preferences_server_package">Пакет сервера</string>
|
||||
<string name="preferences_use_icons">Использовать иконки вместо фона</string>
|
||||
<string name="error">Ошибка!</string>
|
||||
<string name="setup">Установка</string>
|
||||
<string name="app_settings">Настройки</string>
|
||||
<string name="game_settings">Настройки игры</string>
|
||||
<string name="game_settings_command_line">Аргументы командной строки</string>
|
||||
<string name="game_settings_volume_buttons">Использовать кнопки громкости</string>
|
||||
<string name="setup_welcome_title">Добро пожаловать в Xash3D FWGS!</string>
|
||||
<string name="setup_welcome_message">Теперь мы ознакомим вас с процессом установки.</string>
|
||||
<string name="setup_location_title">Игры</string>
|
||||
<string name="setup_location_message">Выберите папку, в которой находятся ваши игры.</string>
|
||||
<string name="setup_location_empty">Выбранный каталог не содержит ни одной игры.</string>
|
||||
<string name="setup_location_invalid">Выбранный каталог недопустим.</string>
|
||||
<string name="preferences_package_name">Пакет библиотек</string>
|
||||
<string name="preferences_separate_libraries">Библиотеки из отдельных пакетов</string>
|
||||
<string name="preferences_client_package">Пакет клиента</string>
|
||||
<string name="preferences_server_package">Пакет сервера</string>
|
||||
<string name="preferences_use_icons">Использовать иконки вместо фона</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="valve_red">#F74843</color>
|
||||
<color name="hl_orange">#FB7E14</color>
|
||||
<color name="black">#000000</color>
|
||||
<color name="hl_dark_grey">#151515</color>
|
||||
<color name="hl_grey">#292929</color>
|
||||
<color name="valve_red">#F74843</color>
|
||||
<color name="hl_orange">#FB7E14</color>
|
||||
<color name="black">#000000</color>
|
||||
<color name="hl_dark_grey">#151515</color>
|
||||
<color name="hl_grey">#292929</color>
|
||||
</resources>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#F74843</color>
|
||||
</resources>
|
||||
<color name="ic_launcher_background">#F74843</color>
|
||||
</resources>
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
<resources>
|
||||
<style name="Theme.App" parent="Theme.Material3.Dark.NoActionBar">
|
||||
<item name="colorPrimary">@color/hl_orange</item>
|
||||
<item name="colorPrimaryDark">@color/hl_dark_grey</item>
|
||||
<!-- <item name="colorPrimaryContainer">@color/valve_red</item>-->
|
||||
<item name="colorSurface">@color/hl_grey</item>
|
||||
<item name="colorSurfaceVariant">@color/hl_grey</item>
|
||||
<item name="android:colorBackground">@color/hl_dark_grey</item>
|
||||
<item name="colorControlNormal">@color/hl_orange</item>
|
||||
<item name="colorOnPrimary">@color/hl_dark_grey</item>
|
||||
<!-- <item name="colorOnPrimaryContainer">@android:color/white</item>-->
|
||||
<!-- <item name="colorOnSurface">@android:color/white</item>-->
|
||||
<!-- <item name="colorOnSurfaceVariant">@android:color/white</item>-->
|
||||
|
||||
<!-- <item name="shapeAppearanceMediumComponent">@style/ShapeAppearance.App.MediumComponent</item>-->
|
||||
</style>
|
||||
</resources>
|
||||
<style name="Theme.App" parent="Theme.Material3.Dark.NoActionBar">
|
||||
<item name="colorPrimary">@color/hl_orange</item>
|
||||
<item name="colorPrimaryDark">@color/hl_dark_grey</item>
|
||||
<!-- <item name="colorPrimaryContainer">@color/valve_red</item>-->
|
||||
<item name="colorSurface">@color/hl_grey</item>
|
||||
<item name="colorSurfaceVariant">@color/hl_grey</item>
|
||||
<item name="android:colorBackground">@color/hl_dark_grey</item>
|
||||
<item name="colorControlNormal">@color/hl_orange</item>
|
||||
<item name="colorOnPrimary">@color/hl_dark_grey</item>
|
||||
<!-- <item name="colorOnPrimaryContainer">@android:color/white</item>-->
|
||||
<!-- <item name="colorOnSurface">@android:color/white</item>-->
|
||||
<!-- <item name="colorOnSurfaceVariant">@android:color/white</item>-->
|
||||
|
||||
<!-- <item name="shapeAppearanceMediumComponent">@style/ShapeAppearance.App.MediumComponent</item>-->
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<SwitchPreferenceCompat
|
||||
app:key="use_icons"
|
||||
app:layout="@layout/switch_preference"
|
||||
app:title="@string/preferences_use_icons" />
|
||||
</PreferenceScreen>
|
||||
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<SwitchPreferenceCompat
|
||||
app:key="use_icons"
|
||||
app:layout="@layout/switch_preference"
|
||||
app:title="@string/preferences_use_icons" />
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -1,42 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<EditTextPreference
|
||||
app:defaultValue="-console -log"
|
||||
app:key="arguments"
|
||||
app:layout="@layout/edit_text_preference"
|
||||
app:title="@string/game_settings_command_line"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<EditTextPreference
|
||||
app:defaultValue="-console -log"
|
||||
app:key="arguments"
|
||||
app:layout="@layout/edit_text_preference"
|
||||
app:title="@string/game_settings_command_line"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
app:key="use_volume_buttons"
|
||||
app:layout="@layout/switch_preference"
|
||||
app:title="@string/game_settings_volume_buttons" />
|
||||
<SwitchPreferenceCompat
|
||||
app:key="use_volume_buttons"
|
||||
app:layout="@layout/switch_preference"
|
||||
app:title="@string/game_settings_volume_buttons" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
app:key="separate_libraries"
|
||||
app:layout="@layout/switch_preference"
|
||||
app:title="@string/preferences_separate_libraries"
|
||||
app:isPreferenceVisible="false"/>
|
||||
<SwitchPreferenceCompat
|
||||
app:key="separate_libraries"
|
||||
app:layout="@layout/switch_preference"
|
||||
app:title="@string/preferences_separate_libraries"
|
||||
app:isPreferenceVisible="false" />
|
||||
|
||||
<ListPreference
|
||||
app:key="package_name"
|
||||
app:layout="@layout/list_preference"
|
||||
app:title="@string/preferences_package_name"
|
||||
app:useSimpleSummaryProvider="true"
|
||||
app:isPreferenceVisible="false"/>
|
||||
<ListPreference
|
||||
app:key="package_name"
|
||||
app:layout="@layout/list_preference"
|
||||
app:title="@string/preferences_package_name"
|
||||
app:useSimpleSummaryProvider="true"
|
||||
app:isPreferenceVisible="false" />
|
||||
|
||||
<ListPreference
|
||||
app:key="client_package"
|
||||
app:layout="@layout/list_preference"
|
||||
app:title="@string/preferences_client_package"
|
||||
app:useSimpleSummaryProvider="true"
|
||||
app:isPreferenceVisible="false"/>
|
||||
<ListPreference
|
||||
app:key="client_package"
|
||||
app:layout="@layout/list_preference"
|
||||
app:title="@string/preferences_client_package"
|
||||
app:useSimpleSummaryProvider="true"
|
||||
app:isPreferenceVisible="false" />
|
||||
|
||||
<ListPreference
|
||||
app:key="server_package"
|
||||
app:layout="@layout/list_preference"
|
||||
app:title="@string/preferences_server_package"
|
||||
app:useSimpleSummaryProvider="true"
|
||||
app:isPreferenceVisible="false"/>
|
||||
<ListPreference
|
||||
app:key="server_package"
|
||||
app:layout="@layout/list_preference"
|
||||
app:title="@string/preferences_server_package"
|
||||
app:useSimpleSummaryProvider="true"
|
||||
app:isPreferenceVisible="false" />
|
||||
</PreferenceScreen>
|
||||
|
||||
Reference in New Issue
Block a user