update fcl lib && export modpack page

This commit is contained in:
Tungstend 2023-07-09 20:24:27 +08:00
parent d4695e8205
commit f01f904cb0
28 changed files with 1842 additions and 48 deletions

View File

@ -18,7 +18,7 @@ import com.tungsten.fcl.util.RuntimeUtils;
import com.tungsten.fclauncher.FCLPath;
import com.tungsten.fclcore.util.io.FileUtils;
import com.tungsten.fcllibrary.component.FCLFragment;
import com.tungsten.fcllibrary.component.LocaleUtils;
import com.tungsten.fcllibrary.util.LocaleUtils;
import com.tungsten.fcllibrary.component.view.FCLButton;
import com.tungsten.fcllibrary.component.view.FCLImageView;

View File

@ -13,7 +13,7 @@ import com.tungsten.fclcore.game.Version;
import com.tungsten.fclcore.launch.DefaultLauncher;
import com.tungsten.fclcore.util.Logging;
import com.tungsten.fclcore.util.io.FileUtils;
import com.tungsten.fcllibrary.component.LocaleUtils;
import com.tungsten.fcllibrary.util.LocaleUtils;
import java.io.BufferedReader;
import java.io.File;

View File

@ -9,7 +9,7 @@ import com.tungsten.fcl.R;
import com.tungsten.fcl.util.ModTranslations;
import com.tungsten.fclcore.mod.RemoteMod;
import com.tungsten.fcllibrary.component.FCLAdapter;
import com.tungsten.fcllibrary.component.LocaleUtils;
import com.tungsten.fcllibrary.util.LocaleUtils;
import com.tungsten.fcllibrary.component.theme.ThemeEngine;
import com.tungsten.fcllibrary.component.view.FCLLinearLayout;
import com.tungsten.fcllibrary.component.view.FCLTextView;

View File

@ -21,7 +21,7 @@ import com.tungsten.fclcore.task.Task;
import com.tungsten.fclcore.util.SimpleMultimap;
import com.tungsten.fclcore.util.StringUtils;
import com.tungsten.fclcore.util.versioning.VersionNumber;
import com.tungsten.fcllibrary.component.LocaleUtils;
import com.tungsten.fcllibrary.util.LocaleUtils;
import com.tungsten.fcllibrary.component.theme.ThemeEngine;
import com.tungsten.fcllibrary.component.ui.FCLTempPage;
import com.tungsten.fcllibrary.component.view.FCLImageButton;

View File

@ -13,7 +13,7 @@ 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.LocaleUtils;
import com.tungsten.fcllibrary.util.LocaleUtils;
import com.tungsten.fcllibrary.component.view.FCLImageView;
import com.tungsten.fcllibrary.component.view.FCLLinearLayout;
import com.tungsten.fcllibrary.component.view.FCLTextView;

View File

