Merge branch 'optimize'

This commit is contained in:
ShirosakiMio 2024-08-24 18:18:09 +08:00
commit aeaea5419c
28 changed files with 1881 additions and 1572 deletions

View File

@ -1,5 +1,6 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android' version '1.9.20'
id "org.hidetake.ssh" version "2.11.2"
}
@ -102,6 +103,15 @@ android {
}
pickFirst '**/libbytehook.so'
}
kotlinOptions {
jvmTarget = "1.8"
}
dataBinding {
enabled true
}
buildFeatures {
buildConfig true
}
splits {
def arch = System.getProperty("arch", "all")
if (arch != 'all') {
@ -178,6 +188,7 @@ dependencies {
implementation 'com.google.android.material:material:1.11.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'com.github.Mathias-Boulay:android_gamepad_remapper:06184ddbce'
implementation 'com.github.bumptech.glide:glide:4.16.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'

Binary file not shown.

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,99 @@
package com.mio.util
import android.animation.ObjectAnimator
import android.animation.TimeInterpolator
import android.view.View
class AnimUtil {
companion object {
@JvmStatic
fun playTranslationY(
view: View,
duration: Long,
vararg values: Float
): ObjectAnimator {
return ObjectAnimator.ofFloat(view, "translationY", *values).apply {
this.duration = duration
}
}
@JvmStatic
fun playTranslationX(
view: View,
duration: Long,
vararg values: Float
): ObjectAnimator {
return ObjectAnimator.ofFloat(view, "translationX", *values).apply {
this.duration = duration
}
}
@JvmStatic
fun playTranslationZ(
view: View,
duration: Long,
vararg values: Float
): ObjectAnimator {
return ObjectAnimator.ofFloat(view, "translationZ", *values).apply {
this.duration = duration
}
}
@JvmStatic
fun playRotation(
view: View,
duration: Long,
vararg values: Float
): ObjectAnimator {
return ObjectAnimator.ofFloat(view, "rotation", *values).apply {
this.duration = duration
}
}
@JvmStatic
fun playScaleX(
view: View,
duration: Long,
vararg values: Float
): ObjectAnimator {
return ObjectAnimator.ofFloat(view, "scaleX", *values).apply {
this.duration = duration
}
}
@JvmStatic
fun playScaleY(
view: View,
duration: Long,
vararg values: Float
): ObjectAnimator {
return ObjectAnimator.ofFloat(view, "scaleY", *values).apply {
this.duration = duration
}
}
@JvmStatic
fun playAlpha(
view: View,
duration: Long,
vararg values: Float
): ObjectAnimator {
return ObjectAnimator.ofFloat(view, "alpha", *values).apply {
this.duration = duration
}
}
@JvmStatic
fun ObjectAnimator.delay(delayTime: Long): ObjectAnimator {
this.startDelay = delayTime
return this
}
@JvmStatic
fun ObjectAnimator.interpolator(interpolator: TimeInterpolator): ObjectAnimator {
this.interpolator = interpolator
return this
}
}
}

View File

@ -1,421 +0,0 @@
package com.tungsten.fcl.activity;
import static com.tungsten.fcl.setting.Accounts.getAccountFactory;
import static com.tungsten.fclcore.download.LibraryAnalyzer.LibraryType.MINECRAFT;
import static com.tungsten.fclcore.fakefx.beans.binding.Bindings.createStringBinding;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.LinearLayoutCompat;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.tungsten.fcl.R;
import com.tungsten.fcl.game.JarExecutorHelper;
import com.tungsten.fcl.game.TexturesLoader;
import com.tungsten.fcl.setting.Accounts;
import com.tungsten.fcl.setting.ConfigHolder;
import com.tungsten.fcl.setting.Profile;
import com.tungsten.fcl.setting.Profiles;
import com.tungsten.fcl.ui.UIManager;
import com.tungsten.fcl.ui.version.Versions;
import com.tungsten.fcl.upgrade.UpdateChecker;
import com.tungsten.fcl.util.AndroidUtils;
import com.tungsten.fcl.util.FXUtils;
import com.tungsten.fcl.util.WeakListenerHolder;
import com.tungsten.fclcore.auth.Account;
import com.tungsten.fclcore.auth.authlibinjector.AuthlibInjectorAccount;
import com.tungsten.fclcore.auth.authlibinjector.AuthlibInjectorServer;
import com.tungsten.fclcore.auth.offline.Skin;
import com.tungsten.fclcore.auth.yggdrasil.TextureModel;
import com.tungsten.fclcore.download.LibraryAnalyzer;
import com.tungsten.fclcore.event.Event;
import com.tungsten.fclcore.fakefx.beans.property.ObjectProperty;
import com.tungsten.fclcore.fakefx.beans.property.SimpleObjectProperty;
import com.tungsten.fclcore.fakefx.beans.value.ObservableValue;
import com.tungsten.fclcore.mod.RemoteMod;
import com.tungsten.fclcore.mod.RemoteModRepository;
import com.tungsten.fclcore.task.Schedulers;
import com.tungsten.fclcore.util.Logging;
import com.tungsten.fclcore.util.fakefx.BindingMapping;
import com.tungsten.fcllibrary.component.FCLActivity;
import com.tungsten.fcllibrary.component.theme.ThemeEngine;
import com.tungsten.fcllibrary.component.view.FCLButton;
import com.tungsten.fcllibrary.component.view.FCLDynamicIsland;
import com.tungsten.fcllibrary.component.view.FCLEditText;
import com.tungsten.fcllibrary.component.view.FCLImageView;
import com.tungsten.fcllibrary.component.view.FCLMenuView;
import com.tungsten.fcllibrary.component.view.FCLTextView;
import com.tungsten.fcllibrary.component.view.FCLUILayout;
import com.tungsten.fcllibrary.util.ConvertUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.stream.Stream;
public class MainActivity extends FCLActivity implements FCLMenuView.OnSelectListener, View.OnClickListener {
private static MainActivity instance;
public ConstraintLayout background;
public FCLDynamicIsland titleView;
private UIManager uiManager;
public FCLUILayout uiLayout;
private ScrollView leftMenu;
public FCLMenuView home;
public FCLMenuView manage;
public FCLMenuView download;
public FCLMenuView controller;
public FCLMenuView multiplayer;
public FCLMenuView setting;
public FCLMenuView back;
private LinearLayoutCompat account;
private FCLImageView avatar;
private FCLTextView accountName;
private FCLTextView accountHint;
private LinearLayoutCompat version;
private FCLImageView icon;
private FCLTextView versionName;
private FCLTextView versionHint;
private FCLButton executeJar;
private FCLButton launch;
private ObjectProperty<Account> currentAccount;
private final WeakListenerHolder holder = new WeakListenerHolder();
private Profile profile;
private Consumer<Event> onVersionIconChangedListener;
public static MainActivity getInstance() {
return instance;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
instance = this;
background = findViewById(R.id.background);
background.setBackground(ThemeEngine.getInstance().getTheme().getBackground(this));
titleView = findViewById(R.id.title);
Skin.registerDefaultSkinLoader((type) -> {
switch (type) {
case ALEX:
return Skin.class.getResourceAsStream("/assets/img/alex.png");
case ARI:
return Skin.class.getResourceAsStream("/assets/img/ari.png");
case EFE:
return Skin.class.getResourceAsStream("/assets/img/efe.png");
case KAI:
return Skin.class.getResourceAsStream("/assets/img/kai.png");
case MAKENA:
return Skin.class.getResourceAsStream("/assets/img/makena.png");
case NOOR:
return Skin.class.getResourceAsStream("/assets/img/noor.png");
case STEVE:
return Skin.class.getResourceAsStream("/assets/img/steve.png");
case SUNNY:
return Skin.class.getResourceAsStream("/assets/img/sunny.png");
case ZURI:
return Skin.class.getResourceAsStream("/assets/img/zuri.png");
default:
return null;
}
});
RemoteMod.registerEmptyRemoteMod(new RemoteMod("", "", getString(R.string.mods_broken_dependency_title), getString(R.string.mods_broken_dependency_desc), new ArrayList<>(), "", "", new RemoteMod.IMod() {
@Override
public List<RemoteMod> loadDependencies(RemoteModRepository modRepository) throws IOException {
throw new IOException();
}
@Override
public Stream<RemoteMod.Version> loadVersions(RemoteModRepository modRepository) throws IOException {
throw new IOException();
}
}));
try {
ConfigHolder.init();
} catch (IOException e) {
Logging.LOG.log(Level.WARNING, e.getMessage());
}
uiLayout = findViewById(R.id.ui_layout);
uiLayout.post(() -> {
leftMenu = findViewById(R.id.left_scroll);
ThemeEngine.getInstance().registerEvent(leftMenu, () -> leftMenu.setBackgroundColor(ThemeEngine.getInstance().getTheme().getColor()));
account = findViewById(R.id.account);
avatar = findViewById(R.id.avatar);
accountName = findViewById(R.id.account_name);
accountHint = findViewById(R.id.account_hint);
version = findViewById(R.id.version);
icon = findViewById(R.id.icon);
versionName = findViewById(R.id.version_name);
versionHint = findViewById(R.id.version_hint);
executeJar = findViewById(R.id.execute_jar);
launch = findViewById(R.id.launch);
account.setOnClickListener(this);
version.setOnClickListener(this);
executeJar.setOnClickListener(this);
executeJar.setOnLongClickListener(V -> {
int padding = ConvertUtils.dip2px(MainActivity.this, 15);
FCLEditText editText = new FCLEditText(MainActivity.this);
RelativeLayout layout = new RelativeLayout(MainActivity.this);
editText.setHint("-jar xxx");
editText.setLines(1);
editText.setMaxLines(1);
layout.setPadding(padding, padding, padding, padding);
layout.addView(editText);
AlertDialog dialog = new AlertDialog.Builder(MainActivity.this)
.setTitle(R.string.jar_execute_custom_args)
.setView(layout)
.setPositiveButton(com.tungsten.fcllibrary.R.string.dialog_positive, (dialog1, which) -> JarExecutorHelper.exec(MainActivity.this, null, 8, editText.getText().toString()))
.setNegativeButton(com.tungsten.fcllibrary.R.string.dialog_negative, null)
.create();
layout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
editText.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
ThemeEngine.getInstance().applyFullscreen(dialog.getWindow(), ThemeEngine.getInstance().getTheme().isFullscreen());
dialog.show();
return true;
});
launch.setOnClickListener(this);
launch.setOnLongClickListener(view -> {
startActivity(new Intent(MainActivity.this, ShellActivity.class));
return true;
});
uiManager = new UIManager(this, uiLayout);
uiManager.registerDefaultBackEvent(backToMainUI);
uiManager.init(() -> {
home = findViewById(R.id.home);
manage = findViewById(R.id.manage);
download = findViewById(R.id.download);
controller = findViewById(R.id.controller);
multiplayer = findViewById(R.id.multiplayer);
setting = findViewById(R.id.setting);
back = findViewById(R.id.back);
home.setOnSelectListener(this);
manage.setOnSelectListener(this);
download.setOnSelectListener(this);
controller.setOnSelectListener(this);
multiplayer.setOnSelectListener(this);
setting.setOnSelectListener(this);
back.setOnClickListener(this);
home.setSelected(true);
setupAccountDisplay();
setupVersionDisplay();
UpdateChecker.getInstance().checkAuto(this).start();
});
});
}
public Runnable backToMainUI = () -> {
if (uiManager.getCurrentUI() == uiManager.getMainUI()) {
Intent i = new Intent(Intent.ACTION_MAIN);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addCategory(Intent.CATEGORY_HOME);
startActivity(i);
} else {
home.setSelected(true);
}
};
@Override
public void onBackPressed() {
if (uiManager != null) {
uiManager.onBackPressed();
}
}
@Override
protected void onPause() {
super.onPause();
if (uiManager != null) {
uiManager.onPause();
}
}
@Override
protected void onResume() {
super.onResume();
if (uiManager != null) {
uiManager.onResume();
}
}
@Override
public void onSelect(FCLMenuView view) {
refreshMenuView(view);
if (view == home) {
titleView.setTextWithAnim(getString(R.string.app_name));
uiManager.switchUI(uiManager.getMainUI());
}
if (view == manage) {
String version = Profiles.getSelectedVersion();
if (version == null) {
refreshMenuView(null);
titleView.setTextWithAnim(getString(R.string.version));
uiManager.switchUI(uiManager.getVersionUI());
} else {
titleView.setTextWithAnim(getString(R.string.manage));
uiManager.getManageUI().setVersion(version, Profiles.getSelectedProfile());
uiManager.switchUI(uiManager.getManageUI());
}
}
if (view == download) {
titleView.setTextWithAnim(getString(R.string.download));
uiManager.switchUI(uiManager.getDownloadUI());
}
if (view == controller) {
titleView.setTextWithAnim(getString(R.string.controller));
uiManager.switchUI(uiManager.getControllerUI());
}
if (view == multiplayer) {
titleView.setTextWithAnim(getString(R.string.multiplayer));
uiManager.switchUI(uiManager.getMultiplayerUI());
}
if (view == setting) {
titleView.setTextWithAnim(getString(R.string.setting));
uiManager.switchUI(uiManager.getSettingUI());
}
}
public void refreshMenuView(FCLMenuView view) {
FCLMenuView[] views = {
home,
manage,
download,
controller,
multiplayer,
setting
};
for (FCLMenuView v : views) {
if (v != view) {
v.setSelected(false);
}
}
}
@Override
public void onClick(View view) {
if (view == account && uiManager.getCurrentUI() != uiManager.getAccountUI()) {
refreshMenuView(null);
titleView.setTextWithAnim(getString(R.string.account));
uiManager.switchUI(uiManager.getAccountUI());
}
if (view == version && uiManager.getCurrentUI() != uiManager.getVersionUI()) {
refreshMenuView(null);
titleView.setTextWithAnim(getString(R.string.version));
uiManager.switchUI(uiManager.getVersionUI());
}
if (view == back) {
if (uiManager != null) {
uiManager.onBackPressed();
}
}
if (view == executeJar) {
JarExecutorHelper.start(this, this);
}
if (view == launch) {
Versions.launch(this, Profiles.getSelectedProfile());
}
}
private static ObservableValue<String> accountSubtitle(Context context, Account account) {
if (account instanceof AuthlibInjectorAccount) {
return BindingMapping.of(((AuthlibInjectorAccount) account).getServer(), AuthlibInjectorServer::getName);
} else {
return createStringBinding(() -> Accounts.getLocalizedLoginTypeName(context, getAccountFactory(account)));
}
}
private void setupAccountDisplay() {
currentAccount = new SimpleObjectProperty<Account>() {
@Override
protected void invalidated() {
Account account = get();
if (account == null) {
accountName.stringProperty().unbind();
accountHint.stringProperty().unbind();
avatar.imageProperty().unbind();
accountName.setText(getString(R.string.account_state_no_account));
accountHint.setText(getString(R.string.account_state_add));
avatar.setBackgroundDrawable(new BitmapDrawable(TexturesLoader.toAvatar(TexturesLoader.getDefaultSkin(TextureModel.ALEX).getImage(), ConvertUtils.dip2px(MainActivity.this, 30))));
} else {
accountName.stringProperty().bind(BindingMapping.of(account, Account::getCharacter));
accountHint.stringProperty().bind(accountSubtitle(MainActivity.this, account));
avatar.imageProperty().unbind();
avatar.imageProperty().bind(TexturesLoader.avatarBinding(account, ConvertUtils.dip2px(MainActivity.this, 30)));
}
}
};
currentAccount.bind(Accounts.selectedAccountProperty());
}
public void refreshAvatar(Account account) {
Schedulers.androidUIThread().execute(() -> {
if (currentAccount.get() == account) {
avatar.imageProperty().unbind();
avatar.imageProperty().bind(TexturesLoader.avatarBinding(currentAccount.get(), ConvertUtils.dip2px(MainActivity.this, 30)));
}
});
}
@SuppressLint("UseCompatLoadingForDrawables")
private void loadVersion(String version) {
if (Profiles.getSelectedProfile() != profile) {
profile = Profiles.getSelectedProfile();
if (profile != null) {
onVersionIconChangedListener = profile.getRepository().onVersionIconChanged.registerWeak(event -> this.loadVersion(Profiles.getSelectedVersion()));
}
}
if (version != null && Profiles.getSelectedProfile() != null && Profiles.getSelectedProfile().getRepository().hasVersion(version)) {
String game = Profiles.getSelectedProfile().getRepository().getGameVersion(version).orElse(getString(R.string.message_unknown));
StringBuilder libraries = new StringBuilder(game);
LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(Profiles.getSelectedProfile().getRepository().getResolvedPreservingPatchesVersion(version));
for (LibraryAnalyzer.LibraryMark mark : analyzer) {
String libraryId = mark.getLibraryId();
String libraryVersion = mark.getLibraryVersion();
if (libraryId.equals(MINECRAFT.getPatchId())) continue;
if (AndroidUtils.hasStringId(this, "install_installer_" + libraryId.replace("-", "_"))) {
libraries.append(", ").append(AndroidUtils.getLocalizedText(this, "install_installer_" + libraryId.replace("-", "_")));
if (libraryVersion != null)
libraries.append(": ").append(libraryVersion.replaceAll("(?i)" + libraryId, ""));
}
}
versionName.setText(version);
versionHint.setText(libraries.toString());
icon.setBackgroundDrawable(Profiles.getSelectedProfile().getRepository().getVersionIconImage(version));
} else {
versionName.setText(getString(R.string.version_no_version));
versionHint.setText(getString(R.string.version_manage));
icon.setBackgroundDrawable(getDrawable(R.drawable.img_grass));
}
}
private void setupVersionDisplay() {
holder.add(FXUtils.onWeakChangeAndOperate(Profiles.selectedVersionProperty(), s -> Schedulers.androidUIThread().execute(() -> loadVersion(s))));
}
}

View File

@ -0,0 +1,455 @@
package com.tungsten.fcl.activity
import android.annotation.SuppressLint
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import androidx.appcompat.app.AlertDialog
import androidx.core.view.forEach
import androidx.databinding.DataBindingUtil
import com.tungsten.fcl.R
import com.tungsten.fcl.databinding.ActivityMainBinding
import com.tungsten.fcl.game.JarExecutorHelper
import com.tungsten.fcl.game.TexturesLoader
import com.tungsten.fcl.setting.Accounts
import com.tungsten.fcl.setting.ConfigHolder
import com.tungsten.fcl.setting.Profile
import com.tungsten.fcl.setting.Profiles
import com.tungsten.fcl.ui.UIManager
import com.tungsten.fcl.ui.version.Versions
import com.tungsten.fcl.upgrade.UpdateChecker
import com.tungsten.fcl.util.AndroidUtils
import com.tungsten.fcl.util.FXUtils
import com.tungsten.fcl.util.WeakListenerHolder
import com.tungsten.fclcore.auth.Account
import com.tungsten.fclcore.auth.authlibinjector.AuthlibInjectorAccount
import com.tungsten.fclcore.auth.authlibinjector.AuthlibInjectorServer
import com.tungsten.fclcore.auth.offline.Skin
import com.tungsten.fclcore.auth.yggdrasil.TextureModel
import com.tungsten.fclcore.download.LibraryAnalyzer
import com.tungsten.fclcore.download.LibraryAnalyzer.LibraryType
import com.tungsten.fclcore.event.Event
import com.tungsten.fclcore.fakefx.beans.binding.Bindings
import com.tungsten.fclcore.fakefx.beans.property.ObjectProperty
import com.tungsten.fclcore.fakefx.beans.property.SimpleObjectProperty
import com.tungsten.fclcore.fakefx.beans.value.ObservableValue
import com.tungsten.fclcore.mod.RemoteMod
import com.tungsten.fclcore.mod.RemoteMod.IMod
import com.tungsten.fclcore.mod.RemoteModRepository
import com.tungsten.fclcore.task.Schedulers
import com.tungsten.fclcore.util.Logging
import com.tungsten.fclcore.util.fakefx.BindingMapping
import com.tungsten.fcllibrary.component.FCLActivity
import com.tungsten.fcllibrary.component.theme.ThemeEngine
import com.tungsten.fcllibrary.component.view.FCLEditText
import com.tungsten.fcllibrary.component.view.FCLMenuView
import com.tungsten.fcllibrary.component.view.FCLMenuView.OnSelectListener
import com.tungsten.fcllibrary.util.ConvertUtils
import java.io.IOException
import java.util.function.Consumer
import java.util.logging.Level
import java.util.stream.Stream
class MainActivity : FCLActivity(), OnSelectListener, View.OnClickListener {
companion object {
@SuppressLint("StaticFieldLeak")
@JvmStatic
lateinit var instance: MainActivity
}
lateinit var bind: ActivityMainBinding
private var _uiManager: UIManager? = null
private lateinit var uiManager: UIManager
private lateinit var currentAccount: ObjectProperty<Account?>
private val holder = WeakListenerHolder()
private var profile: Profile? = null
private var onVersionIconChangedListener: Consumer<Event>? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
instance = this
bind = DataBindingUtil.setContentView(this, R.layout.activity_main)
bind.background.background = ThemeEngine.getInstance().getTheme().getBackground(this)
Skin.registerDefaultSkinLoader {
when (it) {
Skin.Type.ALEX -> return@registerDefaultSkinLoader Skin::class.java.getResourceAsStream(
"/assets/img/alex.png"
)
Skin.Type.ARI -> return@registerDefaultSkinLoader Skin::class.java.getResourceAsStream(
"/assets/img/ari.png"
)
Skin.Type.EFE -> return@registerDefaultSkinLoader Skin::class.java.getResourceAsStream(
"/assets/img/efe.png"
)
Skin.Type.KAI -> return@registerDefaultSkinLoader Skin::class.java.getResourceAsStream(
"/assets/img/kai.png"
)
Skin.Type.MAKENA -> return@registerDefaultSkinLoader Skin::class.java.getResourceAsStream(
"/assets/img/makena.png"
)
Skin.Type.NOOR -> return@registerDefaultSkinLoader Skin::class.java.getResourceAsStream(
"/assets/img/noor.png"
)
Skin.Type.STEVE -> return@registerDefaultSkinLoader Skin::class.java.getResourceAsStream(
"/assets/img/steve.png"
)
Skin.Type.SUNNY -> return@registerDefaultSkinLoader Skin::class.java.getResourceAsStream(
"/assets/img/sunny.png"
)
Skin.Type.ZURI -> return@registerDefaultSkinLoader Skin::class.java.getResourceAsStream(
"/assets/img/zuri.png"
)
else -> return@registerDefaultSkinLoader null
}
}
RemoteMod.registerEmptyRemoteMod(
RemoteMod(
"",
"",
getString(R.string.mods_broken_dependency_title),
getString(R.string.mods_broken_dependency_desc),
ArrayList(),
"",
"",
object : IMod {
@Throws(IOException::class)
override fun loadDependencies(modRepository: RemoteModRepository): List<RemoteMod> {
throw IOException()
}
@Throws(IOException::class)
override fun loadVersions(modRepository: RemoteModRepository): Stream<RemoteMod.Version> {
throw IOException()
}
})
)
try {
ConfigHolder.init()
} catch (e: IOException) {
Logging.LOG.log(Level.WARNING, e.message)
}
bind.apply {
uiLayout.post {
ThemeEngine.getInstance().registerEvent(leftMenu) {
leftMenu.setBackgroundColor(
ThemeEngine.getInstance().getTheme().color
)
}
account.setOnClickListener(this@MainActivity)
version.setOnClickListener(this@MainActivity)
executeJar.setOnClickListener(this@MainActivity)
executeJar.setOnLongClickListener {
val padding = ConvertUtils.dip2px(this@MainActivity, 15f)
val editText = FCLEditText(this@MainActivity)
val layout = RelativeLayout(this@MainActivity)
editText.hint = "-jar xxx"
editText.setLines(1)
editText.maxLines = 1
layout.setPadding(padding, padding, padding, padding)
layout.addView(editText)
val dialog = AlertDialog.Builder(this@MainActivity)
.setTitle(R.string.jar_execute_custom_args)
.setView(layout)
.setPositiveButton(com.tungsten.fcllibrary.R.string.dialog_positive) { _: DialogInterface?, _: Int ->
JarExecutorHelper.exec(
this@MainActivity, null, 8, editText.text.toString()
)
}
.setNegativeButton(com.tungsten.fcllibrary.R.string.dialog_negative, null)
.create()
layout.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
editText.layoutParams = RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
ThemeEngine.getInstance().applyFullscreen(
dialog.window,
ThemeEngine.getInstance().getTheme().isFullscreen
)
dialog.show()
true
}
launch.setOnClickListener(this@MainActivity)
launch.setOnLongClickListener {
startActivity(Intent(this@MainActivity, ShellActivity::class.java))
true
}
uiManager = UIManager(this@MainActivity, uiLayout)
_uiManager = uiManager
uiManager.registerDefaultBackEvent() {
if (uiManager.currentUI === uiManager.mainUI) {
val i = Intent(Intent.ACTION_MAIN)
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
i.addCategory(Intent.CATEGORY_HOME)
startActivity(i)
} else {
home.isSelected = true
}
}
uiManager.init {
home.setOnSelectListener(this@MainActivity)
manage.setOnSelectListener(this@MainActivity)
download.setOnSelectListener(this@MainActivity)
controller.setOnSelectListener(this@MainActivity)
multiplayer.setOnSelectListener(this@MainActivity)
setting.setOnSelectListener(this@MainActivity)
back.setOnClickListener(this@MainActivity)
home.setSelected(true)
setupAccountDisplay()
setupVersionDisplay()
UpdateChecker.getInstance().checkAuto(this@MainActivity).start()
}
}
}
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
_uiManager?.onBackPressed()
return true
}
override fun onPause() {
super.onPause()
_uiManager?.onPause()
}
override fun onResume() {
super.onResume()
_uiManager?.onResume()
}
override fun onSelect(view: FCLMenuView) {
refreshMenuView(view)
bind.apply {
when (view) {
home -> {
title.setTextWithAnim(getString(R.string.app_name))
uiManager.switchUI(uiManager.mainUI)
}
manage -> {
val version = Profiles.getSelectedVersion()
if (version == null) {
refreshMenuView(null)
title.setTextWithAnim(getString(R.string.version))
uiManager.switchUI(uiManager.versionUI)
} else {
title.setTextWithAnim(getString(R.string.manage))
uiManager.manageUI.setVersion(version, Profiles.getSelectedProfile())
uiManager.switchUI(uiManager.manageUI)
}
}
download -> {
title.setTextWithAnim(getString(R.string.download))
uiManager.switchUI(uiManager.downloadUI)
}
controller -> {
title.setTextWithAnim(getString(R.string.controller))
uiManager.switchUI(uiManager.controllerUI)
}
multiplayer -> {
title.setTextWithAnim(getString(R.string.multiplayer))
uiManager.switchUI(uiManager.multiplayerUI)
}
setting -> {
title.setTextWithAnim(getString(R.string.setting))
uiManager.switchUI(uiManager.settingUI)
}
}
}
}
fun refreshMenuView(view: FCLMenuView?) {
bind.menu.forEach {
if (it is FCLMenuView && it != view) {
it.isSelected = false
}
}
}
override fun onClick(view: View) {
bind.apply {
if (view === account && uiManager.currentUI !== uiManager.accountUI) {
refreshMenuView(null)
title.setTextWithAnim(getString(R.string.account))
uiManager.switchUI(uiManager.accountUI)
}
if (view === version && uiManager.currentUI !== uiManager.versionUI) {
refreshMenuView(null)
title.setTextWithAnim(getString(R.string.version))
uiManager.switchUI(uiManager.versionUI)
}
if (view === back) {
uiManager.onBackPressed()
}
if (view === executeJar) {
JarExecutorHelper.start(this@MainActivity, this@MainActivity)
}
if (view === launch) {
Versions.launch(this@MainActivity, Profiles.getSelectedProfile())
}
}
}
private fun setupAccountDisplay() {
bind.apply {
currentAccount = object : SimpleObjectProperty<Account?>() {
override fun invalidated() {
val account = get()
if (account == null) {
accountName.stringProperty().unbind()
accountHint.stringProperty().unbind()
avatar.imageProperty().unbind()
accountName.text = getString(R.string.account_state_no_account)
accountHint.text = getString(R.string.account_state_add)
avatar.setBackgroundDrawable(
BitmapDrawable(
TexturesLoader.toAvatar(
TexturesLoader.getDefaultSkin(TextureModel.ALEX).image,
ConvertUtils.dip2px(
this@MainActivity, 30f
)
)
)
)
} else {
accountName.stringProperty()
.bind(BindingMapping.of(account) { obj: Account -> obj.character })
accountHint.stringProperty()
.bind(accountSubtitle(this@MainActivity, account))
avatar.imageProperty().unbind()
avatar.imageProperty().bind(
TexturesLoader.avatarBinding(
account, ConvertUtils.dip2px(
this@MainActivity, 30f
)
)
)
}
}
}
(currentAccount as SimpleObjectProperty<Account?>).bind(Accounts.selectedAccountProperty())
}
}
fun refreshAvatar(account: Account) {
Schedulers.androidUIThread().execute {
if (currentAccount.get() === account) {
bind.avatar.imageProperty().unbind()
bind.avatar.imageProperty().bind(
TexturesLoader.avatarBinding(
currentAccount.get(), ConvertUtils.dip2px(
this@MainActivity, 30f
)
)
)
}
}
}
@SuppressLint("UseCompatLoadingForDrawables")
private fun loadVersion(version: String?) {
if (Profiles.getSelectedProfile() != profile) {
profile = Profiles.getSelectedProfile()
if (profile != null) {
onVersionIconChangedListener =
profile!!.repository.onVersionIconChanged.registerWeak {
this.loadVersion(Profiles.getSelectedVersion())
}
}
}
if (version != null && Profiles.getSelectedProfile() != null && Profiles.getSelectedProfile().repository.hasVersion(
version
)
) {
val game = Profiles.getSelectedProfile().repository.getGameVersion(version)
.orElse(getString(R.string.message_unknown))
val libraries = StringBuilder(game)
val analyzer = LibraryAnalyzer.analyze(
Profiles.getSelectedProfile().repository.getResolvedPreservingPatchesVersion(version)
)
for (mark in analyzer) {
val libraryId = mark.libraryId
val libraryVersion = mark.libraryVersion
if (libraryId == LibraryType.MINECRAFT.patchId) continue
if (AndroidUtils.hasStringId(
this,
"install_installer_" + libraryId.replace("-", "_")
)
) {
libraries.append(", ").append(
AndroidUtils.getLocalizedText(
this,
"install_installer_" + libraryId.replace("-", "_")
)
)
if (libraryVersion != null) libraries.append(": ").append(
libraryVersion.replace(
"(?i)$libraryId".toRegex(), ""
)
)
}
}
bind.versionName.text = version
bind.versionHint.text = libraries.toString()
bind.icon.setBackgroundDrawable(
Profiles.getSelectedProfile().repository.getVersionIconImage(
version
)
)
} else {
bind.versionName.text = getString(R.string.version_no_version)
bind.versionHint.text = getString(R.string.version_manage)
bind.icon.setBackgroundDrawable(getDrawable(R.drawable.img_grass))
}
}
private fun setupVersionDisplay() {
holder.add(FXUtils.onWeakChangeAndOperate(Profiles.selectedVersionProperty()) { s: String? ->
Schedulers.androidUIThread().execute { loadVersion(s) }
})
}
private fun accountSubtitle(context: Context, account: Account): ObservableValue<String> {
return if (account is AuthlibInjectorAccount) {
BindingMapping.of(account.server) { obj: AuthlibInjectorServer -> obj.name }
} else {
Bindings.createStringBinding({
Accounts.getLocalizedLoginTypeName(
context,
Accounts.getAccountFactory(account)
)
})
}
}
}

View File

@ -1,331 +0,0 @@
package com.tungsten.fcl.fragment;
import android.annotation.SuppressLint;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.tungsten.fcl.R;
import com.tungsten.fcl.activity.SplashActivity;
import com.tungsten.fcl.util.RuntimeUtils;
import com.tungsten.fclauncher.utils.FCLPath;
import com.tungsten.fclcore.util.io.FileUtils;
import com.tungsten.fcllibrary.component.FCLFragment;
import com.tungsten.fcllibrary.component.view.FCLProgressBar;
import com.tungsten.fcllibrary.util.LocaleUtils;
import com.tungsten.fcllibrary.component.view.FCLButton;
import com.tungsten.fcllibrary.component.view.FCLImageView;
import java.io.File;
import java.io.IOException;
import java.util.Locale;
public class RuntimeFragment extends FCLFragment implements View.OnClickListener {
boolean lwjgl = false;
boolean cacio = false;
boolean cacio11 = false;
boolean cacio17 = false;
boolean java8 = false;
boolean java11 = false;
boolean java17 = false;
boolean java21 = false;
private FCLProgressBar lwjglProgress;
private FCLProgressBar cacioProgress;
private FCLProgressBar cacio11Progress;
private FCLProgressBar cacio17Progress;
private FCLProgressBar java8Progress;
private FCLProgressBar java11Progress;
private FCLProgressBar java17Progress;
private FCLProgressBar java21Progress;
private FCLImageView lwjglState;
private FCLImageView cacioState;
private FCLImageView cacio11State;
private FCLImageView cacio17State;
private FCLImageView java8State;
private FCLImageView java11State;
private FCLImageView java17State;
private FCLImageView java21State;
private FCLButton install;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_runtime, container, false);
lwjglProgress = findViewById(view, R.id.lwjgl_progress);
cacioProgress = findViewById(view, R.id.cacio_progress);
cacio11Progress = findViewById(view, R.id.cacio11_progress);
cacio17Progress = findViewById(view, R.id.cacio17_progress);
java8Progress = findViewById(view, R.id.java8_progress);
java11Progress = findViewById(view, R.id.java11_progress);
java17Progress = findViewById(view, R.id.java17_progress);
java21Progress = findViewById(view, R.id.java21_progress);
lwjglState = findViewById(view, R.id.lwjgl_state);
cacioState = findViewById(view, R.id.cacio_state);
cacio11State = findViewById(view, R.id.cacio11_state);
cacio17State = findViewById(view, R.id.cacio17_state);
java8State = findViewById(view, R.id.java8_state);
java11State = findViewById(view, R.id.java11_state);
java17State = findViewById(view, R.id.java17_state);
java21State = findViewById(view, R.id.java21_state);
initState();
refreshDrawables();
check();
install = findViewById(view, R.id.install);
install.setOnClickListener(this);
return view;
}
private void initState() {
try {
lwjgl = RuntimeUtils.isLatest(FCLPath.LWJGL_DIR, "/assets/app_runtime/lwjgl");
cacio = RuntimeUtils.isLatest(FCLPath.CACIOCAVALLO_8_DIR, "/assets/app_runtime/caciocavallo");
cacio11 = RuntimeUtils.isLatest(FCLPath.CACIOCAVALLO_11_DIR, "/assets/app_runtime/caciocavallo11");
cacio17 = RuntimeUtils.isLatest(FCLPath.CACIOCAVALLO_17_DIR, "/assets/app_runtime/caciocavallo17");
java8 = RuntimeUtils.isLatest(FCLPath.JAVA_8_PATH, "/assets/app_runtime/java/jre8");
java11 = RuntimeUtils.isLatest(FCLPath.JAVA_11_PATH, "/assets/app_runtime/java/jre11");
java17 = RuntimeUtils.isLatest(FCLPath.JAVA_17_PATH, "/assets/app_runtime/java/jre17");
java21 = RuntimeUtils.isLatest(FCLPath.JAVA_21_PATH, "/assets/app_runtime/java/jre21");
} catch (IOException e) {
e.printStackTrace();
}
}
private void refreshDrawables() {
if (getContext() != null) {
@SuppressLint("UseCompatLoadingForDrawables") Drawable stateUpdate = getContext().getDrawable(R.drawable.ic_baseline_update_24);
@SuppressLint("UseCompatLoadingForDrawables") Drawable stateDone = getContext().getDrawable(R.drawable.ic_baseline_done_24);
stateUpdate.setTint(Color.GRAY);
stateDone.setTint(Color.GRAY);
lwjglState.setBackgroundDrawable(lwjgl ? stateDone : stateUpdate);
cacioState.setBackgroundDrawable(cacio ? stateDone : stateUpdate);
cacio11State.setBackgroundDrawable(cacio11 ? stateDone : stateUpdate);
cacio17State.setBackgroundDrawable(cacio17 ? stateDone : stateUpdate);
java8State.setBackgroundDrawable(java8 ? stateDone : stateUpdate);
java11State.setBackgroundDrawable(java11 ? stateDone : stateUpdate);
java17State.setBackgroundDrawable(java17 ? stateDone : stateUpdate);
java21State.setBackgroundDrawable(java21 ? stateDone : stateUpdate);
}
}
private boolean isLatest() {
return lwjgl && cacio && cacio11 && cacio17 && java8 && java11 && java17 && java21;
}
private void check() {
if (isLatest()) {
if (getActivity() != null) {
((SplashActivity) getActivity()).enterLauncher();
}
}
}
private boolean installing = false;
private void install() {
if (installing)
return;
installing = true;
if (!lwjgl) {
lwjglState.setVisibility(View.GONE);
lwjglProgress.setVisibility(View.VISIBLE);
new Thread(() -> {
try {
RuntimeUtils.install(getContext(), FCLPath.LWJGL_DIR, "app_runtime/lwjgl");
lwjgl = true;
} catch (IOException e) {
e.printStackTrace();
}
if (getActivity() != null) {
getActivity().runOnUiThread(() -> {
lwjglState.setVisibility(View.VISIBLE);
lwjglProgress.setVisibility(View.GONE);
refreshDrawables();
check();
});
}
}).start();
}
if (!cacio) {
cacioState.setVisibility(View.GONE);
cacioProgress.setVisibility(View.VISIBLE);
new Thread(() -> {
try {
RuntimeUtils.install(getContext(), FCLPath.CACIOCAVALLO_8_DIR, "app_runtime/caciocavallo");
cacio = true;
} catch (IOException e) {
e.printStackTrace();
}
if (getActivity() != null) {
getActivity().runOnUiThread(() -> {
cacioState.setVisibility(View.VISIBLE);
cacioProgress.setVisibility(View.GONE);
refreshDrawables();
check();
});
}
}).start();
}
if (!cacio11) {
cacio11State.setVisibility(View.GONE);
cacio11Progress.setVisibility(View.VISIBLE);
new Thread(() -> {
try {
RuntimeUtils.install(getContext(), FCLPath.CACIOCAVALLO_11_DIR, "app_runtime/caciocavallo11");
cacio11 = true;
} catch (IOException e) {
e.printStackTrace();
}
if (getActivity() != null) {
getActivity().runOnUiThread(() -> {
cacio11State.setVisibility(View.VISIBLE);
cacio11Progress.setVisibility(View.GONE);
refreshDrawables();
check();
});
}
}).start();
}
if (!cacio17) {
cacio17State.setVisibility(View.GONE);
cacio17Progress.setVisibility(View.VISIBLE);
new Thread(() -> {
try {
RuntimeUtils.install(getContext(), FCLPath.CACIOCAVALLO_17_DIR, "app_runtime/caciocavallo17");
cacio17 = true;
} catch (IOException e) {
e.printStackTrace();
}
if (getActivity() != null) {
getActivity().runOnUiThread(() -> {
cacio17State.setVisibility(View.VISIBLE);
cacio17Progress.setVisibility(View.GONE);
refreshDrawables();
check();
});
}
}).start();
}
if (!java8) {
java8State.setVisibility(View.GONE);
java8Progress.setVisibility(View.VISIBLE);
new Thread(() -> {
try {
RuntimeUtils.installJava(getContext(), FCLPath.JAVA_8_PATH, "app_runtime/java/jre8");
java8 = true;
} catch (IOException e) {
e.printStackTrace();
}
if (getActivity() != null) {
getActivity().runOnUiThread(() -> {
java8State.setVisibility(View.VISIBLE);
java8Progress.setVisibility(View.GONE);
refreshDrawables();
check();
});
}
}).start();
}
if (!java11) {
java11State.setVisibility(View.GONE);
java11Progress.setVisibility(View.VISIBLE);
new Thread(() -> {
try {
RuntimeUtils.installJava(getContext(), FCLPath.JAVA_11_PATH, "app_runtime/java/jre11");
if (!LocaleUtils.getSystemLocale().getDisplayName().equals(Locale.CHINA.getDisplayName())) {
FileUtils.writeText(new File(FCLPath.JAVA_11_PATH + "/resolv.conf"), "nameserver 1.1.1.1\n" + "nameserver 1.0.0.1");
} else {
FileUtils.writeText(new File(FCLPath.JAVA_11_PATH + "/resolv.conf"), "nameserver 8.8.8.8\n" + "nameserver 8.8.4.4");
}
java11 = true;
} catch (IOException e) {
e.printStackTrace();
}
if (getActivity() != null) {
getActivity().runOnUiThread(() -> {
java11State.setVisibility(View.VISIBLE);
java11Progress.setVisibility(View.GONE);
refreshDrawables();
check();
});
}
}).start();
}
if (!java17) {
java17State.setVisibility(View.GONE);
java17Progress.setVisibility(View.VISIBLE);
new Thread(() -> {
try {
RuntimeUtils.installJava(getContext(), FCLPath.JAVA_17_PATH, "app_runtime/java/jre17");
if (!LocaleUtils.getSystemLocale().getDisplayName().equals(Locale.CHINA.getDisplayName())) {
FileUtils.writeText(new File(FCLPath.JAVA_17_PATH + "/resolv.conf"), "nameserver 1.1.1.1\n" + "nameserver 1.0.0.1");
} else {
FileUtils.writeText(new File(FCLPath.JAVA_17_PATH + "/resolv.conf"), "nameserver 8.8.8.8\n" + "nameserver 8.8.4.4");
}
java17 = true;
} catch (IOException e) {
e.printStackTrace();
}
if (getActivity() != null) {
getActivity().runOnUiThread(() -> {
java17State.setVisibility(View.VISIBLE);
java17Progress.setVisibility(View.GONE);
refreshDrawables();
check();
});
}
}).start();
}
if (!java21) {
java21State.setVisibility(View.GONE);
java21Progress.setVisibility(View.VISIBLE);
new Thread(() -> {
try {
RuntimeUtils.installJava(getContext(), FCLPath.JAVA_21_PATH, "app_runtime/java/jre21");
if (!LocaleUtils.getSystemLocale().getDisplayName().equals(Locale.CHINA.getDisplayName())) {
FileUtils.writeText(new File(FCLPath.JAVA_21_PATH + "/resolv.conf"), "nameserver 1.1.1.1\n" + "nameserver 1.0.0.1");
} else {
FileUtils.writeText(new File(FCLPath.JAVA_21_PATH + "/resolv.conf"), "nameserver 8.8.8.8\n" + "nameserver 8.8.4.4");
}
java21 = true;
} catch (IOException e) {
e.printStackTrace();
}
if (getActivity() != null) {
getActivity().runOnUiThread(() -> {
java21State.setVisibility(View.VISIBLE);
java21Progress.setVisibility(View.GONE);
refreshDrawables();
check();
});
}
}).start();
}
}
@Override
public void onClick(View view) {
if (view == install) {
install();
}
}
}

