This commit is contained in:
ShirosakiMio 2022-12-12 16:10:09 +08:00
commit bc10763d4d
32 changed files with 1523 additions and 76 deletions

View File

@ -193,6 +193,7 @@ public class MainActivity extends FCLActivity implements FCLMenuView.OnSelectLis
uiManager.switchUI(uiManager.getVersionUI());
} else {
titleView.setTextWithAnim(getString(R.string.manage));
uiManager.getManageUI().setVersion(version, Profiles.getSelectedProfile());
uiManager.switchUI(uiManager.getManageUI());
}
}

View File

@ -123,6 +123,24 @@ public abstract class PageManager {
}
}
public void dismissAllTempPagesCreatedByPage(int id) {
FCLCommonPage commonPage = getPageById(id);
if (commonPage.getCurrentTempPage() != null) {
commonPage.getCurrentTempPage().dismiss();
}
commonPage.getAllTempPages().clear();
commonPage.setCurrentTempPage(null);
if (currentPage == commonPage) {
commonPage.onStart();
}
}
public void dismissAllTempPages() {
for (FCLCommonPage page : allPages) {
dismissAllTempPagesCreatedByPage(page.getId());
}
}
public void onPause() {
for (FCLCommonPage page : allPages) {
page.onPause();

View File

@ -1,18 +1,259 @@
package com.tungsten.fcl.ui.manage;
import static com.tungsten.fcl.ui.download.InstallersPage.alertFailureMessage;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
import androidx.appcompat.app.AppCompatDialog;
import androidx.appcompat.widget.LinearLayoutCompat;
import com.tungsten.fcl.R;
import com.tungsten.fcl.setting.DownloadProviders;
import com.tungsten.fcl.setting.Profile;
import com.tungsten.fcl.ui.InstallerItem;
import com.tungsten.fcl.ui.PageManager;
import com.tungsten.fcl.ui.TaskDialog;
import com.tungsten.fcl.ui.download.InstallerVersionPage;
import com.tungsten.fcl.util.AndroidUtils;
import com.tungsten.fcl.util.RequestCodes;
import com.tungsten.fcl.util.TaskCancellationAction;
import com.tungsten.fclcore.download.LibraryAnalyzer;
import com.tungsten.fclcore.download.RemoteVersion;
import com.tungsten.fclcore.game.Version;
import com.tungsten.fclcore.task.Schedulers;
import com.tungsten.fclcore.task.Task;
import com.tungsten.fclcore.task.TaskExecutor;
import com.tungsten.fclcore.task.TaskListener;
import com.tungsten.fcllibrary.browser.FileBrowser;
import com.tungsten.fcllibrary.browser.options.LibMode;
import com.tungsten.fcllibrary.browser.options.SelectionMode;
import com.tungsten.fcllibrary.component.dialog.FCLAlertDialog;
import com.tungsten.fcllibrary.component.ui.FCLCommonPage;
import com.tungsten.fcllibrary.component.view.FCLButton;
import com.tungsten.fcllibrary.component.view.FCLUILayout;
import com.tungsten.fcllibrary.util.ConvertUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
public class InstallerListPage extends FCLCommonPage implements ManageUI.VersionLoadable, View.OnClickListener {
private Profile profile;
private String versionId;
private Version version;
private String gameVersion;
private ScrollView scrollView;
private LinearLayoutCompat parent;
private FCLButton installOfflineButton;
public class InstallerListPage extends FCLCommonPage {
public InstallerListPage(Context context, int id, FCLUILayout parent, int resId) {
super(context, id, parent, resId);
create();
}
private void create() {
scrollView = findViewById(R.id.scroll);
installOfflineButton = findViewById(R.id.install_offline);
installOfflineButton.setOnClickListener(this);
}
@Override
public Task<?> refresh(Object... param) {
return null;
}
@Override
public void loadVersion(Profile profile, String versionId) {
this.profile = profile;
this.versionId = versionId;
this.version = profile.getRepository().getVersion(versionId);
this.gameVersion = null;
CompletableFuture.supplyAsync(() -> {
gameVersion = profile.getRepository().getGameVersion(version).orElse(null);
return LibraryAnalyzer.analyze(profile.getRepository().getResolvedPreservingPatchesVersion(versionId));
}).thenAcceptAsync(analyzer -> {
Function<String, Runnable> removeAction = libraryId -> () -> profile.getDependency().removeLibraryAsync(version, libraryId)
.thenComposeAsync(profile.getRepository()::saveAsync)
.withComposeAsync(profile.getRepository().refreshVersionsAsync())
.withRunAsync(Schedulers.androidUIThread(), () -> loadVersion(this.profile, this.versionId))
.start();
clear();
InstallerItem.InstallerItemGroup group = new InstallerItem.InstallerItemGroup(getContext());
// Conventional libraries: game, fabric, quilt, forge, liteloader, optifine
for (InstallerItem installerItem : group.getLibraries()) {
String libraryId = installerItem.getLibraryId();
String libraryVersion = analyzer.getVersion(libraryId).orElse(null);
installerItem.libraryVersion.set(libraryVersion);
installerItem.upgradable.set(libraryVersion != null);
installerItem.installable.set(true);
installerItem.action.set(() -> {
InstallerVersionPage page = new InstallerVersionPage(getContext(), PageManager.PAGE_ID_TEMP, getParent(), R.layout.page_install_version, gameVersion, libraryId, remoteVersion -> {
if (libraryVersion == null) {
finish(profile, remoteVersion);
} else {
FCLAlertDialog.Builder builder = new FCLAlertDialog.Builder(getContext());
builder.setCancelable(false);
builder.setAlertLevel(FCLAlertDialog.AlertLevel.INFO);
builder.setTitle(getContext().getString(R.string.install_change_version));
builder.setMessage(AndroidUtils.getLocalizedText(getContext(), "install_change_version_confirm", AndroidUtils.getLocalizedText(getContext(), "install_installer_" + libraryId), libraryVersion, remoteVersion.getSelfVersion()));
builder.setPositiveButton(() -> finish(profile, remoteVersion));
builder.setNegativeButton(null);
builder.create().show();
}
});
ManagePageManager.getInstance().showTempPage(page);
});
boolean removable = !"game".equals(libraryId) && libraryVersion != null;
installerItem.removable.set(removable);
if (removable) {
Runnable action = removeAction.apply(libraryId);
installerItem.removeAction.set(action);
}
addView(installerItem);
}
}, Schedulers.androidUIThread());
}
public void installOffline() {
ArrayList<String> suffix = new ArrayList<>();
suffix.add(".jar");
FileBrowser.Builder builder = new FileBrowser.Builder(getContext());
builder.setTitle(getContext().getString(R.string.install_installer_install_offline_extension));
builder.setLibMode(LibMode.FILE_CHOOSER);
builder.setSelectionMode(SelectionMode.SINGLE_SELECTION);
builder.setSuffix(suffix);
builder.create().browse(getActivity(), RequestCodes.SELECT_AUTO_INSTALLER_CODE, (requestCode, resultCode, data) -> {
if (requestCode == RequestCodes.SELECT_AUTO_INSTALLER_CODE && resultCode == Activity.RESULT_OK && data != null) {
String path = FileBrowser.getSelectedFiles(data).get(0);
if (new File(path).exists()) {
doInstallOffline(new File(path));
}
}
});
}
private void doInstallOffline(File file) {
Task<?> task = profile.getDependency().installLibraryAsync(version, file.toPath())
.thenComposeAsync(profile.getRepository()::saveAsync)
.thenComposeAsync(profile.getRepository().refreshVersionsAsync());
task.setName(getContext().getString(R.string.install_installer_install_offline));
TaskExecutor executor = task.executor(new TaskListener() {
@Override
public void onStop(boolean success, TaskExecutor executor) {
Schedulers.androidUIThread().execute(() -> {
if (success) {
loadVersion(profile, versionId);
FCLAlertDialog.Builder builder = new FCLAlertDialog.Builder(getContext());
builder.setAlertLevel(FCLAlertDialog.AlertLevel.INFO);
builder.setCancelable(false);
builder.setMessage(getContext().getString(R.string.install_success));
builder.setNegativeButton(getContext().getString(com.tungsten.fcllibrary.R.string.dialog_positive), null);
builder.create().show();
} else {
if (executor.getException() == null)
return;
alertFailureMessage(getContext(), executor.getException(), () -> {});
}
loadVersion(InstallerListPage.this.profile, InstallerListPage.this.versionId);
});
}
});
TaskDialog dialog = new TaskDialog(getContext(), TaskCancellationAction.NO_CANCEL);
dialog.setTitle(getContext().getString(R.string.install_installer_install_offline));
dialog.setExecutor(executor);
dialog.show();
executor.start();
}
private void clear() {
if (parent == null) {
parent = new LinearLayoutCompat(getContext());
parent.setOrientation(LinearLayoutCompat.VERTICAL);
scrollView.addView(parent);
ViewGroup.LayoutParams layoutParams = scrollView.getChildAt(0).getLayoutParams();
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
scrollView.getChildAt(0).setLayoutParams(layoutParams);
}
parent.removeAllViews();
}
private void addView(InstallerItem installerItem) {
if (parent == null) {
parent = new LinearLayoutCompat(getContext());
parent.setOrientation(LinearLayoutCompat.VERTICAL);
scrollView.addView(parent);
ViewGroup.LayoutParams layoutParams = scrollView.getChildAt(0).getLayoutParams();
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
scrollView.getChildAt(0).setLayoutParams(layoutParams);
}
View view = installerItem.createView();
if (parent.getChildCount() > 0) {
view.setPadding(0, ConvertUtils.dip2px(getContext(), 10), 0, 0);
}
parent.addView(view);
}
private void finish(Profile profile, RemoteVersion remoteVersion) {
// We remove library but not save it,
// so if installation failed will not break down current version.
Task<Version> ret = Task.supplyAsync(() -> version);
List<String> stages = new ArrayList<>();
ret = ret.thenComposeAsync(version -> profile.getDependency(DownloadProviders.getDownloadProvider()).installLibraryAsync(version, remoteVersion));
stages.add(String.format("fcl.install.%s:%s", remoteVersion.getLibraryId(), remoteVersion.getSelfVersion()));
Task<?> task = ret.thenComposeAsync(profile.getRepository()::saveAsync).thenComposeAsync(profile.getRepository().refreshVersionsAsync()).withStagesHint(stages);
TaskDialog pane = new TaskDialog(getContext(), new TaskCancellationAction(AppCompatDialog::dismiss));
pane.setTitle(getContext().getString(R.string.install_change_version));
Schedulers.androidUIThread().execute(() -> {
TaskExecutor executor = task.executor(new TaskListener() {
@Override
public void onStop(boolean success, TaskExecutor executor) {
Schedulers.androidUIThread().execute(() -> {
if (success) {
FCLAlertDialog.Builder builder1 = new FCLAlertDialog.Builder(getContext());
builder1.setAlertLevel(FCLAlertDialog.AlertLevel.INFO);
builder1.setCancelable(false);
builder1.setMessage(getContext().getString(R.string.install_success));
builder1.setNegativeButton(getContext().getString(com.tungsten.fcllibrary.R.string.dialog_positive), () -> ManagePageManager.getInstance().dismissCurrentTempPage());
builder1.create().show();
} else {
if (executor.getException() == null)
return;
alertFailureMessage(getContext(), executor.getException(), () -> {});
}
loadVersion(InstallerListPage.this.profile, InstallerListPage.this.versionId);
});
}
});
pane.setExecutor(executor);
pane.show();
executor.start();
});
}
@Override
public void onClick(View view) {
if (view == installOfflineButton) {
installOffline();
}
}
}

View File

@ -0,0 +1,177 @@
package com.tungsten.fcl.ui.manage;
import android.content.Context;
import android.view.View;
import com.tungsten.fcl.R;
import com.tungsten.fcl.setting.Profile;
import com.tungsten.fcl.ui.UIManager;
import com.tungsten.fcl.ui.version.Versions;
import com.tungsten.fcl.util.RequestCodes;
import com.tungsten.fclcore.fakefx.beans.property.BooleanProperty;
import com.tungsten.fclcore.fakefx.beans.property.SimpleBooleanProperty;
import com.tungsten.fclcore.task.Task;
import com.tungsten.fclcore.util.io.FileUtils;
import com.tungsten.fcllibrary.browser.FileBrowser;
import com.tungsten.fcllibrary.browser.options.LibMode;
import com.tungsten.fcllibrary.component.ui.FCLCommonPage;
import com.tungsten.fcllibrary.component.view.FCLImageButton;
import com.tungsten.fcllibrary.component.view.FCLLinearLayout;
import com.tungsten.fcllibrary.component.view.FCLUILayout;
import java.io.File;
public class ManagePage extends FCLCommonPage implements ManageUI.VersionLoadable, View.OnClickListener {
private final BooleanProperty currentVersionUpgradable = new SimpleBooleanProperty();
private FCLImageButton browseGame;
private FCLImageButton browseMod;
private FCLImageButton browseConfig;
private FCLImageButton browseResourcepack;
private FCLImageButton browseScreenshot;
private FCLImageButton browseSave;
private FCLImageButton update;
private FCLImageButton rename;
private FCLImageButton duplicate;
private FCLImageButton export;
private FCLImageButton redownload;
private FCLImageButton deleteLibs;
private FCLImageButton deleteLogs;
private FCLLinearLayout updateLayout;
public ManagePage(Context context, int id, FCLUILayout parent, int resId) {
super(context, id, parent, resId);
create();
}
@Override
public Task<?> refresh(Object... param) {
return null;
}
@Override
public void loadVersion(Profile profile, String version) {
currentVersionUpgradable.set(profile.getRepository().isModpack(version));
}
private void create() {
browseGame = findViewById(R.id.browse_game_dir);
browseMod = findViewById(R.id.browse_mods);
browseConfig = findViewById(R.id.browse_config);
browseResourcepack = findViewById(R.id.browse_resourcepacks);
browseScreenshot = findViewById(R.id.browse_screenshots);
browseSave = findViewById(R.id.browse_saves);
update = findViewById(R.id.update);
rename = findViewById(R.id.rename);
duplicate = findViewById(R.id.duplicate);
export = findViewById(R.id.export);
redownload = findViewById(R.id.update_assets);
deleteLibs = findViewById(R.id.delete_libs);
deleteLogs = findViewById(R.id.delete_logs);
browseGame.setOnClickListener(this);
browseMod.setOnClickListener(this);
browseConfig.setOnClickListener(this);
browseResourcepack.setOnClickListener(this);
browseScreenshot.setOnClickListener(this);
browseSave.setOnClickListener(this);
update.setOnClickListener(this);
rename.setOnClickListener(this);
duplicate.setOnClickListener(this);
export.setOnClickListener(this);
redownload.setOnClickListener(this);
deleteLibs.setOnClickListener(this);
deleteLogs.setOnClickListener(this);
updateLayout = findViewById(R.id.update_layout);
updateLayout.visibilityProperty().bind(currentVersionUpgradable);
}
private void onBrowse(String sub) {
FileBrowser.Builder builder = new FileBrowser.Builder(getContext());
builder.setLibMode(LibMode.FILE_BROWSER);
builder.setInitDir(new File(getProfile().getRepository().getRunDirectory(getVersion()), sub).getAbsolutePath());
builder.create().browse(getActivity(), RequestCodes.BROWSE_DIR_CODE, null);
}
private void redownloadAssetIndex() {
Versions.updateGameAssets(getContext(), getProfile(), getVersion());
}
private void clearLibraries() {
FileUtils.deleteDirectoryQuietly(new File(getProfile().getRepository().getBaseDirectory(), "libraries"));
}
private void clearJunkFiles() {
Versions.cleanVersion(getProfile(), getVersion());
}
private void updateGame() {
Versions.updateVersion(getProfile(), getVersion());
}
private void export() {
Versions.exportVersion(getProfile(), getVersion());
}
private void rename() {
Versions.renameVersion(getContext(), getProfile(), getVersion())
.thenApply(newVersionName -> UIManager.getInstance().getManageUI().preferredVersionName = newVersionName);
}
private void duplicate() {
Versions.duplicateVersion(getContext(), getProfile(), getVersion());
}
public Profile getProfile() {
return UIManager.getInstance().getManageUI().getProfile();
}
public String getVersion() {
return UIManager.getInstance().getManageUI().getVersion();
}
@Override
public void onClick(View view) {
if (view == browseGame) {
onBrowse("");
}
if (view == browseMod) {
onBrowse("mods");
}
if (view == browseConfig) {
onBrowse("config");
}
if (view == browseResourcepack) {
onBrowse("resourcepacks");
}
if (view == browseScreenshot) {
onBrowse("screenshots");
}
if (view == browseSave) {
onBrowse("saves");
}
if (view == update) {
updateGame();
}
if (view == rename) {
rename();
}
if (view == duplicate) {
duplicate();
}
if (view == export) {
export();
}
if (view == redownload) {
redownloadAssetIndex();
}
if (view == deleteLibs) {
clearLibraries();
}
if (view == deleteLogs) {
clearJunkFiles();
}
}
}

View File

@ -3,6 +3,7 @@ package com.tungsten.fcl.ui.manage;
import android.content.Context;
import com.tungsten.fcl.R;
import com.tungsten.fcl.setting.Profile;
import com.tungsten.fcl.ui.PageManager;
import com.tungsten.fcl.ui.UIListener;
import com.tungsten.fcl.ui.download.DownloadPage;
@ -14,13 +15,15 @@ import java.util.ArrayList;
public class ManagePageManager extends PageManager {
public static final int PAGE_ID_MANAGE_SETTING = 15000;
public static final int PAGE_ID_MANAGE_INSTALL = 15001;
public static final int PAGE_ID_MANAGE_MOD = 15002;
public static final int PAGE_ID_MANAGE_WORLD = 15003;
public static final int PAGE_ID_MANAGE_MANAGE = 15000;
public static final int PAGE_ID_MANAGE_SETTING = 15001;
public static final int PAGE_ID_MANAGE_INSTALL = 15002;
public static final int PAGE_ID_MANAGE_MOD = 15003;
public static final int PAGE_ID_MANAGE_WORLD = 15004;
private static ManagePageManager instance;
private ManagePage managePage;
private VersionSettingPage versionSettingPage;
private InstallerListPage installerListPage;
private ModListPage modListPage;
@ -40,7 +43,8 @@ public class ManagePageManager extends PageManager {
@Override
public void init(UIListener listener) {
versionSettingPage = new VersionSettingPage(getContext(), PAGE_ID_MANAGE_SETTING, getParent(), R.layout.page_version_setting);
managePage = new ManagePage(getContext(), PAGE_ID_MANAGE_MANAGE, getParent(), R.layout.page_manage);
versionSettingPage = new VersionSettingPage(getContext(), PAGE_ID_MANAGE_SETTING, getParent(), R.layout.page_version_setting, false);
installerListPage = new InstallerListPage(getContext(), PAGE_ID_MANAGE_INSTALL, getParent(), R.layout.page_installer_list);
modListPage = new ModListPage(getContext(), PAGE_ID_MANAGE_MOD, getParent(), R.layout.page_mod_list);
worldListPage = new WorldListPage(getContext(), PAGE_ID_MANAGE_WORLD, getParent(), R.layout.page_world_list);
@ -53,10 +57,19 @@ public class ManagePageManager extends PageManager {
@Override
public ArrayList<FCLCommonPage> getAllPages() {
ArrayList<FCLCommonPage> pages = new ArrayList<>();
pages.add(managePage);
pages.add(versionSettingPage);
pages.add(installerListPage);
pages.add(modListPage);
pages.add(worldListPage);
return pages;
}
public void loadVersion(Profile profile, String version) {
managePage.loadVersion(profile, version);
versionSettingPage.loadVersion(profile, version);
installerListPage.loadVersion(profile, version);
modListPage.loadVersion(profile, version);
worldListPage.loadVersion(profile, version);
}
}

View File

@ -6,6 +6,16 @@ import android.content.Context;
import com.google.android.material.tabs.TabLayout;
import com.tungsten.fcl.R;
import com.tungsten.fcl.activity.MainActivity;
import com.tungsten.fcl.setting.Profile;
import com.tungsten.fcl.util.WeakListenerHolder;
import com.tungsten.fclcore.event.EventBus;
import com.tungsten.fclcore.event.EventPriority;
import com.tungsten.fclcore.event.RefreshedVersionsEvent;
import com.tungsten.fclcore.fakefx.beans.property.ObjectProperty;
import com.tungsten.fclcore.fakefx.beans.property.SimpleObjectProperty;
import com.tungsten.fclcore.game.GameRepository;
import com.tungsten.fclcore.task.Schedulers;
import com.tungsten.fclcore.task.Task;
import com.tungsten.fcllibrary.component.ui.FCLBasePage;
import com.tungsten.fcllibrary.component.ui.FCLMultiPageUI;
@ -20,9 +30,12 @@ public class ManageUI extends FCLMultiPageUI implements TabLayout.OnTabSelectedL
private ManagePageManager pageManager;
private FCLTabLayout tabLayout;
private FCLUILayout container;
private final ObjectProperty<Profile.ProfileVersion> version = new SimpleObjectProperty<>();
private final WeakListenerHolder listenerHolder = new WeakListenerHolder();
public String preferredVersionName = null;
public ManageUI(Context context, FCLUILayout parent, int id) {
super(context, parent, id);
}
@ -30,16 +43,32 @@ public class ManageUI extends FCLMultiPageUI implements TabLayout.OnTabSelectedL
@Override
public void onCreate() {
super.onCreate();
tabLayout = findViewById(R.id.tab_layout);
FCLTabLayout tabLayout = findViewById(R.id.tab_layout);
container = findViewById(R.id.container);
tabLayout.addOnTabSelectedListener(this);
container.post(this::initPages);
listenerHolder.add(EventBus.EVENT_BUS.channel(RefreshedVersionsEvent.class).registerWeak(event -> checkSelectedVersion(), EventPriority.HIGHEST));
}
@Override
public void onStart() {
super.onStart();
// If we jumped to game list page and deleted this version
// and back to this page, we should return to main page.
if (!getProfile().getRepository().isLoaded() ||
!getProfile().getRepository().hasVersion(getVersion())) {
Schedulers.androidUIThread().execute(() -> {
if (isShowing()) {
MainActivity.getInstance().refreshMenuView(null);
MainActivity.getInstance().home.setSelected(true);
}
});
return;
}
loadVersion(getVersion(), getProfile());
}
@Override
@ -69,7 +98,7 @@ public class ManageUI extends FCLMultiPageUI implements TabLayout.OnTabSelectedL
@Override
public void initPages() {
pageManager = new ManagePageManager(getContext(), container, ManagePageManager.PAGE_ID_MANAGE_SETTING, null);
pageManager = new ManagePageManager(getContext(), container, ManagePageManager.PAGE_ID_MANAGE_MANAGE, null);
}
@Override
@ -92,16 +121,19 @@ public class ManageUI extends FCLMultiPageUI implements TabLayout.OnTabSelectedL
if (pageManager != null) {
switch (tab.getPosition()) {
case 1:
pageManager.switchPage(ManagePageManager.PAGE_ID_MANAGE_INSTALL);
pageManager.switchPage(ManagePageManager.PAGE_ID_MANAGE_SETTING);
break;
case 2:
pageManager.switchPage(ManagePageManager.PAGE_ID_MANAGE_MOD);
pageManager.switchPage(ManagePageManager.PAGE_ID_MANAGE_INSTALL);
break;
case 3:
pageManager.switchPage(ManagePageManager.PAGE_ID_MANAGE_MOD);
break;
case 4:
pageManager.switchPage(ManagePageManager.PAGE_ID_MANAGE_WORLD);
break;
default:
pageManager.switchPage(ManagePageManager.PAGE_ID_MANAGE_SETTING);
pageManager.switchPage(ManagePageManager.PAGE_ID_MANAGE_MANAGE);
break;
}
}
@ -116,4 +148,56 @@ public class ManageUI extends FCLMultiPageUI implements TabLayout.OnTabSelectedL
public void onTabReselected(TabLayout.Tab tab) {
}
private void checkSelectedVersion() {
Schedulers.androidUIThread().execute(() -> {
if (this.version.get() == null) return;
GameRepository repository = this.version.get().getProfile().getRepository();
if (!repository.hasVersion(this.version.get().getVersion())) {
if (preferredVersionName != null) {
loadVersion(preferredVersionName, this.version.get().getProfile());
} else if (isShowing()) {
MainActivity.getInstance().refreshMenuView(null);
MainActivity.getInstance().home.setSelected(true);
}
}
});
}
public void setVersion(String version, Profile profile) {
this.version.set(new Profile.ProfileVersion(profile, version));
}
public void loadVersion(String version, Profile profile) {
// If we jumped to game list page and deleted this version
// and back to this page, we should return to main page.
if (this.version.get() != null && (!getProfile().getRepository().isLoaded() ||
!getProfile().getRepository().hasVersion(version))) {
Schedulers.androidUIThread().execute(() -> {
if (isShowing()) {
MainActivity.getInstance().refreshMenuView(null);
MainActivity.getInstance().home.setSelected(true);
}
});
return;
}
setVersion(version, profile);
preferredVersionName = version;
pageManager.dismissAllTempPages();
pageManager.loadVersion(profile, version);
}
public Profile getProfile() {
return Optional.ofNullable(version.get()).map(Profile.ProfileVersion::getProfile).orElse(null);
}
public String getVersion() {
return Optional.ofNullable(version.get()).map(Profile.ProfileVersion::getVersion).orElse(null);
}
public interface VersionLoadable {
void loadVersion(Profile profile, String version);
}
}

View File

@ -2,11 +2,12 @@ package com.tungsten.fcl.ui.manage;
import android.content.Context;
import com.tungsten.fcl.setting.Profile;
import com.tungsten.fclcore.task.Task;
import com.tungsten.fcllibrary.component.ui.FCLCommonPage;
import com.tungsten.fcllibrary.component.view.FCLUILayout;
public class ModListPage extends FCLCommonPage {
public class ModListPage extends FCLCommonPage implements ManageUI.VersionLoadable {
public ModListPage(Context context, int id, FCLUILayout parent, int resId) {
super(context, id, parent, resId);
}
@ -15,4 +16,9 @@ public class ModListPage extends FCLCommonPage {
public Task<?> refresh(Object... param) {
return null;
}
@Override
public void loadVersion(Profile profile, String version) {
}
}

View File

@ -2,17 +2,27 @@ package com.tungsten.fcl.ui.manage;
import android.content.Context;
import com.tungsten.fcl.setting.Profile;
import com.tungsten.fclcore.task.Task;
import com.tungsten.fcllibrary.component.ui.FCLCommonPage;
import com.tungsten.fcllibrary.component.view.FCLUILayout;
public class VersionSettingPage extends FCLCommonPage {
public VersionSettingPage(Context context, int id, FCLUILayout parent, int resId) {
public class VersionSettingPage extends FCLCommonPage implements ManageUI.VersionLoadable {
private final boolean globalSetting;
public VersionSettingPage(Context context, int id, FCLUILayout parent, int resId, boolean globalSetting) {
super(context, id, parent, resId);
this.globalSetting = globalSetting;
}
@Override
public Task<?> refresh(Object... param) {
return null;
}
@Override
public void loadVersion(Profile profile, String version) {
}
}

View File

@ -2,11 +2,12 @@ package com.tungsten.fcl.ui.manage;
import android.content.Context;
import com.tungsten.fcl.setting.Profile;
import com.tungsten.fclcore.task.Task;
import com.tungsten.fcllibrary.component.ui.FCLCommonPage;
import com.tungsten.fcllibrary.component.view.FCLUILayout;
public class WorldListPage extends FCLCommonPage {
public class WorldListPage extends FCLCommonPage implements ManageUI.VersionLoadable {
public WorldListPage(Context context, int id, FCLUILayout parent, int resId) {
super(context, id, parent, resId);
}
@ -15,4 +16,9 @@ public class WorldListPage extends FCLCommonPage {
public Task<?> refresh(Object... param) {
return null;
}
@Override
public void loadVersion(Profile profile, String version) {
}
}

View File

@ -0,0 +1,82 @@
package com.tungsten.fcl.ui.version;
import android.content.Context;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
import com.tungsten.fcl.R;
import com.tungsten.fcl.game.FCLGameRepository;
import com.tungsten.fcl.setting.Profile;
import com.tungsten.fclcore.util.FutureCallback;
import com.tungsten.fclcore.util.StringUtils;
import com.tungsten.fcllibrary.component.dialog.FCLDialog;
import com.tungsten.fcllibrary.component.view.FCLButton;
import com.tungsten.fcllibrary.component.view.FCLCheckBox;
import com.tungsten.fcllibrary.component.view.FCLEditText;
import java.util.ArrayList;
import java.util.Objects;
public class DuplicateVersionDialog extends FCLDialog implements View.OnClickListener {
private final Profile profile;
private final String version;
private final FutureCallback<ArrayList<Object>> callback;
private FCLEditText editText;
private FCLCheckBox checkBox;
private FCLButton positive;
private FCLButton negative;
public DuplicateVersionDialog(@NonNull Context context, Profile profile, String version, FutureCallback<ArrayList<Object>> callback) {
super(context);
this.profile = profile;
this.version = version;
this.callback = callback;
setContentView(R.layout.dialog_duplicate_version);
setCancelable(false);
editText = findViewById(R.id.new_name);
checkBox = findViewById(R.id.check_save);
positive = findViewById(R.id.positive);
negative = findViewById(R.id.negative);
editText.setText(version);
positive.setOnClickListener(this);
negative.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if (view == positive) {
String newVersionName = Objects.requireNonNull(editText.getText()).toString();
if (StringUtils.isBlank(newVersionName)) {
Toast.makeText(getContext(), getContext().getString(R.string.input_not_empty), Toast.LENGTH_SHORT).show();
} else if (profile.getRepository().versionIdConflicts(newVersionName)) {
Toast.makeText(getContext(), getContext().getString(R.string.install_new_game_already_exists), Toast.LENGTH_SHORT).show();
} else if (!FCLGameRepository.isValidVersionId(newVersionName)) {
Toast.makeText(getContext(), getContext().getString(R.string.install_new_game_malformed), Toast.LENGTH_SHORT).show();
} else {
positive.setEnabled(false);
negative.setEnabled(false);
ArrayList<Object> res = new ArrayList<>();
res.add(newVersionName);
res.add(checkBox.isChecked());
callback.call(res, () -> {
positive.setEnabled(true);
negative.setEnabled(true);
dismiss();
}, msg -> {
positive.setEnabled(true);
negative.setEnabled(true);
Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT).show();
});
}
}
if (view == negative) {
dismiss();
}
}
}

View File

@ -8,13 +8,19 @@ import com.tungsten.fcl.activity.MainActivity;
import com.tungsten.fcl.game.LauncherHelper;
import com.tungsten.fcl.setting.Accounts;
import com.tungsten.fcl.setting.Profile;
import com.tungsten.fcl.ui.TaskDialog;
import com.tungsten.fcl.ui.UIManager;
import com.tungsten.fcl.ui.account.CreateAccountDialog;
import com.tungsten.fcl.util.RequestCodes;
import com.tungsten.fcl.util.TaskCancellationAction;
import com.tungsten.fclcore.auth.Account;
import com.tungsten.fclcore.download.game.GameAssetDownloadTask;
import com.tungsten.fclcore.game.GameDirectoryType;
import com.tungsten.fclcore.task.Schedulers;
import com.tungsten.fclcore.task.Task;
import com.tungsten.fclcore.task.TaskExecutor;
import com.tungsten.fclcore.util.Logging;
import com.tungsten.fclcore.util.StringUtils;
import com.tungsten.fclcore.util.platform.OperatingSystem;
import com.tungsten.fcllibrary.browser.FileBrowser;
import com.tungsten.fcllibrary.browser.options.LibMode;
@ -27,6 +33,46 @@ import java.util.logging.Level;
public class Versions {
/*
public static void importModpack() {
Profile profile = Profiles.getSelectedProfile();
if (profile.getRepository().isLoaded()) {
Controllers.getDecorator().startWizard(new ModpackInstallWizardProvider(profile), i18n("install.modpack"));
}
}
public static void downloadModpackImpl(Profile profile, String version, RemoteMod.Version file) {
Path modpack;
URL downloadURL;
try {
modpack = Files.createTempFile("modpack", ".zip");
downloadURL = new URL(file.getFile().getUrl());
} catch (IOException e) {
Controllers.dialog(
i18n("install_failed_downloading_detail", file.getFile().getUrl()) + "\n" + StringUtils.getStackTrace(e),
i18n("download_failed"), MessageDialogPane.MessageType.ERROR);
return;
}
Controllers.taskDialog(
new FileDownloadTask(downloadURL, modpack.toFile())
.whenComplete(Schedulers.javafx(), e -> {
if (e == null) {
Controllers.getDecorator().startWizard(new ModpackInstallWizardProvider(profile, modpack.toFile()));
} else if (e instanceof CancellationException) {
Controllers.showToast(i18n("message.cancelled"));
} else {
Controllers.dialog(
i18n("install.failed.downloading.detail", file.getFile().getUrl()) + "\n" + StringUtils.getStackTrace(e),
i18n("download.failed"), MessageDialogPane.MessageType.ERROR);
}
}).executor(true),
i18n("message.downloading"),
TaskCancellationAction.NORMAL
);
}
*/
public static void deleteVersion(Context context, Profile profile, String version) {
boolean isIndependent = profile.getVersionSetting(version).getGameDirType() == GameDirectoryType.VERSION_FOLDER;
String message = isIndependent ? String.format(context.getString(R.string.version_manage_remove_confirm_independent), version) : String.format(context.getString(R.string.version_manage_remove_confirm), version);
@ -65,26 +111,21 @@ public class Versions {
return dialog.getFuture();
}
/*
public static void exportVersion(Profile profile, String version) {
Controllers.getDecorator().startWizard(new ExportWizardProvider(profile, version), i18n("modpack.wizard"));
//Controllers.getDecorator().startWizard(new ExportWizardProvider(profile, version), i18n("modpack.wizard"));
}
*/
public static void openFolder(Activity context, Profile profile, String version) {
FileBrowser.Builder builder = new FileBrowser.Builder(context);
builder.setLibMode(LibMode.FILE_BROWSER);
builder.setInitDir(profile.getRepository().getRunDirectory(version).getAbsolutePath());
builder.create().browse(context, RequestCodes.BROWSE_VERSION_DIR_CODE, null);
builder.create().browse(context, RequestCodes.BROWSE_DIR_CODE, null);
}
/*
public static void duplicateVersion(Profile profile, String version) {
Controllers.prompt(
new PromptDialogPane.Builder(i18n("version.manage.duplicate.prompt"), (res, resolve, reject) -> {
String newVersionName = ((PromptDialogPane.Builder.StringQuestion) res.get(1)).getValue();
boolean copySaves = ((PromptDialogPane.Builder.BooleanQuestion) res.get(2)).getValue();
public static void duplicateVersion(Context context, Profile profile, String version) {
DuplicateVersionDialog dialog = new DuplicateVersionDialog(context, profile, version, (res, resolve, reject) -> {
String newVersionName = (String) res.get(0);
boolean copySaves = (boolean) res.get(1);
Task.runAsync(() -> profile.getRepository().duplicateVersion(version, newVersionName, copySaves))
.thenComposeAsync(profile.getRepository().refreshVersionsAsync())
.whenComplete(Schedulers.androidUIThread(), (result, exception) -> {
@ -95,26 +136,24 @@ public class Versions {
profile.getRepository().removeVersionFromDisk(newVersionName);
}
}).start();
})
.addQuestion(new PromptDialogPane.Builder.HintQuestion(i18n("version.manage.duplicate.confirm")))
.addQuestion(new PromptDialogPane.Builder.StringQuestion(null, version,
new Validator(i18n("install.new_game.already_exists"), newVersionName -> !profile.getRepository().hasVersion(newVersionName))))
.addQuestion(new PromptDialogPane.Builder.BooleanQuestion(i18n("version.manage.duplicate.duplicate_save"), false)));
});
dialog.show();
}
public static void updateVersion(Profile profile, String version) {
Controllers.getDecorator().startWizard(new ModpackInstallWizardProvider(profile, version));
//Controllers.getDecorator().startWizard(new ModpackInstallWizardProvider(profile, version));
}
public static void updateGameAssets(Profile profile, String version) {
public static void updateGameAssets(Context context, Profile profile, String version) {
TaskExecutor executor = new GameAssetDownloadTask(profile.getDependency(), profile.getRepository().getVersion(version), GameAssetDownloadTask.DOWNLOAD_INDEX_FORCIBLY, true)
.executor();
Controllers.taskDialog(executor, i18n("version.manage.redownload_assets_index"), TaskCancellationAction.NO_CANCEL);
TaskDialog dialog = new TaskDialog(context, TaskCancellationAction.NO_CANCEL);
dialog.setExecutor(executor);
dialog.setTitle(context.getString(R.string.version_manage_redownload_assets_index));
dialog.show();
executor.start();
}
*/
public static void cleanVersion(Profile profile, String id) {
try {
profile.getRepository().clean(id);

View File

@ -4,9 +4,13 @@ public class RequestCodes {
public static final int PERMISSION_REQUEST_CODE = 0;
public static final int BROWSE_VERSION_DIR_CODE = 50;
public static final int BROWSE_DIR_CODE = 50;
public static final int SELECT_PROFILE_CODE = 100;
public static final int SELECT_SKIN_CODE = 150;
public static final int SELECT_AUTO_INSTALLER_CODE = 200;
public static final int SELECT_MANUAL_INSTALLER_CODE = 250;
}

View File

@ -0,0 +1,10 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M17.9,17.39C17.64,16.59 16.89,16 16,16H15V13A1,1 0 0,0 14,12H8V10H10A1,1 0 0,0 11,9V7H13A2,2 0 0,0 15,5V4.59C17.93,5.77 20,8.64 20,12C20,14.08 19.2,15.97 17.9,17.39M11,19.93C7.05,19.44 4,16.08 4,12C4,11.38 4.08,10.78 4.21,10.21L9,15V16A2,2 0 0,0 11,18M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z"/>
</vector>

View File

@ -0,0 +1,13 @@
<vector
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="@android:color/white"
android:pathData="M17,17l5,-5l-5,-5l-1.41,1.41l2.58,2.59l-9.17,0l0,2l9.17,0l-2.58,2.59z"/>
<path
android:fillColor="@android:color/white"
android:pathData="M19,19H5V5h14v2h2V5c0,-1.1 -0.89,-2 -2,-2H5C3.9,3 3,3.9 3,5v14c0,1.1 0.9,2 2,2h14c1.11,0 2,-0.9 2,-2v-2h-2V19z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="@android:color/white"
android:pathData="M9,6H5V10H7V8H9M19,10H17V12H15V14H19M21,16H3V4H21M21,2H3C1.89,2 1,2.89 1,4V16A2,2 0 0,0 3,18H10V20H8V22H16V20H14V18H21A2,2 0 0,0 23,16V4C23,2.89 22.1,2 21,2"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M20 2H4C2.9 2 2 2.9 2 4V20C2 21.11 2.9 22 4 22H20C21.11 22 22 21.11 22 20V4C22 2.9 21.11 2 20 2M4 6L6 4H10.9L4 10.9V6M4 13.7L13.7 4H18.6L4 18.6V13.7M20 18L18 20H13.1L20 13.1V18M20 10.3L10.3 20H5.4L20 5.4V10.3Z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M10.5,4.5c0.28,0 0.5,0.22 0.5,0.5v2h6v6h2c0.28,0 0.5,0.22 0.5,0.5s-0.22,0.5 -0.5,0.5h-2v6h-2.12c-0.68,-1.75 -2.39,-3 -4.38,-3s-3.7,1.25 -4.38,3H4v-2.12c1.75,-0.68 3,-2.39 3,-4.38 0,-1.99 -1.24,-3.7 -2.99,-4.38L4,7h6V5c0,-0.28 0.22,-0.5 0.5,-0.5m0,-2C9.12,2.5 8,3.62 8,5H4c-1.1,0 -1.99,0.9 -1.99,2v3.8h0.29c1.49,0 2.7,1.21 2.7,2.7s-1.21,2.7 -2.7,2.7H2V20c0,1.1 0.9,2 2,2h3.8v-0.3c0,-1.49 1.21,-2.7 2.7,-2.7s2.7,1.21 2.7,2.7v0.3H17c1.1,0 2,-0.9 2,-2v-4c1.38,0 2.5,-1.12 2.5,-2.5S20.38,11 19,11V7c0,-1.1 -0.9,-2 -2,-2h-4c0,-1.38 -1.12,-2.5 -2.5,-2.5z"/>
</vector>

View File

@ -21,6 +21,7 @@
app:tabTextAppearance="@style/TabTextAppearance"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabUnboundedRipple="false"
app:tabGravity="fill"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@ -0,0 +1,90 @@
<?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:padding="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:id="@+id/title"
android:text="@string/version_manage_duplicate"
android:singleLine="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_bias="0.5"/>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="400dp"
android:layout_height="wrap_content"
android:id="@+id/details"
android:layout_marginTop="10dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title"
android:orientation="vertical">
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
app:auto_linear_background_tint="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/version_manage_duplicate_confirm"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:singleLine="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/version_manage_duplicate_prompt"
android:layout_gravity="center"/>
<com.tungsten.fcllibrary.component.view.FCLEditText
android:layout_marginStart="10dp"
android:singleLine="true"
android:id="@+id/new_name"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<com.tungsten.fcllibrary.component.view.FCLCheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/version_manage_duplicate_duplicate_save"
android:id="@+id/check_save"/>
</androidx.appcompat.widget.LinearLayoutCompat>
<com.tungsten.fcllibrary.component.view.FCLButton
android:layout_marginTop="10dp"
android:id="@+id/positive"
android:text="@string/dialog_positive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/details"/>
<com.tungsten.fcllibrary.component.view.FCLButton
android:layout_marginTop="10dp"
android:id="@+id/negative"
android:text="@string/dialog_negative"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/details"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,7 +1,27 @@
<?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:paddingStart="10dp"
android:paddingEnd="10dp"
android:paddingTop="10dp"
android:background="@color/ui_bg_color"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.tungsten.fcllibrary.component.view.FCLButton
android:id="@+id/install_offline"
android:text="@string/install_installer_install_offline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:ripple="true"
app:layout_constraintTop_toTopOf="parent"/>
<ScrollView
android:id="@+id/scroll"
android:layout_marginTop="10dp"
app:layout_constraintTop_toBottomOf="@+id/install_offline"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="match_parent"
android:layout_height="0dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,543 @@
<?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:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintWidth_percent="0.5"
android:layout_width="0dp"
android:layout_height="match_parent">
<androidx.appcompat.widget.LinearLayoutCompat
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:paddingStart="10dp"
android:paddingEnd="5dp">
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:background="@drawable/bg_container_white"
app:auto_linear_background_tint="true">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_videogame_asset_24"
app:auto_src_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginStart="10dp"
android:text="@string/folder_game"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLImageButton
app:no_padding="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_tint="true"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/browse_game_dir"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:background="@drawable/bg_container_white"
app:auto_linear_background_tint="true">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_outline_extension_24"
app:auto_src_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginStart="10dp"
android:text="@string/folder_mod"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLImageButton
app:no_padding="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_tint="true"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/browse_mods"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:background="@drawable/bg_container_white"
app:auto_linear_background_tint="true">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_settings_24"
app:auto_src_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginStart="10dp"
android:text="@string/folder_config"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLImageButton
app:no_padding="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_tint="true"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/browse_config"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:background="@drawable/bg_container_white"
app:auto_linear_background_tint="true">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_texture_24"
app:auto_src_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginStart="10dp"
android:text="@string/folder_resourcepacks"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLImageButton
app:no_padding="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_tint="true"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/browse_resourcepacks"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:background="@drawable/bg_container_white"
app:auto_linear_background_tint="true">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_screenshot_24"
app:auto_src_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginStart="10dp"
android:text="@string/folder_screenshots"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLImageButton
app:no_padding="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_tint="true"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/browse_screenshots"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:background="@drawable/bg_container_white"
app:auto_linear_background_tint="true">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_earth_24"
app:auto_src_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginStart="10dp"
android:text="@string/folder_saves"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLImageButton
app:no_padding="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_tint="true"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/browse_saves"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
</androidx.appcompat.widget.LinearLayoutCompat>
</ScrollView>
<ScrollView
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintWidth_percent="0.5"
android:layout_width="0dp"
android:layout_height="match_parent">
<androidx.appcompat.widget.LinearLayoutCompat
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:paddingStart="5dp"
android:paddingEnd="10dp">
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:id="@+id/update_layout"
android:layout_marginBottom="10dp"
android:background="@drawable/bg_container_white"
app:auto_linear_background_tint="true">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_update_24"
app:auto_src_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginStart="10dp"
android:text="@string/version_update"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLImageButton
app:no_padding="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_tint="true"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/update"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:background="@drawable/bg_container_white"
app:auto_linear_background_tint="true">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_edit_24"
app:auto_src_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginStart="10dp"
android:text="@string/version_manage_rename"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLImageButton
app:no_padding="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_tint="true"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/rename"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:background="@drawable/bg_container_white"
app:auto_linear_background_tint="true">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_content_copy_24"
app:auto_src_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginStart="10dp"
android:text="@string/version_manage_duplicate"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLImageButton
app:no_padding="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_tint="true"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/duplicate"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:background="@drawable/bg_container_white"
app:auto_linear_background_tint="true">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_output_24"
app:auto_src_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginStart="10dp"
android:text="@string/modpack_export"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLImageButton
app:no_padding="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_tint="true"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/export"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:background="@drawable/bg_container_white"
app:auto_linear_background_tint="true">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_list_24"
app:auto_src_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginStart="10dp"
android:text="@string/version_manage_redownload_assets_index"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLImageButton
app:no_padding="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_tint="true"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/update_assets"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:background="@drawable/bg_container_white"
app:auto_linear_background_tint="true">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_delete_24"
app:auto_src_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginStart="10dp"
android:text="@string/version_manage_remove_libraries"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLImageButton
app:no_padding="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_tint="true"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/delete_libs"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp"
android:background="@drawable/bg_container_white"
app:auto_linear_background_tint="true">
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_delete_24"
app:auto_src_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginStart="10dp"
android:text="@string/version_manage_clean"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLImageButton
app:no_padding="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_tint="true"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/delete_logs"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
</androidx.appcompat.widget.LinearLayoutCompat>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -19,6 +19,7 @@
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="10dp"
app:tabUnboundedRipple="false"
app:tabGravity="fill"
app:follow_theme="true"
app:tabTextAppearance="@style/TabTextAppearance"

View File

@ -19,11 +19,17 @@
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="10dp"
app:tabUnboundedRipple="false"
app:tabGravity="fill"
app:follow_theme="true"
app:tabTextAppearance="@style/TabTextAppearance"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/manage"/>
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="match_parent"

View File

@ -82,12 +82,20 @@
<string name="assets_index_malformed">资源文件的索引文件损坏。</string>
<string name="download_code_404">远程服务器不包含需要下载的文件: %s</string>
<string name="download_failed">下载失败: %1$s错误码%2$d</string>
<string name="download_failed_empty">没有可供选择的版本</string>
<string name="exception_access_denied">无法获取文件 %s。</string>
<string name="exception_artifact_malformed">无法校验文件。</string>
<string name="exception_ssl_handshake">缺少 SSL 证书。</string>
<string name="folder_config">浏览配置文件夹</string>
<string name="folder_game">浏览游戏文件夹</string>
<string name="folder_mod">浏览模组文件夹</string>
<string name="folder_resourcepacks">浏览资源包文件夹</string>
<string name="folder_saves">浏览存档文件夹</string>
<string name="folder_screenshots">浏览截屏文件夹</string>
<string name="input_not_empty">请先填写必要的输入框。</string>
<string name="install_change_version">更改版本</string>
@ -137,6 +145,7 @@
<string name="mods_manage">模组管理</string>
<string name="modpack">整合包</string>
<string name="modpack_export">导出整合包</string>
<string name="profile_shared">公有目录</string>
<string name="profile_private">私有目录</string>
@ -160,12 +169,21 @@
<string name="version_launch">启动游戏</string>
<string name="version_no_version">没有版本</string>
<string name="version_manage">点击管理</string>
<string name="version_manage_clean">清理游戏目录</string>
<string name="version_manage_duplicate">复制游戏实例</string>
<string name="version_manage_duplicate_duplicate_save">复制存档</string>
<string name="version_manage_duplicate_prompt">实例名称</string>
<string name="version_manage_duplicate_confirm">将锁定复制产生的新游戏实例:开启版本隔离、游戏设置并复制该版本产生的文件。</string>
<string name="version_manage_redownload_assets_index">更新资源文件</string>
<string name="version_manage_remove_confirm">你确定要删除 %s 吗? 该操作无法撤回!</string>
<string name="version_manage_remove_confirm_independent">该版本启用了版本隔离,删除该版本将会一并删除存档及其他数据。你仍要删除 %s 吗?</string>
<string name="version_manage_remove_libraries">删除所有库文件</string>
<string name="version_manage_rename">重命名版本</string>
<string name="version_manage_rename_message">重命名版本</string>
<string name="version_manage_rename_new">新名称</string>
<string name="version_manage_rename_fail">重命名失败</string>
<string name="version_new_profile">新建目录</string>
<string name="version_update">更新整合包</string>
<string name="world">世界</string>
<string name="world_manage">世界 / 数据包</string>

View File

@ -93,12 +93,20 @@
<string name="assets_index_malformed">Index files of downloaded assets were corrupted.</string>
<string name="download_code_404">File not found on the remote server: %s</string>
<string name="download_failed">Failed to download %1$s, response code: %2$d</string>
<string name="download_failed_empty">No versions are available</string>
<string name="exception_access_denied">Unable to access the file %s.</string>
<string name="exception_artifact_malformed">Cannot verify the integrity of the downloaded files.</string>
<string name="exception_ssl_handshake">Unable to establish SSL connection due to missing SSL certificates in current Java installation.</string>
<string name="folder_config">Browse configs</string>
<string name="folder_game">Browse game directory</string>
<string name="folder_mod">Browse mods</string>
<string name="folder_resourcepacks">Browse resource packs</string>
<string name="folder_saves">Browse saves</string>
<string name="folder_screenshots">Browse screenshots</string>
<string name="input_not_empty">Fill the required input box first.</string>
<string name="install_change_version">Change Version</string>
@ -156,6 +164,7 @@
<string name="mods_manage">Manage Mods</string>
<string name="modpack">Modpack</string>
<string name="modpack_export">Export Modpack</string>
<string name="profile_shared">Shared Directory</string>
<string name="profile_private">Private Directory</string>
@ -179,12 +188,21 @@
<string name="version_launch">Launch Game</string>
<string name="version_no_version">No version</string>
<string name="version_manage">Click to manage</string>
<string name="version_manage_clean">Delete Log Files</string>
<string name="version_manage_duplicate">Duplicate Instance</string>
<string name="version_manage_duplicate_duplicate_save">Duplicate Save</string>
<string name="version_manage_duplicate_prompt">Instance name</string>
<string name="version_manage_duplicate_confirm">The duplicated instance will have a copy of all the files of this instance, with an isolated game directory and settings.</string>
<string name="version_manage_redownload_assets_index">Update Game Assets</string>
<string name="version_manage_remove_confirm">Are you sure you want to permanently remove the version %s? This action cannot be undone!</string>
<string name="version_manage_remove_confirm_independent">Since this instance is stored in an isolated directory, deleting it will also delete its saves and other data. Do you still want to delete instance %s?</string>
<string name="version_manage_remove_libraries">Delete All Libraries</string>
<string name="version_manage_rename">Rename Instance</string>
<string name="version_manage_rename_message">Rename version</string>
<string name="version_manage_rename_new">New name</string>
<string name="version_manage_rename_fail">Rename failed</string>
<string name="version_new_profile">New Directory</string>
<string name="version_update">Update Modpack</string>
<string name="world">Worlds</string>
<string name="world_manage">Worlds / Datapacks</string>

View File

@ -119,8 +119,7 @@ public class FileBrowserActivity extends FCLActivity implements View.OnClickList
public void onSelect(FileBrowserAdapter adapter1, String path) {
if (selectedFiles.stream().anyMatch(s -> s.equals(path))) {
selectedFiles.remove(path);
}
else {
} else {
if (fileBrowser.getSelectionMode() == SelectionMode.SINGLE_SELECTION) {
selectedFiles = new ArrayList<>();
}
@ -139,8 +138,7 @@ public class FileBrowserActivity extends FCLActivity implements View.OnClickList
public void onBackPressed() {
if (currentPath.getParent() != null && !currentPath.toString().equals(Environment.getExternalStorageDirectory().getAbsolutePath())) {
refreshList(currentPath.getParent());
}
else {
} else {
setResult(Activity.RESULT_CANCELED);
finish();
}
@ -151,8 +149,7 @@ public class FileBrowserActivity extends FCLActivity implements View.OnClickList
if (view == back) {
if (currentPath.getParent() != null && !currentPath.toString().equals(Environment.getExternalStorageDirectory().getAbsolutePath())) {
refreshList(currentPath.getParent());
}
else {
} else {
setResult(Activity.RESULT_CANCELED);
finish();
}
@ -167,16 +164,14 @@ public class FileBrowserActivity extends FCLActivity implements View.OnClickList
if (view == privateDir) {
if (getExternalCacheDir().getParent() != null) {
refreshList(new File(getExternalCacheDir().getParent()).toPath());
}
else {
} else {
Toast.makeText(this, getString(R.string.file_browser_private_alert), Toast.LENGTH_SHORT).show();
}
}
if (view == confirm) {
if (selectedFiles.size() == 0 && fileBrowser.getLibMode() != LibMode.FILE_BROWSER) {
Toast.makeText(this, getString(R.string.file_browser_positive_alert), Toast.LENGTH_SHORT).show();
}
else {
} else {
Intent intent = new Intent();
intent.putParcelableArrayListExtra(FileBrowser.SELECTED_FILES, (ArrayList<? extends Parcelable>) selectedFiles.stream().map(Uri::parse).collect(Collectors.toList()));
setResult(Activity.RESULT_OK, intent);

View File

@ -134,7 +134,7 @@ public class FileBrowserAdapter extends FCLAdapter {
if (file.isDirectory()) {
listener.onEnterDir(file.getAbsolutePath());
}
if (fileBrowser.getLibMode() != LibMode.FILE_BROWSER && fileBrowser.getLibMode() != LibMode.FOLDER_CHOOSER && !(fileBrowser.getLibMode() == LibMode.FILE_CHOOSER)) {
if (fileBrowser.getLibMode() != LibMode.FILE_BROWSER && fileBrowser.getLibMode() != LibMode.FOLDER_CHOOSER && file.isFile()) {
listener.onSelect(this, file.getAbsolutePath());
}
});

View File

@ -26,6 +26,7 @@ public class FCLImageButton extends AppCompatImageButton {
private ObjectProperty<Drawable> image;
private boolean autoTint;
private boolean noPadding;
private BooleanProperty visibilityProperty;
private final IntegerProperty theme = new IntegerPropertyBase() {
@ -48,7 +49,7 @@ public class FCLImageButton extends AppCompatImageButton {
setImageTintList(new ColorStateList(state, colorSrc));
}
RippleDrawable drawable = new RippleDrawable(new ColorStateList(state, colorRipple), null, null);
drawable.setRadius(ConvertUtils.dip2px(getContext(), 20));
drawable.setRadius(ConvertUtils.dip2px(getContext(), noPadding ? 12 : 20));
setBackgroundDrawable(drawable);
}
@ -64,12 +65,16 @@ public class FCLImageButton extends AppCompatImageButton {
};
private void init() {
if (!noPadding) {
setPadding(
ConvertUtils.dip2px(getContext(), 8f),
ConvertUtils.dip2px(getContext(), 8f),
ConvertUtils.dip2px(getContext(), 8f),
ConvertUtils.dip2px(getContext(), 8f)
);
} else {
setPadding(0, 0, 0, 0);
}
setScaleType(ScaleType.FIT_XY);
}
@ -83,6 +88,7 @@ public class FCLImageButton extends AppCompatImageButton {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.FCLImageButton);
autoTint = typedArray.getBoolean(R.styleable.FCLImageButton_auto_tint, false);
noPadding = typedArray.getBoolean(R.styleable.FCLImageButton_no_padding, false);
typedArray.recycle();
init();
theme.bind(ThemeEngine.getInstance().getTheme().colorProperty());
@ -92,6 +98,7 @@ public class FCLImageButton extends AppCompatImageButton {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.FCLImageButton);
autoTint = typedArray.getBoolean(R.styleable.FCLImageButton_auto_tint, false);
noPadding = typedArray.getBoolean(R.styleable.FCLImageButton_no_padding, false);
typedArray.recycle();
init();
theme.bind(ThemeEngine.getInstance().getTheme().colorProperty());
@ -105,6 +112,14 @@ public class FCLImageButton extends AppCompatImageButton {
return autoTint;
}
public void setNoPadding(boolean noPadding) {
this.noPadding = noPadding;
}
public boolean isNoPadding() {
return noPadding;
}
public final void setImage(Drawable drawable) {
imageProperty().set(drawable);
}

View File

@ -7,6 +7,7 @@
</declare-styleable>
<declare-styleable name="FCLImageButton">
<attr name="auto_tint" format="boolean"/>
<attr name="no_padding" format="boolean"/>
</declare-styleable>
<declare-styleable name="FCLImageView">
<attr name="auto_src_tint" format="boolean"/>

View File

@ -148,8 +148,13 @@ public class FCLauncher {
envMap.put("LIBGL_NORMALIZE", "1");
envMap.put("LIBGL_VSYNC", "1");
envMap.put("LIBGL_NOINTOVLHACK", "1");
}
else {
} else if (renderer == FCLConfig.Renderer.RENDERER_ANGLE) {
envMap.put("LIBGL_ES","3");
envMap.put("LIBGL_MIPMAP", "3");
envMap.put("LIBGL_NORMALIZE", "1");
envMap.put("LIBGL_VSYNC", "1");
envMap.put("LIBGL_NOINTOVLHACK", "1");
} else {
envMap.put("LIBGL_DRIVERS_PATH", nativeDir);
envMap.put("MESA_GL_VERSION_OVERRIDE", "4.6");
envMap.put("MESA_GLSL_VERSION_OVERRIDE", "460");

View File

@ -301,7 +301,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
EGLConfig config=malloc(sizeof(EGLConfig));
EGLConfig config = malloc(sizeof(EGLConfig));
EGLContext share = NULL;
if (!_glfw.egl.display)