@ -123,7 +123,7 @@ public class ManagePage extends FCLCommonPage implements ManageUI.VersionLoadabl
}
private void export() {
Versions.exportVersion(getProfile(), getVersion());
Versions.exportVersion(getContext(), getParent(), getProfile(), getVersion());
}
private void rename() {

View File

@ -0,0 +1,196 @@
package com.tungsten.fcl.ui.manage;
import static com.tungsten.fclcore.util.Lang.mapOf;
import static com.tungsten.fclcore.util.Pair.pair;
import android.content.Context;
import android.content.res.ColorStateList;
import android.view.View;
import android.widget.ListView;
import com.tungsten.fcl.R;
import com.tungsten.fcl.setting.Profile;
import com.tungsten.fclcore.fakefx.collections.FXCollections;
import com.tungsten.fclcore.fakefx.collections.ObservableList;
import com.tungsten.fclcore.mod.ModAdviser;
import com.tungsten.fclcore.mod.ModpackExportInfo;
import com.tungsten.fclcore.task.Schedulers;
import com.tungsten.fclcore.task.Task;
import com.tungsten.fclcore.util.StringUtils;
import com.tungsten.fclcore.util.io.FileUtils;
import com.tungsten.fcllibrary.component.FCLCheckBoxTreeAdapter;
import com.tungsten.fcllibrary.component.FCLCheckBoxTreeItem;
import com.tungsten.fcllibrary.component.theme.ThemeEngine;
import com.tungsten.fcllibrary.component.ui.FCLTempPage;
import com.tungsten.fcllibrary.component.view.FCLButton;
import com.tungsten.fcllibrary.component.view.FCLProgressBar;
import com.tungsten.fcllibrary.component.view.FCLUILayout;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class ModpackFileSelectionPage extends FCLTempPage implements View.OnClickListener {
private final Profile profile;
private final String version;
private final String type;
private final ModpackExportInfo.Options options;
private final ModAdviser adviser;
private final ModpackExportInfo exportInfo;
private final File file;
private FCLCheckBoxTreeItem<String> rootItem;
private FCLProgressBar progressBar;
private ListView listView;
private FCLButton next;
public ModpackFileSelectionPage(Context context, int id, FCLUILayout parent, int resId, Profile profile, String version, String type, ModpackExportInfo.Options options, ModAdviser adviser, ModpackExportInfo exportInfo, File file) {
super(context, id, parent, resId);
this.profile = profile;
this.version = version;
this.type = type;
this.options = options;
this.adviser = adviser;
this.exportInfo = exportInfo;
this.file = file;
}
@Override
public void onCreate() {
super.onCreate();
progressBar = findViewById(R.id.progress);
listView = findViewById(R.id.list);
ThemeEngine.getInstance().registerEvent(listView, () -> listView.setBackgroundTintList(new ColorStateList(new int[][] { { } }, new int[] { ThemeEngine.getInstance().getTheme().getLtColor() })));
next = findViewById(R.id.next);
next.setOnClickListener(this);
}
@Override
public void onStart() {
super.onStart();
progressBar.setVisibility(View.VISIBLE);
listView.setVisibility(View.GONE);
next.setVisibility(View.GONE);
new Thread(() -> {
this.rootItem = getTreeItem(profile.getRepository().getRunDirectory(version), "minecraft");
Schedulers.androidUIThread().execute(() -> {
progressBar.setVisibility(View.GONE);
listView.setVisibility(View.VISIBLE);
next.setVisibility(View.VISIBLE);
ObservableList<FCLCheckBoxTreeItem<String>> list = FXCollections.observableArrayList();
list.add(rootItem);
FCLCheckBoxTreeAdapter<String> adapter = new FCLCheckBoxTreeAdapter<>(getContext(), list);
listView.setAdapter(adapter);
});
}).start();
}
private void finish() {
ArrayList<String> list = new ArrayList<>();
getFilesNeeded(rootItem, "minecraft", list);
}
private FCLCheckBoxTreeItem<String> getTreeItem(File file, String basePath) {
if (!file.exists())
return null;
ModAdviser.ModSuggestion state = ModAdviser.ModSuggestion.SUGGESTED;
if (basePath.length() > "minecraft/".length()) {
state = adviser.advise(StringUtils.substringAfter(basePath, "minecraft/") + (file.isDirectory() ? "/" : ""), file.isDirectory());
if (file.isFile() && Objects.equals(FileUtils.getNameWithoutExtension(file), version)) // Ignore <version>.json, <version>.jar
state = ModAdviser.ModSuggestion.HIDDEN;
if (file.isDirectory() && Objects.equals(file.getName(), version + "-natives")) // Ignore <version>-natives
state = ModAdviser.ModSuggestion.HIDDEN;
if (state == ModAdviser.ModSuggestion.HIDDEN)
return null;
}
ObservableList<FCLCheckBoxTreeItem<String>> list = FXCollections.observableArrayList();
FCLCheckBoxTreeItem<String> item = new FCLCheckBoxTreeItem<>(StringUtils.substringAfterLast(basePath, "/"), null, list);
if (state == ModAdviser.ModSuggestion.SUGGESTED)
item.setSelected(true);
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null) {
for (File it : files) {
FCLCheckBoxTreeItem<String> subItem = getTreeItem(it, basePath + "/" + it.getName());
if (subItem != null) {
item.setSelected(subItem.isSelected() || item.isSelected());
if (!subItem.isSelected()) {
item.setIndeterminate(true);
}
subItem.selectedProperty().addListener(observable -> item.checkProperty());
subItem.indeterminateProperty().addListener(observable -> item.checkProperty());
item.getSubItem().add(subItem);
}
}
}
if (!item.isSelected()) item.setIndeterminate(false);
// Empty folder need not to be displayed.
if (item.getSubItem().size() == 0) {
return null;
}
}
if (TRANSLATION.containsKey(basePath)) {
item.setComment(TRANSLATION.get(basePath));
}
item.setExpanded("minecraft".equals(basePath));
return item;
}
private void getFilesNeeded(FCLCheckBoxTreeItem<String> item, String basePath, List<String> list) {
if (item == null) return;
if (item.isSelected() || item.isIndeterminate()) {
if (basePath.length() > "minecraft/".length())
list.add(StringUtils.substringAfter(basePath, "minecraft/"));
item.getSubItem().forEach(it -> getFilesNeeded(it, basePath + "/" + it.getData(), list));
}
}
@Override
public Task<?> refresh(Object... param) {
return null;
}
@Override
public void onRestart() {
}
@Override
public void onClick(View v) {
if (v == next) {
finish();
}
}
private final Map<String, String> TRANSLATION = mapOf(
pair("minecraft/fclversion.cfg", getContext().getString(R.string.modpack_files_fclversion_cfg)),
pair("minecraft/servers.dat", getContext().getString(R.string.modpack_files_servers_dat)),
pair("minecraft/saves", getContext().getString(R.string.modpack_files_saves)),
pair("minecraft/mods", getContext().getString(R.string.modpack_files_mods)),
pair("minecraft/config", getContext().getString(R.string.modpack_files_config)),
pair("minecraft/liteconfig", getContext().getString(R.string.modpack_files_liteconfig)),
pair("minecraft/resourcepacks", getContext().getString(R.string.modpack_files_resourcepacks)),
pair("minecraft/resources", getContext().getString(R.string.modpack_files_resourcepacks)),
pair("minecraft/options.txt", getContext().getString(R.string.modpack_files_options_txt)),
pair("minecraft/optionsshaders.txt", getContext().getString(R.string.modpack_files_optionsshaders_txt)),
pair("minecraft/mods/VoxelMods", getContext().getString(R.string.modpack_files_mods_voxelmods)),
pair("minecraft/dumps", getContext().getString(R.string.modpack_files_dumps)),
pair("minecraft/blueprints", getContext().getString(R.string.modpack_files_blueprints)),
pair("minecraft/scripts", getContext().getString(R.string.modpack_files_scripts))
);
}

View File