View File

@ -0,0 +1,363 @@
package com.tungsten.fcl.fragment
import android.annotation.SuppressLint
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.content.res.AppCompatResources
import com.tungsten.fcl.R
import com.tungsten.fcl.activity.SplashActivity
import com.tungsten.fcl.databinding.FragmentRuntimeBinding
import com.tungsten.fcl.util.RuntimeUtils
import com.tungsten.fclauncher.utils.FCLPath
import com.tungsten.fclcore.util.io.FileUtils
import com.tungsten.fcllibrary.component.FCLFragment
import com.tungsten.fcllibrary.component.view.FCLButton
import com.tungsten.fcllibrary.component.view.FCLImageView
import com.tungsten.fcllibrary.component.view.FCLProgressBar
import com.tungsten.fcllibrary.util.LocaleUtils
import java.io.File
import java.io.IOException
import java.util.Locale
class RuntimeFragment : FCLFragment(), View.OnClickListener {
private lateinit var bind: FragmentRuntimeBinding
var lwjgl: Boolean = false
var cacio: Boolean = false
var cacio11: Boolean = false
var cacio17: Boolean = false
var java8: Boolean = false
var java11: Boolean = false
var java17: Boolean = false
var java21: Boolean = false
var jna: Boolean = false
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_runtime, container, false)
bind = FragmentRuntimeBinding.bind(view)
initState()
refreshDrawables()
check()
bind.install.setOnClickListener(this)
return view
}
private fun initState() {
try {
lwjgl = RuntimeUtils.isLatest(FCLPath.LWJGL_DIR, "/assets/app_runtime/lwjgl")
cacio = RuntimeUtils.isLatest(
FCLPath.CACIOCAVALLO_8_DIR,
"/assets/app_runtime/caciocavallo"
)
cacio11 = RuntimeUtils.isLatest(
FCLPath.CACIOCAVALLO_11_DIR,
"/assets/app_runtime/caciocavallo11"
)
cacio17 = RuntimeUtils.isLatest(
FCLPath.CACIOCAVALLO_17_DIR,
"/assets/app_runtime/caciocavallo17"
)
java8 = RuntimeUtils.isLatest(FCLPath.JAVA_8_PATH, "/assets/app_runtime/java/jre8")
java11 = RuntimeUtils.isLatest(FCLPath.JAVA_11_PATH, "/assets/app_runtime/java/jre11")
java17 = RuntimeUtils.isLatest(FCLPath.JAVA_17_PATH, "/assets/app_runtime/java/jre17")
java21 = RuntimeUtils.isLatest(FCLPath.JAVA_21_PATH, "/assets/app_runtime/java/jre21")
jna = RuntimeUtils.isLatest(FCLPath.JNA_PATH, "/assets/app_runtime/jna")
} catch (e: IOException) {
e.printStackTrace()
}
}
private fun refreshDrawables() {
if (context != null) {
val stateUpdate =
AppCompatResources.getDrawable(requireContext(), R.drawable.ic_baseline_update_24)
val stateDone =
AppCompatResources.getDrawable(requireContext(), R.drawable.ic_baseline_done_24)
stateUpdate?.setTint(Color.GRAY)
stateDone?.setTint(Color.GRAY)
bind.apply {
lwjglState.setBackgroundDrawable(if (lwjgl) stateDone else stateUpdate)
cacioState.setBackgroundDrawable(if (cacio) stateDone else stateUpdate)
cacio11State.setBackgroundDrawable(if (cacio11) stateDone else stateUpdate)
cacio17State.setBackgroundDrawable(if (cacio17) stateDone else stateUpdate)
java8State.setBackgroundDrawable(if (java8) stateDone else stateUpdate)
java11State.setBackgroundDrawable(if (java11) stateDone else stateUpdate)
java17State.setBackgroundDrawable(if (java17) stateDone else stateUpdate)
java21State.setBackgroundDrawable(if (java21) stateDone else stateUpdate)
jnaState.setBackgroundDrawable(if (jna) stateDone else stateUpdate)
}
}
}
private val isLatest: Boolean
get() = lwjgl && cacio && cacio11 && cacio17 && java8 && java11 && java17 && java21 && jna
private fun check() {
if (isLatest) {
(activity as SplashActivity).enterLauncher()
}
}
private var installing = false
private fun install() {
if (installing) return
bind.apply {
installing = true
if (!lwjgl) {
lwjglState.visibility = View.GONE
lwjglProgress.visibility = View.VISIBLE
Thread {
try {
RuntimeUtils.install(context, FCLPath.LWJGL_DIR, "app_runtime/lwjgl")
lwjgl = true
} catch (e: IOException) {
e.printStackTrace()
}
activity?.runOnUiThread {
lwjglState.visibility = View.VISIBLE
lwjglProgress.visibility = View.GONE
refreshDrawables()
check()
}
}.start()
}
if (!cacio) {
cacioState.visibility = View.GONE
cacioProgress.visibility = View.VISIBLE
Thread {
try {
RuntimeUtils.install(
context,
FCLPath.CACIOCAVALLO_8_DIR,
"app_runtime/caciocavallo"
)
cacio = true
} catch (e: IOException) {
e.printStackTrace()
}
activity?.runOnUiThread {
cacioState.visibility = View.VISIBLE
cacioProgress.visibility = View.GONE
refreshDrawables()
check()
}
}.start()
}
if (!cacio11) {
cacio11State.visibility = View.GONE
cacio11Progress.visibility = View.VISIBLE
Thread {
try {
RuntimeUtils.install(
context,
FCLPath.CACIOCAVALLO_11_DIR,
"app_runtime/caciocavallo11"
)
cacio11 = true
} catch (e: IOException) {
e.printStackTrace()
}
activity?.runOnUiThread {
cacio11State.visibility = View.VISIBLE
cacio11Progress.visibility = View.GONE
refreshDrawables()
check()
}
}.start()
}
if (!cacio17) {
cacio17State.visibility = View.GONE
cacio17Progress.visibility = View.VISIBLE
Thread {
try {
RuntimeUtils.install(
context,
FCLPath.CACIOCAVALLO_17_DIR,
"app_runtime/caciocavallo17"
)
cacio17 = true
} catch (e: IOException) {
e.printStackTrace()
}
activity?.runOnUiThread {
cacio17State.visibility = View.VISIBLE
cacio17Progress.visibility = View.GONE
refreshDrawables()
check()
}
}.start()
}
if (!java8) {
java8State.visibility = View.GONE
java8Progress.visibility = View.VISIBLE
Thread {
try {
RuntimeUtils.installJava(
context,
FCLPath.JAVA_8_PATH,
"app_runtime/java/jre8"
)
java8 = true
} catch (e: IOException) {
e.printStackTrace()
}
activity?.runOnUiThread {
java8State.visibility = View.VISIBLE
java8Progress.visibility = View.GONE
refreshDrawables()
check()
}
}.start()
}
if (!java11) {
java11State.visibility = View.GONE
java11Progress.visibility = View.VISIBLE
Thread {
try {
RuntimeUtils.installJava(
context,
FCLPath.JAVA_11_PATH,
"app_runtime/java/jre11"
)
if (LocaleUtils.getSystemLocale().displayName != Locale.CHINA.displayName) {
FileUtils.writeText(
File(FCLPath.JAVA_11_PATH + "/resolv.conf"), """
nameserver 1.1.1.1
nameserver 1.0.0.1
""".trimIndent()
)
} else {
FileUtils.writeText(
File(FCLPath.JAVA_11_PATH + "/resolv.conf"), """
nameserver 8.8.8.8
nameserver 8.8.4.4
""".trimIndent()
)
}
java11 = true
} catch (e: IOException) {
e.printStackTrace()
}
activity?.runOnUiThread {
java11State.visibility = View.VISIBLE
java11Progress.visibility = View.GONE
refreshDrawables()
check()
}
}.start()
}
if (!java17) {
java17State.visibility = View.GONE
java17Progress.visibility = View.VISIBLE
Thread {
try {
RuntimeUtils.installJava(
context,
FCLPath.JAVA_17_PATH,
"app_runtime/java/jre17"
)
if (LocaleUtils.getSystemLocale().displayName != Locale.CHINA.displayName) {
FileUtils.writeText(
File(FCLPath.JAVA_17_PATH + "/resolv.conf"), """
nameserver 1.1.1.1
nameserver 1.0.0.1
""".trimIndent()
)
} else {
FileUtils.writeText(
File(FCLPath.JAVA_17_PATH + "/resolv.conf"), """
nameserver 8.8.8.8
nameserver 8.8.4.4
""".trimIndent()
)
}
java17 = true
} catch (e: IOException) {
e.printStackTrace()
}
activity?.runOnUiThread {
java17State.visibility = View.VISIBLE
java17Progress.visibility = View.GONE
refreshDrawables()
check()
}
}.start()
}
if (!java21) {
java21State.visibility = View.GONE
java21Progress.visibility = View.VISIBLE
Thread {
try {
RuntimeUtils.installJava(
context,
FCLPath.JAVA_21_PATH,
"app_runtime/java/jre21"
)
if (LocaleUtils.getSystemLocale().displayName != Locale.CHINA.displayName) {
FileUtils.writeText(
File(FCLPath.JAVA_21_PATH + "/resolv.conf"), """
nameserver 1.1.1.1
nameserver 1.0.0.1
""".trimIndent()
)
} else {
FileUtils.writeText(
File(FCLPath.JAVA_21_PATH + "/resolv.conf"), """
nameserver 8.8.8.8
nameserver 8.8.4.4
""".trimIndent()
)
}
java21 = true
} catch (e: IOException) {
e.printStackTrace()
}
activity?.runOnUiThread {
java21State.visibility = View.VISIBLE
java21Progress.visibility = View.GONE
refreshDrawables()
check()
}
}.start()
}
if (!jna) {
jnaState.visibility = View.GONE
jnaProgress.visibility = View.VISIBLE
Thread {
try {
RuntimeUtils.installJna(
context,
FCLPath.JNA_PATH,
"app_runtime/jna"
)
jna = true
} catch (e: IOException) {
e.printStackTrace()
}
activity?.runOnUiThread {
jnaState.visibility = View.VISIBLE
jnaProgress.visibility = View.GONE
refreshDrawables()
check()
}
}.start()
}
}
}
override fun onClick(view: View) {
if (view === bind.install) {
install()
}
}
}

