Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.tungsten.fcl.ui.PageManager;
import com.tungsten.fcl.ui.UIManager;
import com.tungsten.fcl.util.AndroidUtils;
import com.tungsten.fcl.util.LayoutConverter;
import com.tungsten.fcl.util.RequestCodes;
import com.tungsten.fclauncher.utils.FCLPath;
import com.tungsten.fclcore.fakefx.beans.binding.Bindings;
Expand All @@ -33,20 +34,25 @@
import com.tungsten.fclcore.task.Schedulers;
import com.tungsten.fclcore.task.Task;
import com.tungsten.fclcore.util.Logging;
import com.tungsten.fclcore.util.function.ExceptionalConsumer;
import com.tungsten.fclcore.util.io.FileUtils;
import com.tungsten.fcllibrary.browser.FileBrowser;
import com.tungsten.fcllibrary.browser.options.LibMode;

import kotlin.Unit;
import com.tungsten.fcllibrary.browser.options.SelectionMode;
import com.tungsten.fcllibrary.component.ui.FCLCommonPage;
import com.tungsten.fcllibrary.component.view.FCLButton;
import com.tungsten.fcllibrary.component.view.FCLLinearLayout;
import com.tungsten.fcllibrary.component.view.FCLProgressBar;
import com.tungsten.fcllibrary.component.view.FCLTextView;
import com.tungsten.fcllibrary.component.view.FCLUILayout;
import com.tungsten.fcllibrary.ui.ProgressDialog;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Level;

public class ControllerManagePage extends FCLCommonPage implements View.OnClickListener {
Expand Down Expand Up @@ -238,14 +244,22 @@ public void onClick(View view) {
ControllerPageManager.getInstance().showTempPage(page);
}
if (view == share) {
Intent intent = new Intent(Intent.ACTION_SEND);
Uri uri = FileProvider.getUriForFile(getContext(), getContext().getString(com.tungsten.fcllibrary.R.string.file_browser_provider), new File(FCLPath.CONTROLLER_DIR, getSelectedController().getFileName()));
intent.setType(AndroidUtils.getMimeType(FCLPath.CONTROLLER_DIR + "/" + getSelectedController().getFileName()));
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addCategory(Intent.CATEGORY_DEFAULT);
getActivity().startActivity(Intent.createChooser(intent, getContext().getString(R.string.control_share)));
DialogUtilKt.showItemSelectionDialog(
getContext(),
getContext().getString(R.string.control_share_choose),
new ArrayList<>(Arrays.asList(
getContext().getString(R.string.control_share_direct),
getContext().getString(R.string.control_share_zl2)
)),
selected -> {
if (selected.equals(getContext().getString(R.string.control_share_direct))) {
shareDirect();
} else if (selected.equals(getContext().getString(R.string.control_share_zl2))) {
shareAsZl2();
}
return Unit.INSTANCE;
}
);
}
if (view == editInfo) {
ControllerInfoDialog dialog = new ControllerInfoDialog(getContext(), false, selectedController.get(), (controller) -> changeControllerInfo(selectedController.get(), controller));
Expand All @@ -259,4 +273,53 @@ public void onClick(View view) {
getActivity().startActivity(intent);
}
}

/** 直接分享原始 FCL 控制布局 JSON 文件。 */
private void shareDirect() {
File file = new File(FCLPath.CONTROLLER_DIR, getSelectedController().getFileName());
shareFile(file, R.string.control_share, AndroidUtils.getMimeType(file.getAbsolutePath()));
}

/** 转换为 ZL2 格式后分享。 */
private void shareAsZl2() {
if (!LayoutConverter.isSupported()) {
Toast.makeText(getContext(), R.string.control_convert_unsupported, Toast.LENGTH_LONG).show();
return;
}
ProgressDialog dialog = new ProgressDialog(getContext());
dialog.show();
Controller controller = getSelectedController();
File input = new File(FCLPath.CONTROLLER_DIR, controller.getFileName());
// 输出到公共目录 FCL/share/,便于文件管理器定位
File output = new File(FCLPath.SHARE_DIR, controller.getId() + "_zl2.json");
//noinspection ResultOfMethodCallIgnored
output.delete();
Task.supplyAsync(() -> {
return LayoutConverter.convertFclToZl2(input, output);
}).thenAcceptAsync(Schedulers.androidUIThread(), (ExceptionalConsumer<String, Exception>) error -> {
if (error == null) {
shareFile(output, R.string.control_share_zl2_title, "application/json");
} else {
DialogUtilKt.showErrorDialog(getContext(), getContext().getString(R.string.control_convert_failed) + "\n" + error);
}
}).whenComplete(Schedulers.androidUIThread(), exception -> {
dialog.dismiss();
if (exception != null) {
Logging.LOG.log(Level.SEVERE, "Failed to convert controller to ZL2", exception);
DialogUtilKt.showErrorDialog(getContext(), getContext().getString(R.string.control_convert_failed) + "\n" + exception.getMessage());
}
}).start();
}

/** 通过系统分享面板分享指定文件。 */
private void shareFile(File file, int chooserTitleRes, String mimeType) {
Intent intent = new Intent(Intent.ACTION_SEND);
Uri uri = FileProvider.getUriForFile(getContext(), getContext().getString(com.tungsten.fcllibrary.R.string.file_browser_provider), file);
intent.setType(mimeType);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addCategory(Intent.CATEGORY_DEFAULT);
getActivity().startActivity(Intent.createChooser(intent, getContext().getString(chooserTitleRes)));
}
}
56 changes: 56 additions & 0 deletions FCL/src/main/java/com/tungsten/fcl/util/LayoutConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.tungsten.fcl.util;