@ -0,0 +1,280 @@
package com.tungsten.fcl.ui.manage;
import static com.tungsten.fcl.setting.ConfigHolder.config;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import com.tungsten.fcl.R;
import com.tungsten.fcl.setting.Accounts;
import com.tungsten.fcl.setting.Profile;
import com.tungsten.fcl.setting.VersionSetting;
import com.tungsten.fcl.ui.PageManager;
import com.tungsten.fcl.util.FXUtils;
import com.tungsten.fcl.util.RequestCodes;
import com.tungsten.fclcore.auth.Account;
import com.tungsten.fclcore.auth.authlibinjector.AuthlibInjectorServer;
import com.tungsten.fclcore.fakefx.beans.binding.Bindings;
import com.tungsten.fclcore.fakefx.beans.property.SimpleBooleanProperty;
import com.tungsten.fclcore.fakefx.beans.property.SimpleIntegerProperty;
import com.tungsten.fclcore.fakefx.beans.property.SimpleStringProperty;
import com.tungsten.fclcore.mod.ModAdviser;
import com.tungsten.fclcore.mod.ModpackExportInfo;
import com.tungsten.fclcore.mod.mcbbs.McbbsModpackManifest;
import com.tungsten.fclcore.task.Task;
import com.tungsten.fclcore.util.Lang;
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;
import com.tungsten.fcllibrary.browser.options.SelectionMode;
import com.tungsten.fcllibrary.component.ui.FCLTempPage;
import com.tungsten.fcllibrary.component.view.FCLButton;
import com.tungsten.fcllibrary.component.view.FCLEditText;
import com.tungsten.fcllibrary.component.view.FCLImageButton;
import com.tungsten.fcllibrary.component.view.FCLLinearLayout;
import com.tungsten.fcllibrary.component.view.FCLSeekBar;
import com.tungsten.fcllibrary.component.view.FCLSpinner;
import com.tungsten.fcllibrary.component.view.FCLSwitch;
import com.tungsten.fcllibrary.component.view.FCLTextView;
import com.tungsten.fcllibrary.component.view.FCLUILayout;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
public class ModpackInfoPage extends FCLTempPage implements View.OnClickListener {
private final Profile profile;
private final String versionName;
private final String type;
private final ModpackExportInfo.Options options;
private final ModpackExportInfo exportInfo = new ModpackExportInfo();
private final SimpleStringProperty path = new SimpleStringProperty("");
private final SimpleStringProperty fileName = new SimpleStringProperty("");
private final SimpleStringProperty name = new SimpleStringProperty("");
private final SimpleStringProperty author = new SimpleStringProperty("");
private final SimpleStringProperty version = new SimpleStringProperty("1.0");
private final SimpleStringProperty description = new SimpleStringProperty("");
private final SimpleStringProperty url = new SimpleStringProperty("");
private final SimpleBooleanProperty forceUpdate = new SimpleBooleanProperty();
private final SimpleStringProperty fileApi = new SimpleStringProperty("");
private final SimpleIntegerProperty minMemory = new SimpleIntegerProperty(0);
private final SimpleStringProperty authlibInjectorServer = new SimpleStringProperty();
private final SimpleStringProperty launchArguments = new SimpleStringProperty("");
private final SimpleStringProperty javaArguments = new SimpleStringProperty("");
private final SimpleStringProperty mcbbsThreadId = new SimpleStringProperty("");
private FCLImageButton pathButton;
private FCLButton next;
public ModpackInfoPage(Context context, int id, FCLUILayout parent, int resId, Profile profile, String version, String type, ModpackExportInfo.Options options) {
super(context, id, parent, resId);
this.profile = profile;
this.versionName = version;
this.type = type;
this.options = options;
name.set(version);
author.set(Optional.ofNullable(Accounts.getSelectedAccount()).map(Account::getUsername).orElse(""));
VersionSetting versionSetting = profile.getRepository().getVersionSetting(versionName);
minMemory.set(Optional.ofNullable(versionSetting.getMinMemory()).orElse(0));
launchArguments.set(versionSetting.getMinecraftArgs());
javaArguments.set(versionSetting.getJavaArgs());
}
@Override
public void onStart() {
super.onStart();
FCLLinearLayout fileApiLayout = findViewById(R.id.file_api_layout);
FCLLinearLayout launchArgsLayout = findViewById(R.id.minecraft_args_layout);
FCLLinearLayout jvmArgsLayout = findViewById(R.id.jvm_args_layout);
FCLLinearLayout originUrlLayout = findViewById(R.id.origin_url_layout);
FCLLinearLayout mcbbsLayout = findViewById(R.id.mcbbs_layout);
FCLLinearLayout memoryLayout = findViewById(R.id.memory_layout);
FCLLinearLayout serverLayout = findViewById(R.id.server_layout);
FCLLinearLayout forceUpdateLayout = findViewById(R.id.force_update_layout);
View splitF = findViewById(R.id.split_1);
View splitS = findViewById(R.id.split_2);
View splitT = findViewById(R.id.split_3);
FCLTextView versionNameText = findViewById(R.id.game_version);
FCLEditText nameText = findViewById(R.id.name);
FCLEditText authorText = findViewById(R.id.author);
FCLEditText versionText = findViewById(R.id.version);
FCLEditText fileApiText = findViewById(R.id.file_api);
FCLEditText launchArgsText = findViewById(R.id.minecraft_args);
FCLEditText jvmArgsText = findViewById(R.id.jvm_args);
FCLEditText originUrlText = findViewById(R.id.origin_url);
FCLEditText mcbbsText = findViewById(R.id.mcbbs);
FCLSeekBar memorySeekbar = findViewById(R.id.memory);
FCLTextView memoryText = findViewById(R.id.memory_text);
FCLEditText descText = findViewById(R.id.desc);
FCLSpinner<String> serverSpinner = findViewById(R.id.server);
FCLSwitch forceUpdateSwitch = findViewById(R.id.force_update);
FCLTextView pathText = findViewById(R.id.path_text);
pathButton = findViewById(R.id.path);
FCLEditText fileNameText = findViewById(R.id.file_name);
next = findViewById(R.id.next);
versionNameText.setText(versionName);
nameText.setText(name.get());
nameText.stringProperty().bindBidirectional(name);
authorText.setText(author.get());
authorText.stringProperty().bindBidirectional(author);
versionText.setText(version.get());
versionText.stringProperty().bindBidirectional(version);
if (options.isRequireFileApi()) {
if (options.isValidateFileApi()) {
fileApiText.setHint(getContext().getString(R.string.input_hint_not_empty));
} else {
fileApiText.setHint("");
}
fileApiText.stringProperty().bindBidirectional(fileApi);
}
fileApiLayout.setVisibility(options.isRequireFileApi() ? View.VISIBLE : View.GONE);
if (options.isRequireLaunchArguments()) {
launchArgsText.setText(launchArguments.get());
launchArgsText.stringProperty().bindBidirectional(launchArguments);
}
launchArgsLayout.setVisibility(options.isRequireLaunchArguments() ? View.VISIBLE : View.GONE);
if (options.isRequireJavaArguments()) {
jvmArgsText.setText(javaArguments.get());
jvmArgsText.stringProperty().bindBidirectional(javaArguments);
}
jvmArgsLayout.setVisibility(options.isRequireJavaArguments() ? View.VISIBLE : View.GONE);
if (options.isRequireUrl()) {
originUrlText.stringProperty().bindBidirectional(url);
}
originUrlLayout.setVisibility(options.isRequireUrl() ? View.VISIBLE : View.GONE);
if (options.isRequireOrigins()) {
mcbbsText.stringProperty().bindBidirectional(mcbbsThreadId);
}
mcbbsLayout.setVisibility(options.isRequireOrigins() ? View.VISIBLE : View.GONE);
if (options.isRequireMinMemory()) {
memorySeekbar.setProgress(minMemory.get());
memorySeekbar.addProgressListener();
memorySeekbar.progressProperty().bindBidirectional(minMemory);
memoryText.stringProperty().bind(Bindings.createStringBinding(() -> minMemory.get() + " MB", minMemory));
}
memoryLayout.setVisibility(options.isRequireMinMemory() ? View.VISIBLE : View.GONE);
splitF.setVisibility(options.isRequireMinMemory() ? View.VISIBLE : View.GONE);
descText.stringProperty().bindBidirectional(description);
if (options.isRequireAuthlibInjectorServer()) {
ArrayList<String> list = (ArrayList<String>) config().getAuthlibInjectorServers().stream().map(AuthlibInjectorServer::getName).collect(Collectors.toList());
Map<String, String> map = new HashMap<>();
list.add(0, "");
map.put("", null);
config().getAuthlibInjectorServers().forEach(it -> map.put(it.getName(), it.getUrl()));
serverSpinner.setDataList(list);
ArrayAdapter<String> adapter = new ArrayAdapter<>(getContext(), R.layout.item_spinner, list);
adapter.setDropDownViewResource(R.layout.item_spinner_dropdown);
serverSpinner.setAdapter(adapter);
SimpleStringProperty serverName = new SimpleStringProperty("");
FXUtils.bindSelection(serverSpinner, serverName);
serverName.addListener(observable -> authlibInjectorServer.set(map.get(serverName.get())));
}
serverLayout.setVisibility(options.isRequireAuthlibInjectorServer() ? View.VISIBLE : View.GONE);
splitS.setVisibility(options.isRequireAuthlibInjectorServer() ? View.VISIBLE : View.GONE);
if (options.isRequireForceUpdate()) {
forceUpdateSwitch.addCheckedChangeListener();
forceUpdateSwitch.checkProperty().bindBidirectional(forceUpdate);
}
forceUpdateLayout.setVisibility(options.isRequireForceUpdate() ? View.VISIBLE : View.GONE);
splitT.setVisibility(options.isRequireForceUpdate() ? View.VISIBLE : View.GONE);
pathText.stringProperty().bind(path);
pathButton.setOnClickListener(this);
fileNameText.stringProperty().bindBidirectional(fileName);
next.setOnClickListener(this);
}
@Override
public Task<?> refresh(Object... param) {
return null;
}
@Override
public void onRestart() {
}
private void selectPath() {
FileBrowser.Builder builder = new FileBrowser.Builder(getContext());
builder.setLibMode(LibMode.FOLDER_CHOOSER);
builder.setSelectionMode(SelectionMode.SINGLE_SELECTION);
builder.create().browse(getActivity(), RequestCodes.SELECT_EXPORT_FOLDER_CODE, ((requestCode, resultCode, data) -> {
if (requestCode == RequestCodes.SELECT_EXPORT_FOLDER_CODE && resultCode == Activity.RESULT_OK && data != null) {
String p = FileBrowser.getSelectedFiles(data).get(0);
path.set(p);
}
}));
}
@Override
public void onClick(View v) {
if (v == pathButton) {
selectPath();
}
if (v == next) {
boolean urlValid = false;
if (StringUtils.isNotBlank(fileApi.get())) {
try {
new URL(fileApi.get()).toURI();
urlValid = true;
} catch (IOException | URISyntaxException ignored) {
}
}
if (StringUtils.isBlank(name.get()) || StringUtils.isBlank(author.get()) || StringUtils.isBlank(version.get()) || StringUtils.isBlank(fileName.get())
|| (options.isRequireFileApi() && options.isValidateFileApi() && StringUtils.isBlank(fileApi.get()))) {
Toast.makeText(getContext(), getContext().getString(R.string.input_not_empty), Toast.LENGTH_SHORT).show();
} else if (options.isRequireFileApi() && StringUtils.isNotBlank(fileApi.get()) && !urlValid) {
Toast.makeText(getContext(), getContext().getString(R.string.input_url), Toast.LENGTH_SHORT).show();
} else if (options.isRequireOrigins() && StringUtils.isNotBlank(mcbbsThreadId.get()) && Lang.toIntOrNull(mcbbsThreadId.get()) == null) {
Toast.makeText(getContext(), getContext().getString(R.string.input_number), Toast.LENGTH_SHORT).show();
} else if (!OperatingSystem.isNameValid(fileName.get())) {
Toast.makeText(getContext(), getContext().getString(R.string.install_new_game_malformed), Toast.LENGTH_SHORT).show();
} else if (StringUtils.isBlank(path.get())) {
selectPath();
} else {
File file = new File(path.get(), fileName.get() + ".zip");
exportInfo.setName(name.get());
exportInfo.setFileApi(fileApi.get());
exportInfo.setVersion(version.get());
exportInfo.setAuthor(author.get());
exportInfo.setDescription(description.get());
exportInfo.setPackWithLauncher(false);
exportInfo.setUrl(url.get());
exportInfo.setForceUpdate(forceUpdate.get());
exportInfo.setMinMemory(minMemory.get());
exportInfo.setLaunchArguments(launchArguments.get());
exportInfo.setJavaArguments(javaArguments.get());
exportInfo.setAuthlibInjectorServer(authlibInjectorServer.get());
if (StringUtils.isNotBlank(mcbbsThreadId.get())) {
exportInfo.setOrigins(Collections.singletonList(new McbbsModpackManifest.Origin(
"mcbbs", Integer.parseInt(mcbbsThreadId.get())
)));
}
ModpackFileSelectionPage page = new ModpackFileSelectionPage(getContext(), PageManager.PAGE_ID_TEMP, getParent(), R.layout.page_modpack_file, profile, versionName, type, options, ModAdviser::suggestMod, exportInfo, file);
ManagePageManager.getInstance().showTempPage(page);
}
}
}
}