View File

@ -161,13 +161,19 @@ public final class LauncherHelper {
.thenComposeAsync(() -> logIn(context, account).withStage("launch.state.logging_in"))
.thenComposeAsync(authInfo -> Task.supplyAsync(() -> {
LaunchOptions launchOptions = repository.getLaunchOptions(selectedVersion, javaVersionRef.get(), profile.getGameDir(), javaAgents);
return new FCLGameLauncher(
FCLGameLauncher launcher = new FCLGameLauncher(
context,
repository,
version.get(),
authInfo,
launchOptions
);
version.get().getLibraries().forEach(library -> {
if (library.getName().startsWith("net.java.dev.jna:jna:")) {
launcher.setJnaVersion(library.getVersion());
}
});
return launcher;
}).thenComposeAsync(launcher -> { // launcher is prev task's result
return Task.supplyAsync(launcher::launch);
}).thenAcceptAsync(fclBridge -> Schedulers.androidUIThread().execute(() -> {

View File

@ -7,6 +7,7 @@ import android.graphics.BitmapFactory;
import android.view.View;
import android.widget.ListView;
import com.bumptech.glide.Glide;
import com.tungsten.fcl.R;
import com.tungsten.fcl.setting.Profile;
import com.tungsten.fcl.ui.PageManager;
@ -100,19 +101,7 @@ public class RemoteModInfoPage extends FCLTempPage implements View.OnClickListen
super.onStart();
icon.setImageDrawable(null);
new Thread(() -> {
try {
URL url = new URL(addon.getIconUrl());
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setDoInput(true);
httpURLConnection.connect();
InputStream inputStream = httpURLConnection.getInputStream();
Bitmap icon = BitmapFactory.decodeStream(inputStream);
Schedulers.androidUIThread().execute(() -> RemoteModInfoPage.this.icon.setImageBitmap(icon));
} catch (IOException e) {
e.printStackTrace();
}
}).start();
Glide.with(getContext()).load(addon.getIconUrl()).into(icon);
ModTranslations.Mod mod = translations.getModByCurseForgeId(addon.getSlug());
name.setText(mod != null && LocaleUtils.isChinese(getContext()) ? mod.getDisplayName() : addon.getTitle());
description.setText(addon.getDescription());

View File

@ -7,12 +7,15 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.bumptech.glide.Glide;
import com.mio.util.AnimUtil;
import com.tungsten.fcl.R;
import com.tungsten.fcl.util.ModTranslations;
import com.tungsten.fclcore.mod.RemoteMod;
import com.tungsten.fclcore.task.Schedulers;
import com.tungsten.fclcore.util.StringUtils;
import com.tungsten.fcllibrary.component.FCLAdapter;
import com.tungsten.fcllibrary.component.theme.ThemeEngine;
import com.tungsten.fcllibrary.util.LocaleUtils;
import com.tungsten.fcllibrary.component.view.FCLImageView;
import com.tungsten.fcllibrary.component.view.FCLLinearLayout;
@ -76,21 +79,7 @@ public class RemoteModListAdapter extends FCLAdapter {
viewHolder.parent.setOnClickListener(v -> callback.onItemSelect(remoteMod));
viewHolder.icon.setImageDrawable(null);
viewHolder.icon.setTag(i);
new Thread(() -> {
try {
URL url = new URL(remoteMod.getIconUrl());
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setDoInput(true);
httpURLConnection.connect();
InputStream inputStream = httpURLConnection.getInputStream();
Bitmap icon = BitmapFactory.decodeStream(inputStream);
if (viewHolder.icon.getTag().equals(i)) {
Schedulers.androidUIThread().execute(() -> viewHolder.icon.setImageBitmap(icon));
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
Glide.with(getContext()).load(remoteMod.getIconUrl()).into(viewHolder.icon);
ModTranslations.Mod mod = ModTranslations.getTranslationsByRepositoryType(downloadPage.repository.getType()).getModByCurseForgeId(remoteMod.getSlug());
viewHolder.name.setText(mod != null && LocaleUtils.isChinese(getContext()) ? mod.getDisplayName() : remoteMod.getTitle());
List<String> categories = remoteMod.getCategories().stream().map(downloadPage::getLocalizedCategory).collect(Collectors.toList());
@ -99,6 +88,7 @@ public class RemoteModListAdapter extends FCLAdapter {
String tag = StringUtils.removeSuffix(stringBuilder.toString(), " ");
viewHolder.tag.setText(tag);
viewHolder.description.setText(remoteMod.getDescription());
AnimUtil.playTranslationX(view, ThemeEngine.getInstance().getTheme().getAnimationSpeed() * 30L, -100f, 0f).start();
return view;
}

View File

@ -10,6 +10,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.mio.util.AnimUtil;
import com.tungsten.fcl.R;
import com.tungsten.fclcore.download.RemoteVersion;
import com.tungsten.fclcore.download.fabric.FabricAPIRemoteVersion;
@ -84,6 +85,7 @@ public class RemoteVersionListAdapter extends FCLAdapter {
viewHolder.tag.setText(getTag(remoteVersion));
viewHolder.date.setVisibility(remoteVersion.getReleaseDate() == null ? View.GONE : View.VISIBLE);
viewHolder.date.setText(remoteVersion.getReleaseDate() == null ? "" : formatDateTime(getContext(), remoteVersion.getReleaseDate()));
AnimUtil.playTranslationX(view, ThemeEngine.getInstance().getTheme().getAnimationSpeed() * 30L, -100f, 0f).start();
return view;
}

View File

@ -62,7 +62,7 @@ public class ManageUI extends FCLMultiPageUI implements TabLayout.OnTabSelectedL
Schedulers.androidUIThread().execute(() -> {
if (isShowing()) {
MainActivity.getInstance().refreshMenuView(null);
MainActivity.getInstance().home.setSelected(true);
MainActivity.getInstance().bind.home.setSelected(true);
}
});
return;
@ -158,7 +158,7 @@ public class ManageUI extends FCLMultiPageUI implements TabLayout.OnTabSelectedL
loadVersion(preferredVersionName, this.version.get().getProfile());
} else if (isShowing()) {
MainActivity.getInstance().refreshMenuView(null);
MainActivity.getInstance().home.setSelected(true);
MainActivity.getInstance().bind.home.setSelected(true);
}
}
});
@ -176,7 +176,7 @@ public class ManageUI extends FCLMultiPageUI implements TabLayout.OnTabSelectedL
Schedulers.androidUIThread().execute(() -> {
if (isShowing()) {
MainActivity.getInstance().refreshMenuView(null);
MainActivity.getInstance().home.setSelected(true);
MainActivity.getInstance().bind.home.setSelected(true);
}
});
return;

View File

@ -406,7 +406,7 @@ public class ModListPage extends FCLCommonPage implements ManageUI.VersionLoadab
public void download() {
MainActivity.getInstance().refreshMenuView(null);
MainActivity.getInstance().download.setSelected(true);
MainActivity.getInstance().bind.download.setSelected(true);
DownloadPageManager.getInstance().switchPage(DownloadPageManager.PAGE_ID_DOWNLOAD_MOD);
}

View File

@ -289,7 +289,7 @@ public class LauncherSettingPage extends FCLCommonPage implements View.OnClickLi
if (AndroidUtils.isDocUri(uri)) {
path = AndroidUtils.copyFileToDir(getActivity(), uri, new File(FCLPath.CACHE_DIR));
}
ThemeEngine.getInstance().applyAndSave(getContext(), ((MainActivity) getActivity()).background, path, null);
ThemeEngine.getInstance().applyAndSave(getContext(), ((MainActivity) getActivity()).bind.background, path, null);
}
}));
}
@ -307,7 +307,7 @@ public class LauncherSettingPage extends FCLCommonPage implements View.OnClickLi
if (AndroidUtils.isDocUri(uri)) {
path = AndroidUtils.copyFileToDir(getActivity(), uri, new File(FCLPath.CACHE_DIR));
}
ThemeEngine.getInstance().applyAndSave(getContext(), ((MainActivity) getActivity()).background, null, path);
ThemeEngine.getInstance().applyAndSave(getContext(), ((MainActivity) getActivity()).bind.background, null, path);
}
}));
}
@ -319,7 +319,7 @@ public class LauncherSettingPage extends FCLCommonPage implements View.OnClickLi
if (!new File(FCLPath.LT_BACKGROUND_PATH).delete() && new File(FCLPath.LT_BACKGROUND_PATH).exists())
Schedulers.androidUIThread().execute(() -> Toast.makeText(getContext(), getContext().getString(R.string.message_failed), Toast.LENGTH_SHORT).show());
Schedulers.androidUIThread().execute(() -> ThemeEngine.getInstance().applyAndSave(getContext(), ((MainActivity) getActivity()).background, null, null));
Schedulers.androidUIThread().execute(() -> ThemeEngine.getInstance().applyAndSave(getContext(), ((MainActivity) getActivity()).bind.background, null, null));
}).start();
}
if (v == resetDkBackground) {
@ -327,7 +327,7 @@ public class LauncherSettingPage extends FCLCommonPage implements View.OnClickLi
if (!new File(FCLPath.DK_BACKGROUND_PATH).delete() && new File(FCLPath.DK_BACKGROUND_PATH).exists())
Schedulers.androidUIThread().execute(() -> Toast.makeText(getContext(), getContext().getString(R.string.message_failed), Toast.LENGTH_SHORT).show());
Schedulers.androidUIThread().execute(() -> ThemeEngine.getInstance().applyAndSave(getContext(), ((MainActivity) getActivity()).background, null, null));
Schedulers.androidUIThread().execute(() -> ThemeEngine.getInstance().applyAndSave(getContext(), ((MainActivity) getActivity()).bind.background, null, null));
}).start();
}
}