import android.os.Build;

/**
* 通过 JNI 调用 control-converter 项目编译的原生库 {@code libcc.so}
* 实现 FCL 控制布局与 ZalithLauncher2 (ZL2) 布局之间的转换。
*
* 原生库来源:d:\project\control-converter\go (Go 实现, c-shared 编译)
* 打包位置:jniLibs/arm64-v8a/libcc.so
* 通过 JNI 调用,避免命令执行方式在 Android 上的兼容性问题。
*/
public final class LayoutConverter {

static {
System.loadLibrary("cc");
}

private LayoutConverter() {
}

/** 当前设备是否支持运行转换(仅 arm64-v8a)。 */
public static boolean isSupported() {
for (String abi : Build.SUPPORTED_ABIS) {
if ("arm64-v8a".equals(abi)) {
return true;
}
}
return false;
}

/**
* JNI 原生方法:将 FCL 控制布局 JSON 转换为 ZL2 格式。
*
* @param inputPath FCL 控制布局 JSON 文件路径
* @param outputPath 转换后的 ZL2 JSON 输出文件路径
* @return 转换成功返回 null;失败返回错误信息
*/
private static native String convertFclToZl2Native(String inputPath, String outputPath);

/**
* 将 FCL 控制布局 JSON 转换为 ZL2 格式。
* <p>同步阻塞,调用方需在后台线程执行。
*
* @param input FCL 控制布局 JSON 文件
* @param output 转换后的 ZL2 JSON 输出文件
* @return 转换成功返回 null;失败返回错误信息
*/
public static String convertFclToZl2(java.io.File input, java.io.File output) {
try {
return convertFclToZl2Native(input.getAbsolutePath(), output.getAbsolutePath());
} catch (Throwable t) {
return t.getClass().getSimpleName() + ": " + t.getMessage();
}
}
}
Binary file added FCL/src/main/jniLibs/arm64-v8a/libcc.so
Binary file not shown.
7 changes: 7 additions & 0 deletions FCL/src/main/res/values-zh-rHK/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,13 @@
<string name="control_list">佈局列表</string>
<string name="control_select">選擇佈局</string>
<string name="control_share">分享佈局</string>
<string name="control_share_choose">選擇分享方式</string>
<string name="control_share_direct">直接分享</string>
<string name="control_share_zl2">分享為 ZL2 控制佈局</string>
<string name="control_share_zl2_title">分享 ZL2 控制佈局</string>
<string name="control_converting">正在轉換…</string>
<string name="control_convert_failed">轉換失敗!</string>
<string name="control_convert_unsupported">當前設備不支持 ZL2 轉換(需 arm64)</string>
<string name="control_upload">上傳佈局</string>

<!-- 保持原有分類名稱不變 -->
Expand Down
7 changes: 7 additions & 0 deletions FCL/src/main/res/values-zh/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,13 @@
<string name="control_list">布局列表</string>
<string name="control_select">选择布局</string>
<string name="control_share">分享布局</string>
<string name="control_share_choose">选择分享方式</string>
<string name="control_share_direct">直接分享</string>
<string name="control_share_zl2">分享为 ZL2 控制布局</string>
<string name="control_share_zl2_title">分享 ZL2 控制布局</string>
<string name="control_converting">正在转换…</string>
<string name="control_convert_failed">转换失败!</string>
<string name="control_convert_unsupported">当前设备不支持 ZL2 转换(需 arm64)</string>
<string name="control_upload">上传布局</string>

<string name="curse_category_0">全部</string>
Expand Down
7 changes: 7 additions & 0 deletions FCL/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,13 @@
<string name="control_list">Controller List</string>
<string name="control_select">Select Controller</string>
<string name="control_share">Share Controller</string>
<string name="control_share_choose">Choose share method</string>
<string name="control_share_direct">Direct share</string>
<string name="control_share_zl2">Share as ZL2 layout</string>
<string name="control_share_zl2_title">Share ZL2 layout</string>
<string name="control_converting">Converting…</string>
<string name="control_convert_failed">Conversion failed!</string>
<string name="control_convert_unsupported">ZL2 conversion is not supported on this device (arm64 required)</string>
<string name="control_upload">Upload Controller</string>