View File

@ -0,0 +1,77 @@
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.PageManager;
import com.tungsten.fclcore.mod.ModpackExportInfo;
import com.tungsten.fclcore.mod.mcbbs.McbbsModpackExportTask;
import com.tungsten.fclcore.mod.multimc.MultiMCModpackExportTask;
import com.tungsten.fclcore.mod.server.ServerModpackExportTask;
import com.tungsten.fclcore.task.Task;
import com.tungsten.fcllibrary.component.ui.FCLTempPage;
import com.tungsten.fcllibrary.component.view.FCLLinearLayout;
import com.tungsten.fcllibrary.component.view.FCLUILayout;
public class ModpackTypeSelectionPage extends FCLTempPage implements View.OnClickListener {
private final Profile profile;
private final String version;
private FCLLinearLayout mcbbs;
private FCLLinearLayout multimc;
private FCLLinearLayout server;
public ModpackTypeSelectionPage(Context context, int id, FCLUILayout parent, int resId, Profile profile, String version) {
super(context, id, parent, resId);
this.profile = profile;
this.version = version;
}
@Override
public void onCreate() {
super.onCreate();
mcbbs = findViewById(R.id.mcbbs);
multimc = findViewById(R.id.multimc);
server = findViewById(R.id.server);
mcbbs.setOnClickListener(this);
multimc.setOnClickListener(this);
server.setOnClickListener(this);
}
@Override
public Task<?> refresh(Object... param) {
return null;
}
@Override
public void onRestart() {
}
@Override
public void onClick(View v) {
String type = null;
ModpackExportInfo.Options options = null;
if (v == mcbbs) {
type = MODPACK_TYPE_MCBBS;
options = McbbsModpackExportTask.OPTION;
}
if (v == multimc) {
type = MODPACK_TYPE_MULTIMC;
options = MultiMCModpackExportTask.OPTION;
}
if (v == server) {
type = MODPACK_TYPE_SERVER;
options = ServerModpackExportTask.OPTION;
}
ModpackInfoPage page = new ModpackInfoPage(getContext(), PageManager.PAGE_ID_TEMP, getParent(), R.layout.page_modpack_info, profile, version, type, options);
ManagePageManager.getInstance().showTempPage(page);
}
public static final String MODPACK_TYPE_MCBBS = "mcbbs";
public static final String MODPACK_TYPE_MULTIMC = "multimc";
public static final String MODPACK_TYPE_SERVER = "server";
}

View File