View File

@ -219,7 +219,7 @@ public class Versions {
builder.setMessage(context.getString(R.string.version_empty_launch));
builder.setNegativeButton(context.getString(com.tungsten.fcllibrary.R.string.dialog_positive), () -> {
MainActivity.getInstance().refreshMenuView(null);
MainActivity.getInstance().download.setSelected(true);
MainActivity.getInstance().bind.download.setSelected(true);
});
builder.create().show();
return false;

View File

@ -5,10 +5,12 @@ import android.system.Os;
import com.tungsten.fclauncher.FCLauncher;
import com.tungsten.fclauncher.utils.Architecture;
import com.tungsten.fclauncher.utils.FCLPath;
import com.tungsten.fclcore.util.Logging;
import com.tungsten.fclcore.util.Pack200Utils;
import com.tungsten.fclcore.util.io.FileUtils;
import com.tungsten.fclcore.util.io.IOUtils;
import com.tungsten.fclcore.util.io.Unzipper;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
@ -37,6 +39,15 @@ public class RuntimeUtils {
copyAssets(context, srcDir, targetDir);
}
public static void installJna(Context context, String targetDir, String srcDir) throws IOException {
FileUtils.deleteDirectory(new File(targetDir));
new File(targetDir).mkdirs();
copyAssets(context, srcDir, targetDir);
File file = new File(FCLPath.JNA_PATH, "jna-arm64.zip");
new Unzipper(file, new File(FCLPath.RUNTIME_DIR)).unzip();
file.delete();
}
@SuppressWarnings("ResultOfMethodCallIgnored")
public static void installJava(Context context, String targetDir, String srcDir) throws IOException {
FileUtils.deleteDirectory(new File(targetDir));

View File

@ -1,292 +1,304 @@
<?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:id="@+id/background"
tools:context=".activity.MainActivity">
<ScrollView
android:id="@+id/left_scroll"
android:layout_width="wrap_content"
<layout>
<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"
app:layout_constraintStart_toStartOf="parent">
android:id="@+id/background"
tools:context=".activity.MainActivity">
<androidx.appcompat.widget.LinearLayoutCompat
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:orientation="vertical"
<ScrollView
android:id="@+id/left_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.tungsten.fcllibrary.component.view.FCLMenuView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_home_24"
android:id="@+id/home"/>
<com.tungsten.fcllibrary.component.view.FCLMenuView
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_build_24"
android:id="@+id/manage"/>
<com.tungsten.fcllibrary.component.view.FCLMenuView
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_cloud_download_24"
android:id="@+id/download"/>
<com.tungsten.fcllibrary.component.view.FCLMenuView
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_videogame_asset_24"
android:id="@+id/controller"/>
<com.tungsten.fcllibrary.component.view.FCLMenuView
android:visibility="gone"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_wifi_24"
android:id="@+id/multiplayer"/>
<com.tungsten.fcllibrary.component.view.FCLMenuView
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_settings_24"
android:id="@+id/setting"/>
<com.tungsten.fcllibrary.component.view.FCLMenuView
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_arrow_back_24"
android:id="@+id/back"/>
</androidx.appcompat.widget.LinearLayoutCompat>
</ScrollView>
<View
android:background="@android:color/darker_gray"
android:id="@+id/split_left"
android:layout_width="1dp"
android:layout_height="match_parent"
app:layout_constraintStart_toEndOf="@id/left_scroll"/>
<View
android:background="@android:color/darker_gray"
android:id="@+id/split_right"
android:layout_width="1dp"
android:layout_height="match_parent"
app:layout_constraintEnd_toStartOf="@id/right_menu"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:background="@color/ui_bg_color"
android:id="@+id/right_menu"
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintWidth_percent="0.25">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:id="@+id/account_textview"
android:singleLine="true"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/account"
android:textSize="11sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<View
android:id="@+id/view"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"
app:layout_constraintTop_toBottomOf="@id/account_textview"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_marginTop="10dp"
android:background="@drawable/bg_container_transparent_clickable"
android:focusable="true"
android:clickable="true"
android:id="@+id/account"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
app:layout_constraintTop_toBottomOf="@+id/view">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:id="@+id/avatar"/>
<LinearLayout
android:layout_marginStart="10dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center"
android:orientation="vertical">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:singleLine="true"
android:id="@+id/account_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/account_state_no_account"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:singleLine="true"
android:id="@+id/account_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/account_state_add"
android:textSize="11sp"/>
</LinearLayout>
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_list_24"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:id="@+id/version_textview"
android:singleLine="true"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/version"
android:textSize="11sp"
app:layout_constraintTop_toBottomOf="@id/account"
app:layout_constraintStart_toStartOf="parent"/>
<View
android:id="@+id/view2"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"
app:layout_constraintTop_toBottomOf="@id/version_textview"
app:layout_constraintStart_toStartOf="parent"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_marginTop="10dp"
android:background="@drawable/bg_container_transparent_clickable"
android:focusable="true"
android:clickable="true"
android:id="@+id/version"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
app:layout_constraintTop_toBottomOf="@id/view2"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:id="@+id/icon"/>
<LinearLayout
android:layout_marginStart="10dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center"
android:orientation="vertical">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:singleLine="true"
android:id="@+id/version_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/version_no_version"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:singleLine="true"
android:id="@+id/version_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/version_manage"
android:textSize="11sp"/>
</LinearLayout>
<androidx.appcompat.widget.AppCompatImageView
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/menu"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_list_24"/>
android:clipChildren="false"
android:clipToPadding="false">
</androidx.appcompat.widget.LinearLayoutCompat>
<com.tungsten.fcllibrary.component.view.FCLMenuView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_home_24"
android:id="@+id/home"/>
<com.tungsten.fcllibrary.component.view.FCLButton
android:id="@+id/execute_jar"
android:layout_width="match_parent"
<com.tungsten.fcllibrary.component.view.FCLMenuView
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_build_24"
android:id="@+id/manage"/>
<com.tungsten.fcllibrary.component.view.FCLMenuView
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_cloud_download_24"
android:id="@+id/download"/>
<com.tungsten.fcllibrary.component.view.FCLMenuView
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_videogame_asset_24"
android:id="@+id/controller"/>
<com.tungsten.fcllibrary.component.view.FCLMenuView
android:visibility="gone"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_wifi_24"
android:id="@+id/multiplayer"/>
<com.tungsten.fcllibrary.component.view.FCLMenuView
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_settings_24"
android:id="@+id/setting"/>
<com.tungsten.fcllibrary.component.view.FCLMenuView
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_arrow_back_24"
android:id="@+id/back"/>
</androidx.appcompat.widget.LinearLayoutCompat>
</ScrollView>
<View
android:background="@android:color/darker_gray"
android:id="@+id/split_left"
android:layout_width="1dp"
android:layout_height="match_parent"
app:layout_constraintStart_toEndOf="@id/left_menu"/>
<View
android:background="@android:color/darker_gray"
android:id="@+id/split_right"
android:layout_width="1dp"
android:layout_height="match_parent"
app:layout_constraintEnd_toStartOf="@id/right_menu"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:background="@color/ui_bg_color"
android:id="@+id/right_menu"
android:layout_width="0dp"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintWidth_percent="0.25">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:id="@+id/account_textview"
android:singleLine="true"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/account"
android:textSize="11sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<View
android:id="@+id/view"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"
app:layout_constraintTop_toBottomOf="@id/account_textview"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_marginTop="10dp"
android:background="@drawable/bg_container_transparent_clickable"
android:focusable="true"
android:clickable="true"
android:id="@+id/account"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
app:layout_constraintTop_toBottomOf="@+id/view"
android:clipChildren="false"
android:clipToPadding="false"
android:stateListAnimator="@xml/anim_scale">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:id="@+id/avatar"
android:focusable="true"
android:clickable="true"
android:stateListAnimator="@xml/anim_scale_large"/>
<LinearLayout
android:layout_marginStart="10dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center"
android:orientation="vertical">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:singleLine="true"
android:id="@+id/account_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/account_state_no_account"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:singleLine="true"
android:id="@+id/account_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/account_state_add"
android:textSize="11sp"/>
</LinearLayout>
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_list_24"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:id="@+id/version_textview"
android:singleLine="true"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/version"
android:textSize="11sp"
app:layout_constraintTop_toBottomOf="@id/account"
app:layout_constraintStart_toStartOf="parent"/>
<View
android:id="@+id/view2"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"
app:layout_constraintTop_toBottomOf="@id/version_textview"
app:layout_constraintStart_toStartOf="parent"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_marginTop="10dp"
android:background="@drawable/bg_container_transparent_clickable"
android:focusable="true"
android:clickable="true"
android:id="@+id/version"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
app:layout_constraintTop_toBottomOf="@id/view2"
app:layout_constraintStart_toStartOf="parent"
android:stateListAnimator="@xml/anim_scale">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:id="@+id/icon"/>
<LinearLayout
android:layout_marginStart="10dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center"
android:orientation="vertical">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:singleLine="true"
android:id="@+id/version_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/version_no_version"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:singleLine="true"
android:id="@+id/version_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/version_manage"
android:textSize="11sp"/>
</LinearLayout>
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_list_24"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<com.tungsten.fcllibrary.component.view.FCLButton
android:id="@+id/execute_jar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/jar_execute"
android:layout_marginBottom="10dp"
android:layout_marginHorizontal="8dp"
app:ripple="true"
app:layout_constraintBottom_toTopOf="@id/launch"/>
<com.tungsten.fcllibrary.component.view.FCLButton
android:id="@+id/launch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/launch"
android:layout_marginHorizontal="8dp"
app:ripple="true"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.tungsten.fcllibrary.component.view.FCLUILayout
android:id="@+id/ui_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintStart_toEndOf="@+id/split_left"
app:layout_constraintEnd_toStartOf="@id/split_right"/>
<com.tungsten.fcllibrary.component.view.FCLDynamicIsland
android:stateListAnimator="@null"
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/jar_execute"
android:layout_marginBottom="10dp"
android:layout_marginHorizontal="8dp"
app:ripple="true"
app:layout_constraintBottom_toTopOf="@id/launch"/>
<com.tungsten.fcllibrary.component.view.FCLButton
android:id="@+id/launch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/launch"
android:layout_marginHorizontal="8dp"
app:ripple="true"
android:layout_marginBottom="15dp"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.tungsten.fcllibrary.component.view.FCLUILayout
android:id="@+id/ui_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintStart_toEndOf="@+id/split_left"
app:layout_constraintEnd_toStartOf="@id/split_right"/>
<com.tungsten.fcllibrary.component.view.FCLDynamicIsland
android:stateListAnimator="@null"
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@ -1,381 +1,425 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<layout>
<ScrollView
android:id="@+id/runtime_parent"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintWidth_percent="0.7"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
<ScrollView
android:id="@+id/runtime_parent"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintWidth_percent="0.7"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/splash_runtime_lwjgl"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:visibility="gone"
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/lwjgl_progress"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
app:auto_src_tint="false"
android:tint="@android:color/darker_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/lwjgl_state"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/splash_runtime_cacio"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:visibility="gone"
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/cacio_progress"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
app:auto_src_tint="false"
android:tint="@android:color/darker_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/cacio_state"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/splash_runtime_cacio11"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:visibility="gone"
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/cacio11_progress"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
app:auto_src_tint="false"
android:tint="@android:color/darker_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/cacio11_state"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/splash_runtime_cacio17"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:visibility="gone"
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/cacio17_progress"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
app:auto_src_tint="false"
android:tint="@android:color/darker_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/cacio17_state"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/splash_runtime_java8"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:visibility="gone"
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/java8_progress"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
app:auto_src_tint="false"
android:tint="@android:color/darker_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/java8_state"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/splash_runtime_java11"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:visibility="gone"
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/java11_progress"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
app:auto_src_tint="false"
android:tint="@android:color/darker_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/java11_state"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/splash_runtime_java17"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:visibility="gone"
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/java17_progress"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
app:auto_src_tint="false"
android:backgroundTint="@android:color/darker_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/java17_state"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/splash_runtime_java21"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:visibility="gone"
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/java21_progress"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
app:auto_src_tint="false"
android:backgroundTint="@android:color/darker_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/java21_state"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/splash_runtime_jna"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:visibility="gone"
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/jna_progress"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
app:auto_src_tint="false"
android:backgroundTint="@android:color/darker_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/jna_state"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</ScrollView>
<View
android:id="@+id/split"
android:background="@android:color/darker_gray"
android:layout_width="1dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/runtime_parent"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginTop="10dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical">
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:text="@string/splash_runtime_title"
app:layout_constraintStart_toEndOf="@id/split"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLButton
android:text="@string/splash_runtime_install"
android:id="@+id/install"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
app:layout_constraintStart_toEndOf="@id/split"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/splash_runtime_lwjgl"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:visibility="gone"
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/lwjgl_progress"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
app:auto_src_tint="false"
android:tint="@android:color/darker_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/lwjgl_state"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/splash_runtime_cacio"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:visibility="gone"
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/cacio_progress"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
app:auto_src_tint="false"
android:tint="@android:color/darker_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/cacio_state"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/splash_runtime_cacio11"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:visibility="gone"
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/cacio11_progress"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
app:auto_src_tint="false"
android:tint="@android:color/darker_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/cacio11_state"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/splash_runtime_cacio17"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:visibility="gone"
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/cacio17_progress"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
app:auto_src_tint="false"
android:tint="@android:color/darker_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/cacio17_state"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/splash_runtime_java8"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:visibility="gone"
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/java8_progress"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
app:auto_src_tint="false"
android:tint="@android:color/darker_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/java8_state"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/splash_runtime_java11"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:visibility="gone"
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/java11_progress"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
app:auto_src_tint="false"
android:tint="@android:color/darker_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/java11_state"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/splash_runtime_java17"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:visibility="gone"
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/java17_progress"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
app:auto_src_tint="false"
android:backgroundTint="@android:color/darker_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/java17_state"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/splash_runtime_java21"
android:layout_gravity="center"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:visibility="gone"
android:layout_width="24dp"
android:layout_height="24dp"
android:id="@+id/java21_progress"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
app:auto_src_tint="false"
android:backgroundTint="@android:color/darker_gray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/java21_state"
android:layout_gravity="center"
android:layout_marginStart="10dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</ScrollView>
<View
android:id="@+id/split"
android:background="@android:color/darker_gray"
android:layout_width="1dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/runtime_parent"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginTop="10dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:text="@string/splash_runtime_title"
app:layout_constraintStart_toEndOf="@id/split"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<com.tungsten.fcllibrary.component.view.FCLButton
android:text="@string/splash_runtime_install"
android:id="@+id/install"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
app:layout_constraintStart_toEndOf="@id/split"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@ -15,7 +15,8 @@
android:background="@drawable/bg_container_white_clickable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
android:orientation="horizontal"
android:stateListAnimator="@xml/anim_scale">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="30dp"

View File

@ -1,232 +1,231 @@
<?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:background="@color/ui_bg_color"
android:paddingTop="10dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="@color/ui_bg_color"
android:paddingStart="10dp"
android:paddingTop="10dp"
android:paddingEnd="10dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/left"
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintWidth_percent="0.3">
<ScrollView
android:id="@+id/search_layout"
android:background="@drawable/bg_container_white"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
android:layout_weight="1"
android:background="@drawable/bg_container_white">
<androidx.appcompat.widget.LinearLayoutCompat
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:orientation="vertical"
android:padding="10dp">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="@string/mods_name"
app:auto_text_tint="true"/>
app:auto_text_tint="true" />
<com.tungsten.fcllibrary.component.view.FCLEditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:singleLine="true"
android:textSize="13sp"
android:id="@+id/name"
app:auto_edit_tint="true"/>
app:auto_edit_tint="true" />
<com.tungsten.fcllibrary.component.view.FCLTextView
android:id="@+id/download_source_text"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:singleLine="true"
android:text="@string/settings_launcher_download_source"
app:auto_text_tint="true"/>
app:auto_text_tint="true" />
<com.tungsten.fcllibrary.component.view.FCLSpinner
android:id="@+id/download_source"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:id="@+id/download_source"/>
android:layout_marginTop="10dp" />
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:singleLine="true"
android:text="@string/world_game_version"
app:auto_text_tint="true"/>
app:auto_text_tint="true" />
<com.tungsten.fcllibrary.component.view.FCLSpinner
android:id="@+id/game_version"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:id="@+id/game_version"/>
android:layout_marginTop="10dp" />
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:singleLine="true"
android:text="@string/mods_category"
app:auto_text_tint="true"/>
app:auto_text_tint="true" />
<com.tungsten.fcllibrary.component.view.FCLSpinner
android:id="@+id/category"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:id="@+id/category"/>
android:layout_marginTop="10dp" />
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:singleLine="true"
android:text="@string/search_sort"
app:auto_text_tint="true"/>
app:auto_text_tint="true" />
<com.tungsten.fcllibrary.component.view.FCLSpinner
android:id="@+id/sort"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:id="@+id/sort"/>
android:layout_marginTop="10dp" />
</androidx.appcompat.widget.LinearLayoutCompat>
</ScrollView>
<com.tungsten.fcllibrary.component.view.FCLButton
android:visibility="gone"
app:ripple="true"
android:id="@+id/install_modpack"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/install_modpack"/>
android:layout_marginTop="10dp"
android:text="@string/install_modpack"
android:visibility="gone"
app:ripple="true" />
<com.tungsten.fcllibrary.component.view.FCLButton
app:ripple="true"
android:id="@+id/search"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/search"/>
android:layout_marginTop="10dp"
android:text="@string/search"
app:ripple="true" />
</androidx.appcompat.widget.LinearLayoutCompat>
<RelativeLayout
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/list_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
app:layout_constraintStart_toEndOf="@+id/left"
app:layout_constraintEnd_toEndOf="parent">
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/left">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/list_layout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:id="@+id/page"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:background="@drawable/bg_container_white"
android:gravity="center"
android:text="@string/search_page_n"
app:auto_text_background_tint="true"
app:auto_text_tint="true" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
app:auto_text_background_tint="true"
app:auto_text_tint="true"
android:gravity="center"
android:background="@drawable/bg_container_white"
android:id="@+id/page"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:text="@string/search_page_n"/>
<com.tungsten.fcllibrary.component.view.FCLButton
app:ripple="true"
app:auto_padding="false"
android:padding="10dp"
android:id="@+id/previous"
android:layout_marginStart="10dp"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/search_previous_page"/>
<com.tungsten.fcllibrary.component.view.FCLButton
app:ripple="true"
app:auto_padding="false"
android:padding="10dp"
android:id="@+id/next"
android:layout_marginStart="10dp"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/search_next_page"/>
<com.tungsten.fcllibrary.component.view.FCLButton
app:ripple="true"
app:auto_padding="false"
android:padding="10dp"
android:id="@+id/first"
android:layout_marginStart="10dp"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/search_first_page"/>
<com.tungsten.fcllibrary.component.view.FCLButton
app:ripple="true"
app:auto_padding="false"
android:padding="10dp"
android:id="@+id/last"
android:layout_marginStart="10dp"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/search_last_page"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<ListView
android:layout_marginTop="10dp"
android:id="@+id/list"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:id="@+id/progress"
<com.tungsten.fcllibrary.component.view.FCLButton
android:id="@+id/previous"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:padding="10dp"
android:text="@string/search_previous_page"
app:auto_padding="false"
app:ripple="true" />
<com.tungsten.fcllibrary.component.view.FCLImageButton
android:id="@+id/retry"
android:src="@drawable/ic_baseline_refresh_24"
<com.tungsten.fcllibrary.component.view.FCLButton
android:id="@+id/next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:padding="10dp"
android:text="@string/search_next_page"
app:auto_padding="false"
app:ripple="true" />
</RelativeLayout>
<com.tungsten.fcllibrary.component.view.FCLButton
android:id="@+id/first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:padding="10dp"
android:text="@string/search_first_page"
app:auto_padding="false"
app:ripple="true" />
<com.tungsten.fcllibrary.component.view.FCLButton
android:id="@+id/last"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:padding="10dp"
android:text="@string/search_last_page"
app:auto_padding="false"
app:ripple="true" />
</androidx.appcompat.widget.LinearLayoutCompat>
<ListView
android:id="@+id/list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/left"
app:layout_constraintTop_toBottomOf="@id/list_layout" />
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.tungsten.fcllibrary.component.view.FCLImageButton
android:id="@+id/retry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/ic_baseline_refresh_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -22,6 +22,7 @@
<string name="splash_runtime_java11" translatable="false">JRE 11</string>
<string name="splash_runtime_java17" translatable="false">JRE 17</string>
<string name="splash_runtime_java21" translatable="false">JRE 21</string>
<string name="splash_runtime_jna" translatable="false">JNA</string>
<string name="splash_runtime_install">Install / Update</string>
<string name="account">Account</string>

View File

@ -54,6 +54,7 @@ import java.util.logging.Level;
import java.util.stream.Collectors;
public class DefaultLauncher extends Launcher {
private String jnaVersion;
public DefaultLauncher(Context context, GameRepository repository, Version version, AuthInfo authInfo, LaunchOptions options) {
super(context, repository, version, authInfo, options);
@ -152,6 +153,9 @@ public class DefaultLauncher extends Launcher {
res.addDefault("-Duser.timezone=", TimeZone.getDefault().getID());
res.addDefault("-Dorg.lwjgl.vulkan.libname=", "libvulkan.so");
File libJna = new File(FCLPath.RUNTIME_DIR, "jna");
if (jnaVersion != null && !jnaVersion.isEmpty()) {
libJna = new File(libJna, jnaVersion);
}
res.addDefault("-Djna.boot.library.path=", libJna.exists() ? libJna.getAbsolutePath() : context.getApplicationInfo().nativeLibraryDir);
if (getInjectorArg() != null && options.isBeGesture()) {
@ -436,4 +440,8 @@ public class DefaultLauncher extends Launcher {
config.setUseVKDriverSystem(options.isVKDriverSystem());
return FCLauncher.launchMinecraft(config);
}
public void setJnaVersion(String jnaVersion) {
this.jnaVersion = jnaVersion;
}
}

View File

@ -1,5 +1,6 @@
package com.tungsten.fcllibrary.component.view;
import android.animation.AnimatorInflater;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.ColorStateList;
@ -95,6 +96,7 @@ public class FCLButton extends AppCompatButton {
drawablePress.setCornerRadius(ConvertUtils.dip2px(getContext(), 8));
drawablePress.setStroke(ConvertUtils.dip2px(getContext(), 1.5f), Color.GRAY);
drawablePress.setColor(ThemeEngine.getInstance().getTheme().getLtColor());
setStateListAnimator(AnimatorInflater.loadStateListAnimator(getContext(), R.xml.anim_scale));
}
public FCLButton(@NonNull Context context) {

View File

@ -1,5 +1,6 @@
package com.tungsten.fcllibrary.component.view;
import android.animation.AnimatorInflater;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.drawable.RippleDrawable;
@ -11,6 +12,7 @@ import androidx.appcompat.widget.AppCompatImageButton;
import com.tungsten.fclcore.fakefx.beans.property.IntegerProperty;
import com.tungsten.fclcore.fakefx.beans.property.IntegerPropertyBase;
import com.tungsten.fcllibrary.R;
import com.tungsten.fcllibrary.component.theme.ThemeEngine;
import com.tungsten.fcllibrary.util.ConvertUtils;
@ -68,6 +70,7 @@ public class FCLMenuView extends AppCompatImageButton {
setSelected(true);
}
});
setStateListAnimator(AnimatorInflater.loadStateListAnimator(getContext(), R.xml.anim_scale_large));
}
public void setSelected(boolean selected) {

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<set>
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="scaleX"
android:valueTo="0.9"
android:valueType="floatType" />
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="scaleY"
android:valueTo="0.9"
android:valueType="floatType" />
</set>
</item>
<item android:state_pressed="false">
<set>
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="scaleX"
android:valueTo="1"
android:valueType="floatType" />
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="scaleY"
android:valueTo="1"
android:valueType="floatType" />
</set>
</item>
</selector>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<set>
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="scaleX"
android:valueTo="1.5"
android:valueType="floatType" />
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="scaleY"
android:valueTo="1.5"
android:valueType="floatType" />
</set>
</item>
<item android:state_pressed="false">
<set>
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="scaleX"
android:valueTo="1"
android:valueType="floatType" />
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="scaleY"
android:valueTo="1"
android:valueType="floatType" />
</set>
</item>
</selector>

View File

@ -19,6 +19,7 @@ public class FCLPath {
public static String JAVA_11_PATH;
public static String JAVA_17_PATH;
public static String JAVA_21_PATH;
public static String JNA_PATH;
public static String LWJGL_DIR;
public static String CACIOCAVALLO_8_DIR;
public static String CACIOCAVALLO_11_DIR;
@ -51,6 +52,7 @@ public class FCLPath {
JAVA_11_PATH = RUNTIME_DIR + "/java/jre11";
JAVA_17_PATH = RUNTIME_DIR + "/java/jre17";
JAVA_21_PATH = RUNTIME_DIR + "/java/jre21";
JNA_PATH = RUNTIME_DIR + "/jna";
LWJGL_DIR = RUNTIME_DIR + "/lwjgl";
CACIOCAVALLO_8_DIR = RUNTIME_DIR + "/caciocavallo";
CACIOCAVALLO_11_DIR = RUNTIME_DIR + "/caciocavallo11";