<string name="curse_category_0">All</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class FCLPath {
public static String PLUGIN_DIR;
public static String BACKGROUND_DIR;
public static String CONTROLLER_DIR;
public static String SHARE_DIR;

public static String PRIVATE_COMMON_DIR;
public static String SHARED_COMMON_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + "/FCL/.minecraft";
Expand Down Expand Up @@ -66,6 +67,7 @@ public static void loadPaths(Context context) {
PLUGIN_DIR = FILES_DIR + "/plugins";
BACKGROUND_DIR = FILES_DIR + "/background";
CONTROLLER_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + "/FCL/control";
SHARE_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + "/FCL/share";
File externalFilesDir = context.getExternalFilesDir(null);
if (externalFilesDir == null) {
externalFilesDir = new File(Environment.getExternalStorageDirectory(), "Android/data/" + context.getPackageName() + "/files");
Expand Down Expand Up @@ -94,6 +96,7 @@ public static void loadPaths(Context context) {
init(PLUGIN_DIR);
init(BACKGROUND_DIR);
init(CONTROLLER_DIR);
init(SHARE_DIR);
init(PRIVATE_COMMON_DIR);
init(SHARED_COMMON_DIR);
}
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,5 @@
- [virglrenderer](https://github.com/AngelAuraMC/virglrenderer): [MIT License](https://gitlab.freedesktop.org/virgl/virglrenderer/-/blob/master/COPYING).
- [OpenAL-Soft](https://github.com/kcat/openal-soft): [GNU GPLv2](app_pojavlauncher/src/main/assets/licenses/OPENAL-SOFT_GPL2)
- [oboe](https://github.com/google/oboe): [Apache License 2.0](app_pojavlauncher/src/main/assets/licenses/OBOE_APACHE2).
- [pfffft](https://bitbucket.org/jpommier/pffft/src/master/): [ARR](app_pojavlauncher/src/main/assets/licenses/PFFFT_LICENSE)
- [pfffft](https://bitbucket.org/jpommier/pffft/src/master/): [ARR](app_pojavlauncher/src/main/assets/licenses/PFFFT_LICENSE)
- [control-converter](https://github.com/NingZeStudio/control-converter) (FCL→ZL2 控制布局转换,Go 实现,打包为 `libcc.so`): [MIT License](https://opensource.org/licenses/MIT)
1 change: 1 addition & 0 deletions README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,4 @@ This project is licensed under **[GPL-3.0 License](https://www.gnu.org/licenses/
- [OpenAL-Soft](https://github.com/kcat/openal-soft): [GNU GPLv2](app_pojavlauncher/src/main/assets/licenses/OPENAL-SOFT_GPL2)
- [oboe](https://github.com/google/oboe): [Apache License 2.0](app_pojavlauncher/src/main/assets/licenses/OBOE_APACHE2).
- [pfffft](https://bitbucket.org/jpommier/pffft/src/master/): [ARR](app_pojavlauncher/src/main/assets/licenses/PFFFT_LICENSE)
- [control-converter](https://github.com/NingZeStudio/control-converter) (FCL→ZL2 control layout converter, Go implementation, packaged as `libcc.so`): [MIT License](https://opensource.org/licenses/MIT)
3 changes: 2 additions & 1 deletion README_RU.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,5 @@
- [virglrenderer](https://github.com/AngelAuraMC/virglrenderer): [MIT License](https://gitlab.freedesktop.org/virgl/virglrenderer/-/blob/master/COPYING).
- [OpenAL-Soft](https://github.com/kcat/openal-soft): [GNU GPLv2](app_pojavlauncher/src/main/assets/licenses/OPENAL-SOFT_GPL2)
- [oboe](https://github.com/google/oboe): [Apache License 2.0](app_pojavlauncher/src/main/assets/licenses/OBOE_APACHE2).
- [pfffft](https://bitbucket.org/jpommier/pffft/src/master/): [ARR](app_pojavlauncher/src/main/assets/licenses/PFFFT_LICENSE)
- [pfffft](https://bitbucket.org/jpommier/pffft/src/master/): [ARR](app_pojavlauncher/src/main/assets/licenses/PFFFT_LICENSE)
- [control-converter](https://github.com/NingZeStudio/control-converter) (конвертер раскладок управления FCL→ZL2, реализация на Go, упакован как `libcc.so`): [MIT License](https://opensource.org/licenses/MIT)
Loading