@ -1,6 +1,5 @@
package com.tungsten.fcl.ui.version;
import android.app.Activity;
import android.content.Context;
import android.widget.Toast;
@ -19,8 +18,8 @@ import com.tungsten.fcl.ui.download.DownloadPageManager;
import com.tungsten.fcl.ui.download.LocalModpackPage;
import com.tungsten.fcl.ui.download.ModpackSelectionPage;
import com.tungsten.fcl.ui.manage.ManagePageManager;
import com.tungsten.fcl.ui.manage.ModpackTypeSelectionPage;
import com.tungsten.fcl.util.AndroidUtils;
import com.tungsten.fcl.util.RequestCodes;
import com.tungsten.fcl.util.TaskCancellationAction;
import com.tungsten.fclcore.auth.Account;
import com.tungsten.fclcore.auth.AccountFactory;
@ -33,8 +32,6 @@ 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;
import com.tungsten.fcllibrary.component.dialog.FCLAlertDialog;
import com.tungsten.fcllibrary.component.view.FCLUILayout;
@ -132,15 +129,9 @@ public class Versions {
return dialog.getFuture();
}
public static void exportVersion(Profile profile, String version) {
//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_DIR_CODE, null);
public static void exportVersion(Context context, FCLUILayout parent, Profile profile, String version) {
ModpackTypeSelectionPage page = new ModpackTypeSelectionPage(context, PageManager.PAGE_ID_TEMP, parent, R.layout.page_modpack_type, profile, version);
ManagePageManager.getInstance().showTempPage(page);
}
public static void duplicateVersion(Context context, Profile profile, String version) {

View File

@ -17,6 +17,7 @@ import com.tungsten.fcllibrary.component.view.FCLSwitch;
import java.lang.ref.WeakReference;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
public final class FXUtils {
@ -54,6 +55,21 @@ public final class FXUtils {
return originalListener;
}
public static <T> StringConverter<T> stringConverter(Function<T, String> func) {
return new StringConverter<T>() {
@Override
public String toString(T object) {
return object == null ? "" : func.apply(object);
}
@Override
public T fromString(String string) {
throw new UnsupportedOperationException();
}
};
}
public static <T> void bind(FCLEditText editText, Property<T> property, StringConverter<T> converter) {
editText.setText(converter == null ? (String) property.getValue() : converter.toString(property.getValue()));
EditTextBindingListener<T> listener = new EditTextBindingListener<>(editText, property, converter);

View File

@ -25,4 +25,6 @@ public class RequestCodes {
public static final int SELECT_DOWNLOAD_FOLDER_CODE = 500;
public static final int SELECT_MODPACK_CODE = 550;
public static final int SELECT_EXPORT_FOLDER_CODE = 600;
}

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="M7,10l5,5 5,-5z"/>
</vector>

View File

@ -0,0 +1,11 @@
<vector
android:autoMirrored="true"
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="M10,17l5,-5 -5,-5v10z"/>
</vector>

View File

@ -49,7 +49,7 @@
<com.tungsten.fcllibrary.component.view.FCLButton
android:layout_marginTop="10dp"
android:id="@+id/next"
android:text="@string/event_next"
android:text="@string/button_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
@ -124,7 +124,7 @@
<com.tungsten.fcllibrary.component.view.FCLButton
android:layout_marginTop="15dp"
android:id="@+id/prev"
android:text="@string/event_prev"
android:text="@string/button_prev"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"

View File

@ -0,0 +1,62 @@
<?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">
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingStart="10dp"
android:paddingEnd="10dp"
app:layout_constraintTop_toTopOf="parent">
<com.tungsten.fcllibrary.component.view.FCLImageButton
android:id="@+id/switch_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_baseline_arrow_right_24"
app:auto_tint="true"
app:no_padding="true"/>
<com.tungsten.fcllibrary.component.view.FCLCheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:id="@+id/check"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:id="@+id/text"
android:layout_marginStart="10dp"
android:layout_gravity="center"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:id="@+id/comment"
android:layout_marginStart="10dp"
android:layout_gravity="center"
app:auto_text_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<ListView
android:layout_marginTop="1px"
android:layout_marginStart="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@android:color/transparent"
android:dividerHeight="1px"
android:id="@+id/list"
app:layout_constraintTop_toBottomOf="@+id/main"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/ui_bg_color"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:paddingTop="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.tungsten.fcllibrary.component.view.FCLProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<ListView
android:layout_width="match_parent"
android:layout_height="0dp"
android:divider="@android:color/transparent"
android:dividerHeight="1px"
android:id="@+id/list"
android:layout_marginBottom="10dp"
android:background="@drawable/bg_container_white"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/next"/>
<com.tungsten.fcllibrary.component.view.FCLButton
app:ripple="true"
app:layout_constraintBottom_toBottomOf="parent"
android:id="@+id/next"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/button_next"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,619 @@
<?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:background="@color/ui_bg_color"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:paddingTop="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="@drawable/bg_container_white"
android:text="@string/modpack_wizard_step_initialization_warning"
app:auto_text_background_tint="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:background="@drawable/bg_container_white"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="10dp"
app:auto_linear_background_tint="true">
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/modpack_wizard_step_initialization_exported_version"
android:singleLine="true"
android:layout_gravity="center"
app:auto_text_tint="true"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/game_version"
android:singleLine="true"
android:layout_gravity="center"
app:auto_text_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/modpack_name"
android:singleLine="true"
android:layout_gravity="center"
app:auto_text_tint="true"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLEditText
android:textSize="14sp"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:singleLine="true"
android:id="@+id/name"
android:hint="@string/input_hint_not_empty"
app:auto_edit_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/archive_author"
android:singleLine="true"
android:layout_gravity="center"
app:auto_text_tint="true"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLEditText
android:textSize="14sp"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:singleLine="true"
android:id="@+id/author"
android:hint="@string/input_hint_not_empty"
app:auto_edit_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/archive_version"
android:singleLine="true"
android:layout_gravity="center"
app:auto_text_tint="true"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLEditText
android:textSize="14sp"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:singleLine="true"
android:id="@+id/version"
android:hint="@string/input_hint_not_empty"
app:auto_edit_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:id="@+id/file_api_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/modpack_file_api"
android:singleLine="true"
android:layout_gravity="center"
app:auto_text_tint="true"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLEditText
android:textSize="14sp"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:singleLine="true"
android:id="@+id/file_api"
app:auto_edit_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:id="@+id/minecraft_args_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settings_advanced_minecraft_arguments"
android:singleLine="true"
android:layout_gravity="center"
app:auto_text_tint="true"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLEditText
android:textSize="14sp"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:singleLine="true"
android:id="@+id/minecraft_args"
app:auto_edit_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:id="@+id/jvm_args_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settings_advanced_jvm_args"
android:singleLine="true"
android:layout_gravity="center"
app:auto_text_tint="true"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLEditText
android:textSize="14sp"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:singleLine="true"
android:id="@+id/jvm_args"
app:auto_edit_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:id="@+id/origin_url_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/modpack_origin_url"
android:singleLine="true"
android:layout_gravity="center"
app:auto_text_tint="true"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLEditText
android:textSize="14sp"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:singleLine="true"
android:id="@+id/origin_url"
app:auto_edit_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:id="@+id/mcbbs_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/modpack_origin_mcbbs"
android:singleLine="true"
android:layout_gravity="center"
app:auto_text_tint="true"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLEditText
android:textSize="14sp"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:singleLine="true"
android:id="@+id/mcbbs"
app:auto_edit_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<View
android:id="@+id/split_1"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:id="@+id/memory_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="10dp"
android:paddingEnd="10dp">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_text_tint="true"
android:singleLine="true"
android:text="@string/settings_memory"/>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_marginTop="10dp"
android:layout_marginStart="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:auto_text_tint="true"
android:layout_gravity="center"
android:singleLine="true"
android:text="@string/settings_memory_lower_bound"/>
<com.tungsten.fcllibrary.component.view.FCLSeekBar
android:layout_marginStart="10dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center"
android:max="16384"
android:id="@+id/memory"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
app:auto_text_tint="true"
android:singleLine="true"
android:layout_marginStart="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/memory_text"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:orientation="vertical">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/modpack_desc"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLEditText
android:textSize="14sp"
android:gravity="top"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:id="@+id/desc"
app:auto_edit_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<View
android:id="@+id/split_2"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:id="@+id/server_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/account_injector_server"
android:singleLine="true"
android:layout_gravity="center"
app:auto_text_tint="true"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLSpinner
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/server"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<View
android:id="@+id/split_3"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:id="@+id/force_update_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/modpack_wizard_step_initialization_force_update"
android:singleLine="true"
android:layout_gravity="center"
app:auto_text_tint="true"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLSwitch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/force_update"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/modpack_wizard_step_initialization_save"
android:singleLine="true"
android:layout_gravity="center"
app:auto_text_tint="true"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_marginStart="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/path_text"
android:singleLine="true"
android:layout_gravity="center"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLImageButton
android:layout_marginStart="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/path"
android:src="@drawable/ic_baseline_edit_24"
app:auto_tint="true"
app:no_padding="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:orientation="horizontal">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/archive_name"
android:singleLine="true"
android:layout_gravity="center"
app:auto_text_tint="true"/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLEditText
android:textSize="14sp"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:singleLine="true"
android:id="@+id/file_name"
android:hint="@string/input_hint_not_empty"
app:auto_edit_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="40dp"
android:layout_height="wrap_content"
android:text=".zip"
android:singleLine="true"
android:layout_gravity="center"
android:gravity="end"
app:auto_text_tint="true"
tools:ignore="HardcodedText"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLButton
app:ripple="true"
android:id="@+id/next"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/button_next"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,177 @@
<?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:padding="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:id="@+id/hint"
android:text="@string/modpack_export_as"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_container_white"
android:padding="10dp"
app:layout_constraintTop_toTopOf="parent"
app:auto_text_tint="true"
app:auto_text_background_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="@drawable/bg_container_white_clickable"
android:orientation="horizontal"
android:id="@+id/mcbbs"
android:layout_marginTop="10dp"
app:layout_constraintTop_toBottomOf="@+id/hint"
app:auto_linear_background_tint="true">
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/modpack_type_mcbbs"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/modpack_type_mcbbs_export"
android:textSize="12sp"
android:singleLine="true"
app:auto_text_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_gravity="center"
app:auto_src_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="@drawable/bg_container_white_clickable"
android:orientation="horizontal"
android:id="@+id/multimc"
android:layout_marginTop="10dp"
app:layout_constraintTop_toBottomOf="@+id/mcbbs"
app:auto_linear_background_tint="true">
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/modpack_type_multimc"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/modpack_type_multimc_export"
android:textSize="12sp"
android:singleLine="true"
app:auto_text_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_gravity="center"
app:auto_src_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="@drawable/bg_container_white_clickable"
android:orientation="horizontal"
android:id="@+id/server"
android:layout_marginTop="10dp"
app:layout_constraintTop_toBottomOf="@+id/multimc"
app:auto_linear_background_tint="true">
<com.tungsten.fcllibrary.component.view.FCLLinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center">
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/modpack_type_server"
android:singleLine="true"
app:auto_text_tint="true"/>
<com.tungsten.fcllibrary.component.view.FCLTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/modpack_type_server_export"
android:textSize="12sp"
android:singleLine="true"
app:auto_text_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_arrow_forward_24"
android:layout_gravity="center"
app:auto_src_tint="true"/>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
</com.tungsten.fcllibrary.component.view.FCLLinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -89,6 +89,8 @@
<string name="assets_index_malformed">资源文件的索引文件损坏。</string>
<string name="button_install">安装</string>
<string name="button_next">下一步</string>
<string name="button_prev">上一步</string>
<string name="community">社区</string>
@ -264,9 +266,6 @@
<string name="edit_direction_event_sneak">双击中心潜行</string>
<string name="edit_direction_event_sneak_code">潜行键值</string>
<string name="event_next">下一步</string>
<string name="event_prev">上一步</string>
<string name="exception_access_denied">无法获取文件 %s。</string>
<string name="exception_artifact_malformed">无法校验文件。</string>
<string name="exception_ssl_handshake">缺少 SSL 证书。</string>
@ -283,6 +282,8 @@
<string name="input_hint_not_empty">必填</string>
<string name="input_hint_optional">选填</string>
<string name="input_not_empty">请先填写必要的输入框。</string>
<string name="input_number">指定的输入框必须输入数字。</string>
<string name="input_url">指定的输入框必须输入有效的链接。</string>
<string name="install_change_version">更改版本</string>
<string name="install_change_version_confirm">你确定将 %s 版本从 %s 改为 %s 吗?</string>

View File

@ -100,6 +100,8 @@
<string name="assets_index_malformed">Index files of downloaded assets were corrupted.</string>
<string name="button_install">Install</string>
<string name="button_next">Next</string>
<string name="button_prev">Prev</string>
<string name="community">Community</string>
@ -275,9 +277,6 @@
<string name="edit_direction_event_sneak">Double Click Center to Sneak</string>
<string name="edit_direction_event_sneak_code">Sneak Keycode</string>
<string name="event_next">Next</string>
<string name="event_prev">Prev</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>
@ -294,6 +293,8 @@
<string name="input_hint_not_empty">Required</string>
<string name="input_hint_optional">Optional</string>
<string name="input_not_empty">Fill the required input box first.</string>
<string name="input_number">The input must be a number.</string>
<string name="input_url">The input must be a valid URL.</string>
<string name="install_change_version">Change Version</string>
<string name="install_change_version_confirm">Are you sure you want to switch %s from version %s to %s?</string>

View File

@ -17,6 +17,7 @@ import androidx.core.content.ContextCompat;
import com.tungsten.fclauncher.FCLPath;
import com.tungsten.fcllibrary.component.theme.ThemeEngine;
import com.tungsten.fcllibrary.util.LocaleUtils;
public class FCLActivity extends AppCompatActivity {

View File

@ -0,0 +1,131 @@
package com.tungsten.fcllibrary.component;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import com.tungsten.fcl.R;
import com.tungsten.fclcore.fakefx.beans.binding.Bindings;
import com.tungsten.fclcore.fakefx.beans.property.SimpleBooleanProperty;
import com.tungsten.fclcore.fakefx.collections.ObservableList;
import com.tungsten.fclcore.task.Schedulers;
import com.tungsten.fcllibrary.component.view.FCLCheckBox;
import com.tungsten.fcllibrary.component.view.FCLImageButton;
import com.tungsten.fcllibrary.component.view.FCLLinearLayout;
import com.tungsten.fcllibrary.component.view.FCLTextView;
public class FCLCheckBoxTreeAdapter<T> extends FCLAdapter {
private final ObservableList<FCLCheckBoxTreeItem<T>> list;
private final SimpleBooleanProperty checkHeightProperty = new SimpleBooleanProperty(false);
public SimpleBooleanProperty checkHeightProperty() {
return checkHeightProperty;
}
public void setCheckHeight(boolean checkHeight) {
checkHeightProperty.set(checkHeight);
}
public boolean isCheckHeight() {
return checkHeightProperty.get();
}
public FCLCheckBoxTreeAdapter(Context context, ObservableList<FCLCheckBoxTreeItem<T>> list) {
super(context);
this.list = list;
}
private static class ViewHolder {
FCLLinearLayout main;
FCLImageButton switchView;
FCLCheckBox checkBox;
FCLTextView textView;
FCLTextView comment;
ListView listView;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int i) {
return list.get(i);
}
@SuppressLint("UseCompatLoadingForDrawables")
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
final ViewHolder viewHolder;
if (view == null) {
viewHolder = new ViewHolder();
view = LayoutInflater.from(getContext()).inflate(R.layout.item_check_box_tree, null);
viewHolder.main = view.findViewById(R.id.main);
viewHolder.switchView = view.findViewById(R.id.switch_view);
viewHolder.checkBox = view.findViewById(R.id.check);
viewHolder.textView = view.findViewById(R.id.text);
viewHolder.comment = view.findViewById(R.id.comment);
viewHolder.listView = view.findViewById(R.id.list);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
FCLCheckBoxTreeItem<T> item = list.get(i);
viewHolder.switchView.setVisibility(item.getSubItem().size() == 0 ? View.INVISIBLE : View.VISIBLE);
viewHolder.switchView.imageProperty().bind(Bindings.createObjectBinding(() -> item.isExpanded() ? getContext().getDrawable(R.drawable.ic_baseline_arrow_drop_down_24) : getContext().getDrawable(R.drawable.ic_baseline_arrow_right_24), item.expandedProperty()));
viewHolder.switchView.setOnClickListener(v -> item.setExpanded(!item.isExpanded()));
viewHolder.checkBox.addCheckedChangeListener();
viewHolder.checkBox.checkProperty().bindBidirectional(item.selectedProperty());
viewHolder.checkBox.indeterminateProperty().bindBidirectional(item.indeterminateProperty());
viewHolder.textView.setText(item.getText());
viewHolder.comment.setVisibility(item.getComment() == null ? View.GONE : View.VISIBLE);
if (item.getComment() != null)
viewHolder.comment.setText(item.getComment());
viewHolder.listView.setVisibility((item.isExpanded() && item.getSubItem().size() > 0) ? View.VISIBLE : View.GONE);
item.expandedProperty().addListener(observable -> viewHolder.listView.setVisibility((item.isExpanded() && item.getSubItem().size() > 0) ? View.VISIBLE : View.GONE));
if (item.getSubItem().size() > 0) {
viewHolder.main.post(() -> {
viewHolder.listView.setAdapter(new FCLCheckBoxTreeAdapter<>(getContext(), item.getSubItem()));
ViewGroup.LayoutParams layoutParams = viewHolder.listView.getLayoutParams();
new Thread(() -> {
layoutParams.height = getListViewHeight(item, viewHolder.listView.getDividerHeight(), viewHolder.main.getMeasuredHeight());
Schedulers.androidUIThread().execute(() -> viewHolder.listView.setLayoutParams(layoutParams));
}).start();
item.expandedProperty().addListener(observable -> setCheckHeight(true));
((FCLCheckBoxTreeAdapter<?>) viewHolder.listView.getAdapter()).checkHeightProperty().addListener(observable -> {
if (((FCLCheckBoxTreeAdapter<?>) viewHolder.listView.getAdapter()).isCheckHeight()) {
ViewGroup.LayoutParams lp = viewHolder.listView.getLayoutParams();
new Thread(() -> {
lp.height = getListViewHeight(item, viewHolder.listView.getDividerHeight(), viewHolder.main.getMeasuredHeight());
Schedulers.androidUIThread().execute(() -> viewHolder.listView.setLayoutParams(lp));
}).start();
((FCLCheckBoxTreeAdapter<?>) viewHolder.listView.getAdapter()).setCheckHeight(false);
setCheckHeight(true);
}
});
});
}
return view;
}
public static int getListViewHeight(FCLCheckBoxTreeItem<?> item, int splitSize, int baseHeight) {
int count = getSubItemCount(item);
return (baseHeight * count) + (splitSize * (count - 1));
}
public static int getSubItemCount(FCLCheckBoxTreeItem<?> item) {
int count = item.isExpanded() ? item.getSubItem().size() : 0;
if (item.isExpanded()) {
for (FCLCheckBoxTreeItem<?> subItem : item.getSubItem()) {
count += getSubItemCount(subItem);
}
}
return count;
}
}

View File

@ -0,0 +1,129 @@
package com.tungsten.fcllibrary.component;
import com.tungsten.fclcore.fakefx.beans.property.SimpleBooleanProperty;
import com.tungsten.fclcore.fakefx.collections.ObservableList;
import com.tungsten.fclcore.fakefx.util.StringConverter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class FCLCheckBoxTreeItem<T> {
private final T data;
private final StringConverter<T> stringConverter;
@Nullable
private String comment;
@NotNull
private final ObservableList<FCLCheckBoxTreeItem<T>> subItem;
private final SimpleBooleanProperty expandedProperty = new SimpleBooleanProperty(false);
private final SimpleBooleanProperty selectedProperty = new SimpleBooleanProperty(false);
private final SimpleBooleanProperty indeterminateProperty = new SimpleBooleanProperty(false);
public FCLCheckBoxTreeItem(T data, StringConverter<T> stringConverter, @NotNull ObservableList<FCLCheckBoxTreeItem<T>> subItem) {
this.data = data;
this.stringConverter = stringConverter;
this.subItem = subItem;
selectedProperty().addListener(observable -> {
if (!fromCheck) {
subItem.forEach(it -> it.setSelected(isSelected()));
}
});
}
private boolean fromCheck = false;
public void checkProperty() {
if (subItem.stream().anyMatch(FCLCheckBoxTreeItem::isIndeterminate)) {
if (!isIndeterminate()) {
setIndeterminate(true);
}
} else if (subItem.stream().noneMatch(FCLCheckBoxTreeItem::isSelected)) {
if (isIndeterminate()) {
setIndeterminate(false);
}
if (isSelected()) {
fromCheck = true;
setSelected(false);
fromCheck = false;
}
} else if (subItem.stream().allMatch(FCLCheckBoxTreeItem::isSelected)) {
if (isIndeterminate()) {
setIndeterminate(false);
}
if (!isSelected()) {
fromCheck = true;
setSelected(true);
fromCheck = false;
}
} else if (subItem.stream().anyMatch(FCLCheckBoxTreeItem::isSelected) && subItem.stream().anyMatch(it -> !it.isSelected())) {
if (!isIndeterminate()) {
setIndeterminate(true);
}
}
}
public T getData() {
return data;
}
public String getText() {
if (data instanceof String && stringConverter == null)
return (String) data;
else if (stringConverter == null)
return data.toString();
return stringConverter.toString(data);
}
public void setComment(@Nullable String comment) {
this.comment = comment;
}
@Nullable
public String getComment() {
return comment;
}
@NotNull
public ObservableList<FCLCheckBoxTreeItem<T>> getSubItem() {
return subItem;
}
public SimpleBooleanProperty expandedProperty() {
return expandedProperty;
}
public void setExpanded(boolean expanded) {
this.expandedProperty.set(expanded);
}
public boolean isExpanded() {
return expandedProperty.get();
}
public SimpleBooleanProperty selectedProperty() {
return selectedProperty;
}
public void setSelected(boolean selected) {
this.selectedProperty.set(selected);
}
public boolean isSelected() {
return selectedProperty.get();
}
public SimpleBooleanProperty indeterminateProperty() {
return indeterminateProperty;
}
public void setIndeterminate(boolean indeterminate) {
this.indeterminateProperty.set(indeterminate);
}
public boolean isIndeterminate() {
return indeterminateProperty.get();
}
}

View File

@ -11,6 +11,7 @@ import androidx.annotation.Nullable;
import com.tungsten.fclauncher.FCLPath;
import com.tungsten.fcllibrary.component.theme.ThemeEngine;
import com.tungsten.fcllibrary.util.LocaleUtils;
public class FCLService extends Service {

View File

@ -22,8 +22,10 @@ public class FCLCheckBox extends AppCompatCheckBox {
private boolean autoTint;
private boolean fromUserOrSystem = false;
private boolean fromIndeterminate = false;
private BooleanProperty visibilityProperty;
private BooleanProperty checkProperty;
private BooleanProperty indeterminateProperty;
private BooleanProperty disableProperty;
private final IntegerProperty theme = new IntegerPropertyBase() {
@ -62,9 +64,12 @@ public class FCLCheckBox extends AppCompatCheckBox {
public void addCheckedChangeListener() {
setOnCheckedChangeListener((compoundButton, b) -> {
fromUserOrSystem = true;
checkProperty().set(b);
fromUserOrSystem = false;
if (!fromIndeterminate) {
fromUserOrSystem = true;
checkProperty().set(b);
indeterminateProperty().set(false);
fromUserOrSystem = false;
}
});
}
@ -163,6 +168,45 @@ public class FCLCheckBox extends AppCompatCheckBox {
return checkProperty;
}
public final void setIndeterminate(boolean indeterminate) {
checkProperty().set(indeterminate);
}
public final boolean isIndeterminate() {
return indeterminateProperty().get();
}
public final BooleanProperty indeterminateProperty() {
if (indeterminateProperty == null) {
indeterminateProperty = new BooleanPropertyBase() {
public void invalidated() {
Schedulers.androidUIThread().execute(() -> {
if (!fromUserOrSystem) {
fromIndeterminate = true;
if (get()) {
setChecked(true);
} else {
setChecked(checkProperty().get());
}
fromIndeterminate = false;
}
});
}
public Object getBean() {
return this;
}
public String getName() {
return "indeterminate";
}
};
}
return indeterminateProperty;
}
public final void setDisableValue(boolean disableValue) {
disableProperty().set(disableValue);
}

View File

@ -35,23 +35,7 @@ public class FCLImageButton extends AppCompatImageButton {
@Override
protected void invalidated() {
get();
int[][] state = {
{
}
};
int[] colorSrc = {
ThemeEngine.getInstance().getTheme().getAutoTint()
};
int[] colorRipple = {
ThemeEngine.getInstance().getTheme().getLtColor()
};
if (autoTint) {
setImageTintList(new ColorStateList(state, colorSrc));
}
RippleDrawable drawable = new RippleDrawable(new ColorStateList(state, colorRipple), null, null);
drawable.setRadius(ConvertUtils.dip2px(getContext(), noPadding ? 12 : 20));
setBackgroundDrawable(drawable);
refreshStyle();
}
@Override
@ -65,6 +49,26 @@ public class FCLImageButton extends AppCompatImageButton {
}
};
public void refreshStyle() {
int[][] state = {
{
}
};
int[] colorSrc = {
ThemeEngine.getInstance().getTheme().getAutoTint()
};
int[] colorRipple = {
ThemeEngine.getInstance().getTheme().getLtColor()
};
if (autoTint) {
setImageTintList(new ColorStateList(state, colorSrc));
}
RippleDrawable drawable = new RippleDrawable(new ColorStateList(state, colorRipple), null, null);
drawable.setRadius(ConvertUtils.dip2px(getContext(), noPadding ? 12 : 20));
setBackgroundDrawable(drawable);
}
private void init() {
if (!noPadding) {
setPadding(
@ -107,6 +111,7 @@ public class FCLImageButton extends AppCompatImageButton {
public void setAutoTint(boolean autoTint) {
this.autoTint = autoTint;
refreshStyle();
}
public boolean isAutoTint() {
@ -115,6 +120,7 @@ public class FCLImageButton extends AppCompatImageButton {
public void setNoPadding(boolean noPadding) {
this.noPadding = noPadding;
refreshStyle();
}
public boolean isNoPadding() {

View File

@ -1,4 +1,4 @@
package com.tungsten.fcllibrary.component;
package com.tungsten.fcllibrary.util;
import android.annotation.SuppressLint;
import android.content.Context;