From 81add29bc521a69817296ad17ef448ef63a93271 Mon Sep 17 00:00:00 2001 From: ewt45 <79033456+ewt45@users.noreply.github.com> Date: Sun, 26 Nov 2023 16:11:15 +0800 Subject: [PATCH] edpatch v1.0.0 --- .../datainsert/exagear/FAB/FabMenu.java | 5 +- .../FAB/dialogfragment/BaseFragment.java | 26 +- .../FAB/dialogfragment/DriveD_origin.java | 418 ------------------ .../FAB/dialogfragment/PulseAudio.java | 37 +- .../FAB/dialogfragment/VirGLOverlay_old.java | 396 ----------------- .../FAB/dialogfragment/VirglOverlay.java | 4 - .../customcontrols/SubView1Mouse.java | 56 ++- .../customcontrols/SubView2Keys.java | 19 +- .../customcontrols/SubView3Style.java | 80 ++-- .../customcontrols/SubView4Other.java | 115 ++--- .../widgets/AvailableKeysView.java | 5 +- .../widgets/BtnPropertiesView.java | 14 +- .../com/example/datainsert/exagear/QH.java | 65 +++ .../com/example/datainsert/exagear/RR.java | 53 ++- .../containerSettings/ConSetOtherArgv.java | 9 +- .../containerSettings/ConSetRenderer.java | 25 +- .../otherargv/AdapterHelper.java | 2 + .../otherargv/AllArgsAdapter.java | 30 +- .../otherargv/Arguments.java | 5 + .../axs/gamesControls/GestureMachineMix.java | 3 +- .../exagear/controls/widget/JoyStickBtn.java | 11 +- patchapp/build.gradle | 2 +- patchapp/release/output-metadata.json | 2 +- .../patchapp/fragment/FragmentPatchStep1.java | 37 +- .../patchapp/fragment/FragmentPatchStep2.java | 3 +- .../com/ewt45/patchapp/thread/FuncFAB.java | 3 +- .../ewt45/patchapp/thread/FuncRenderer.java | 2 +- .../com/ewt45/patchapp/thread/SignalDone.java | 1 + patchapp/src/main/res/drawable/otherargv.jpg | Bin 50465 -> 74434 bytes .../main/res/layout/fragment_patch_step1.xml | 47 +- .../layout/fragment_patch_step1_newselect.xml | 109 +++++ .../main/res/layout/fragment_patch_step3.xml | 1 + .../main/res/layout/item_func_help_descp.xml | 55 ++- patchapp/src/main/res/values-ru/strings.xml | 16 +- patchapp/src/main/res/values-zh/strings.xml | 18 +- patchapp/src/main/res/values/strings.xml | 115 +---- readme.md | 44 +- readme/readme_en.md | 40 +- readme/readme_ru.md | 29 +- 39 files changed, 643 insertions(+), 1259 deletions(-) delete mode 100644 app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/DriveD_origin.java delete mode 100644 app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/VirGLOverlay_old.java create mode 100644 patchapp/src/main/res/layout/fragment_patch_step1_newselect.xml diff --git a/app/src/main/java/com/example/datainsert/exagear/FAB/FabMenu.java b/app/src/main/java/com/example/datainsert/exagear/FAB/FabMenu.java index def3df26..5590ae79 100644 --- a/app/src/main/java/com/example/datainsert/exagear/FAB/FabMenu.java +++ b/app/src/main/java/com/example/datainsert/exagear/FAB/FabMenu.java @@ -45,7 +45,8 @@ public class FabMenu { 3: 修复了左右布局编辑一列按键时,重新选择按键之后会导致按键顺序被打乱的问题 pulseaudio - 2:保留 deamon.conf + 2: 保留 deamon.conf + 3: 将工作目录 以及 日志输出 移动到 z:/opt/edpatch/pulseaudio-xsdl xegw 1: 为xegw2.0准备的更多选项, -legacy-drawing 和关闭电池优化 @@ -56,7 +57,7 @@ public class FabMenu { private static final int VERSION_FOR_EDPATCH = 0x3 //自定义d盘的版本号 | 0x3 << 4 //自定义按键的版本号 - | 0x2 << 8 //pulseaudio + | 0x3 << 8 //pulseaudio | 0x1 << 12 //Xegw | 0x1 << 16 //VirglOverlay ; diff --git a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/BaseFragment.java b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/BaseFragment.java index d630d58f..3d00006a 100644 --- a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/BaseFragment.java +++ b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/BaseFragment.java @@ -69,34 +69,10 @@ public static TextView getTextViewWithText(Context c, String s) { * @return 线性布局 * @deprecated 请使用QH的同名函数 */ - @Deprecated public static LinearLayout getOneLineWithTitle(Context c, @Nullable String s, @Nullable View view, boolean vertical) { -// return QH.getOneLineWithTitle(c,s,view,vertical); - LinearLayout linearLayout = new LinearLayout(c); - linearLayout.setOrientation(vertical ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL); - if (s != null && !s.equals("")) { - TextView textView = getTextViewWithText(c, s); - //加粗一下吧 - textView.getPaint().setFakeBoldText(true); -// textView.setTypeface(Typeface.DEFAULT_BOLD); - textView.invalidate(); - linearLayout.addView(textView); - } - if (view != null) { - LinearLayout.LayoutParams params = view.getLayoutParams() != null - ? new LinearLayout.LayoutParams(view.getLayoutParams()) - : new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT); - if (linearLayout.getChildCount() > 0) - params.setMarginStart(20); - if(vertical) - params.topMargin=20; - linearLayout.addView(view, params); - } - linearLayout.setPadding(0, 20, 0, 0); - return linearLayout; + return QH.getOneLineWithTitle(c, s, view, vertical); } - /** * 获取设置相关的sharepreference 写入或读取。 写入:.edit().apply() * diff --git a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/DriveD_origin.java b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/DriveD_origin.java deleted file mode 100644 index 970fb22d..00000000 --- a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/DriveD_origin.java +++ /dev/null @@ -1,418 +0,0 @@ -package com.example.datainsert.exagear.FAB.dialogfragment; - -import static android.content.DialogInterface.BUTTON_NEGATIVE; -import static android.content.DialogInterface.BUTTON_POSITIVE; -import static com.example.datainsert.exagear.RR.getS; - -import android.Manifest; -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.graphics.Typeface; -import android.net.Uri; -import android.os.Bundle; -import android.os.Environment; -import android.provider.Settings; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.design.widget.Snackbar; -import android.support.design.widget.TextInputLayout; -import android.support.v4.content.ContextCompat; -import android.support.v7.app.AppCompatActivity; -import android.text.Editable; -import android.text.InputType; -import android.text.Spannable; -import android.text.SpannableStringBuilder; -import android.text.Spanned; -import android.text.TextWatcher; -import android.text.style.ForegroundColorSpan; -import android.text.style.StrikethroughSpan; -import android.text.style.StyleSpan; -import android.util.Log; -import android.view.Menu; -import android.view.ViewGroup; -import android.view.inputmethod.EditorInfo; -import android.widget.LinearLayout; -import android.widget.PopupMenu; -import android.widget.TextView; - -import com.eltechs.axs.Globals; -import com.example.datainsert.exagear.FAB.FabMenu; -import com.example.datainsert.exagear.FAB.widget.MyTextInputEditText; -import com.example.datainsert.exagear.RR; - -import java.io.File; - -public class DriveD_origin extends BaseFragment implements DialogInterface.OnClickListener { - public final static String TAG = "DriveD"; - private static final String[] dstDirArrKeys = new String[]{"Exagear", "Download"}; - private static final String[] dstDirArrVals = new String[]{"Exagear", "Download"}; - private static final String[] parDirArrKeys = new String[]{getS(RR.DriveD_ParDirKey_1), getS(RR.DriveD_ParDirKey_2), getS(RR.DriveD_ParDirKey_3)}; - private static final ParDirEnum[] parDirArrVals = new ParDirEnum[]{ParDirEnum.ExternalStorage, ParDirEnum.ExternalFilesDir, ParDirEnum.SDCardExternalFilesDir}; - //sharedpreference里记录父路径和文件夹的key - public static String PREF_KEY_PAR_IND = "PREF_KEY_PAR_IND"; //值为int - public static String PREF_KEY_DST_NAME = "PREF_KEY_DST_IND"; //值为string - public static String PREF_VAL_DST_NAME = "Exagear";//没有自定义的时候,默认的文件夹名,可以改这个默认的路径 - String[] testCheckStr = new String[]{getS(RR.DriveD_check_1), getS(RR.DriveD_check_2), getS(RR.DriveD_check_3), getS(RR.DriveD_check_4), getS(RR.DriveD_check_5)}; - //用于动态显示父目录和测试结果的textview - private TextView tvTestResult; - private MyTextInputEditText tvInputParDir; - //用于编辑文件夹名的edittext - private MyTextInputEditText tvInputDstDir; - //当前设置的父目录和文件夹名称 - private int currentParDir; //考虑到持久化保存,还是用enum好一些,也许外部路径会有变化? - private String currentDstDirName; - - /** - * 根据parDirEnum生成对应文件路径字符串并返回 - * - * @param parDirEnum enum - * @return 文件字符串, - */ - private static File dirEnumToFile(ParDirEnum parDirEnum) { - File parDir = null; - try { - if (parDirEnum == ParDirEnum.ExternalFilesDir) { - parDir = Globals.getAppContext().getExternalFilesDir(null); - } else if (parDirEnum == ParDirEnum.ExternalStorage) { - parDir = Environment.getExternalStorageDirectory(); - } else if (parDirEnum == ParDirEnum.SDCardExternalFilesDir) { - parDir = Globals.getAppContext().getExternalFilesDirs(null)[1]; - } - } catch (Exception e) { - e.printStackTrace(); - } - return parDir; - } - - /** - * 在StartGuest中初始化d盘路径时调用,返回对应的file - * - * @return file - */ - public static File getDriveDDir() { - if (getPreference() == null) - return null; - File parFile = dirEnumToFile(parDirArrVals[getPreference().getInt(PREF_KEY_PAR_IND, 0)]); - try { - return new File(parFile, getPreference().getString(PREF_KEY_DST_NAME, PREF_VAL_DST_NAME)); -// return new File("/storage/BA73-022B");//825E-837B - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - @NonNull - @Override - public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { - return super.onCreateDialog(savedInstanceState); - } - - @Override - protected ViewGroup buildUI() { - Context c = requireContext(); - tvTestResult = getTextViewWithText(c, ""); - - LinearLayout rootView = new LinearLayout(c); - rootView.setOrientation(LinearLayout.VERTICAL); - rootView.addView(getTextViewWithText(c, getS(RR.DriveD_Explain))); - - TextInputLayout textInputLayout = new TextInputLayout(c); - textInputLayout.addView(setupETPar()); - rootView.addView(textInputLayout); - - TextInputLayout textInputLayout2 = new TextInputLayout(c); - textInputLayout2.addView(setupETDst()); - rootView.addView(textInputLayout2); - - tvTestResult.setTextIsSelectable(true); - rootView.addView(tvTestResult); - - - rootView.addView(getOneLineWithTitle(c, getS(RR.DriveD_DescTitle), getTextViewWithText(c, getS(RR.DriveD_DescCont)), false)); - //初始化当前路径 - tvInputDstDir.setText(getPreference().getString(PREF_KEY_DST_NAME, PREF_VAL_DST_NAME)); - updateCurrentParDir(getPreference().getInt(PREF_KEY_PAR_IND, 0)); - return rootView; - } - - /** - * 当本dialog关闭时的操作 - */ - @Override - public void onClick(DialogInterface dialog, int which) { - if (which == BUTTON_POSITIVE) { - //将设置更新到preference。整个dialog应该只有此时向pref中写入数据 - if (checkCurrDirAvailable() - //如果当前路径可用,且设置与之前设置不一样了 - && (currentParDir != getPreference().getInt(PREF_KEY_PAR_IND, 0) - || !currentDstDirName.equals(getPreference().getString(PREF_KEY_DST_NAME, PREF_VAL_DST_NAME)) - ) - - ) { - getPreference().edit().putInt(PREF_KEY_PAR_IND, currentParDir).putString(PREF_KEY_DST_NAME, currentDstDirName).apply(); -// Toast.makeText(requireActivity(), "设置已更新", Toast.LENGTH_SHORT).show(); - Snackbar.make(FabMenu.getMainFrameView((AppCompatActivity) requireActivity()), getS(RR.DriveD_SncBrTxt), Snackbar.LENGTH_LONG) - .setAction(getS(RR.DriveD_SncBrBtn), v -> android.os.Process.killProcess(android.os.Process.myPid())) - .show(); - } else { - Snackbar.make(FabMenu.getMainFrameView((AppCompatActivity) requireActivity()), getS(RR.DriveD_ToastExitFail), Snackbar.LENGTH_LONG).show(); - } - } else if (which == BUTTON_NEGATIVE) { - Snackbar.make(FabMenu.getMainFrameView((AppCompatActivity) requireActivity()), getS(RR.DriveD_ToastExitFail), Snackbar.LENGTH_LONG).show(); - } - } - - /** - * 设置文件夹名称的edittext - */ - private MyTextInputEditText setupETDst() { - tvInputDstDir = new MyTextInputEditText(requireContext(), dstDirArrKeys, dstDirArrVals, getS(RR.DriveD_EditDstTitle)); - tvInputDstDir.setInputType( - InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); -// InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;用于禁用语法检查 - tvInputDstDir.setSingleLine(); - tvInputDstDir.setImeOptions(EditorInfo.IME_ACTION_DONE); - tvInputDstDir.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void afterTextChanged(Editable s) { - updateCurrentDstDir(s.toString().trim()); - } - }); - return tvInputDstDir; - } - - /** - * 更新文件夹名称请调用edittext.settext,然后会自动触发这个函数。 - * 输入的当前文件夹名称更新后,更新成员变量currentDstDir(不要在这里设置edittext文本显示,否则会循环调用) - * 然后重新检查可用性并将结果显示到textview上 - * - * @param s 新更新的文件夹名称 - */ - private void updateCurrentDstDir(String s) { - currentDstDirName = s; - checkCurrDirAvailable(); - } - - /** - * 设置文件夹父目录的edittext - */ - private MyTextInputEditText setupETPar() { - tvInputParDir = new MyTextInputEditText(requireContext(), null, null, getS(RR.DriveD_EditParTitle)); - tvInputParDir.setInputType(InputType.TYPE_NULL); - //设置弹窗菜单 - PopupMenu popupMenu = new PopupMenu(requireContext(), this.tvInputParDir); - for (int i = 0; i < parDirArrKeys.length; i++) { - popupMenu.getMenu().add(Menu.NONE, i, Menu.NONE, parDirArrKeys[i]).setOnMenuItemClickListener(item -> { - //点击某个选项后更新成员变量和tv的文件夹父目录 - updateCurrentParDir(item.getItemId()); - return true; - }); - } -// tvInputParDir.setPopupMenu(popupMenu); - return tvInputParDir; - } - - /** - * 更新父目录应调用此函数。 - * 输入的当前文件夹父目录更新后,更新成员变量currentParDir以及edittext显示 - * 然后重新检查可用性并将结果显示到textview上 - * - * @param i 新更新的文件夹父目录 - */ - private void updateCurrentParDir(int i) { - currentParDir = i; - File file = dirEnumToFile(parDirArrVals[currentParDir]); - this.tvInputParDir.setText(file == null ? getS(RR.DriveD_getPathFail) : file.getAbsolutePath()); - checkCurrDirAvailable(); - } - - /** - * 检查当前设置的文件夹是否有效,并将检查结果显示到textview上 - * - * @return 是否有效 - */ - private boolean checkCurrDirAvailable() { - int result = 0; - //先更新一下文件夹名(不允许文件夹名为空,如果为""就改成Download) (不更新了,最后点击确定的时候再说吧) - //如果文件夹或父目录获取不到返回false。 - if (currentDstDirName == null || currentDstDirName.equals("") || dirEnumToFile(parDirArrVals[currentParDir]) == null) { -// tvInputDstDir.setText(dstDirArrVals[0]); - setTvTestResult(null, result); - return false; - } - String str = null; - try { - File dstFile = new File(dirEnumToFile(parDirArrVals[currentParDir]), currentDstDirName); - //用位记录吧.从低位到高位:父目录是否存在,文件夹是否存在,是否为文件夹,是否可读,是否可写 - result = 0b00000001 - | (dstFile.exists() ? 1 : 0) << 1 - | (dstFile.isDirectory() ? 1 : 0) << 2 - | (dstFile.canRead() ? 1 : 0) << 3 - | (dstFile.canWrite() ? 1 : 0) << 4; - } catch (Exception e) { - str = e.getLocalizedMessage(); - } - setTvTestResult(str, result); - return result == 0b00011111; - } - - /** - * 设置测试结果的文字到tv - * - * @param s 文字 - * @param checkFlag 类型,0为错误,1为成功,null为exception - */ - private void setTvTestResult(String s, int checkFlag) { - SpannableStringBuilder str = new SpannableStringBuilder("\n"); - //有报错,或者没权限,或者无法获取路径,不进行下一步测试,直接红色消息显示商。 - if (s != null) { - str.append(s); - str.setSpan(new ForegroundColorSpan(0xffF56C6C), str.length() - s.length(), str.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } - //检查是否有存储权限 - else if (ContextCompat.checkSelfPermission(requireActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - str.append(getS(RR.DriveD_NoStrgPmsn)); - str.setSpan(new ForegroundColorSpan(0xffF56C6C), str.length() - getS(RR.DriveD_NoStrgPmsn).length(), str.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.fromParts("package", requireContext().getPackageName(), null)); - startActivity(intent); - } - //如果父路径或子路径为null - else if (dirEnumToFile(parDirArrVals[currentParDir]) == null || currentDstDirName == null || "".equals(currentDstDirName)) { - str.append(getS(RR.DriveD_getPathFail)); - str.setSpan(new ForegroundColorSpan(0xffF56C6C), str.length() - getS(RR.DriveD_getPathFail).length(), str.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } - //获取文件夹file,并检查是否可用 - else { - File parFile = dirEnumToFile(parDirArrVals[currentParDir]); - boolean stillGood = true; //判断当前是否已经循环到错误的地方。如果是的话下面都改成灰色 - String completePath = parFile.getAbsolutePath() + "/" + currentDstDirName; - str.append(completePath); - str.setSpan(new StyleSpan(Typeface.BOLD), str.length() - completePath.length(), str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - str.append("\n\n"); - for (int i = 0; i < 5; i++) { - str.append(testCheckStr[i]); - if (stillGood) { - stillGood = ((checkFlag >> i) & 0b000000001) == 1; - str.append(stillGood ? " √" : " ×"); - str.setSpan(new ForegroundColorSpan(stillGood ? 0xff67C23A : 0xffF56C6C), str.length() - 1, str.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } else { - str.setSpan(new StrikethroughSpan(), str.length() - testCheckStr[i].length(), str.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } - str.append('\n'); - } - - } - tvTestResult.setText(str); - } - - /** - * 初始化时,创建Exagear文件夹 - */ - @Override - public void callWhenFirstStart(AppCompatActivity activity) { - File file = new File(Environment.getExternalStorageDirectory(), PREF_VAL_DST_NAME); - if (!file.exists()) { - boolean b = file.mkdir(); - Log.d(TAG, "callWhenFirstStart: 初次安装后启动,尝试创建文件夹结果 " + b); - } - - } - - @Override - public String getTitle() { - return getS(RR.DriveD_Title); - } - - private enum ParDirEnum { - ExternalStorage, - ExternalFilesDir, - SDCardExternalFilesDir - } - - -// /** -// * 创建 “测试可用性”按钮 -// * -// * @return 按钮 -// */ -// private Button getValidateBtn() { -// Button btn = new Button(requireActivity()); -// btn.setText("测试可用性"); -// btn.setOnClickListener(v -> checkCurrDirAvailable()); -// return btn; -// } - //突然发现不是重启activity能解决的,放弃。让用户手动重启吧 -// @Override -// public void onDismiss(DialogInterface dialog) { -// super.onDismiss(dialog); -// Log.d(TAG, "onDismiss: actvity类型是 "+requireActivity().getClass()); -// if(requireActivity() instanceof EDMainActivity){ -// EDMainActivity a = (EDMainActivity) requireActivity(); -//// ((StartupActionsCollectionAware)Globals.getApplicationState()).getStartupActionsCollection().addAction(new EmptyAction()); -//// a.signalUserInteractionFinished(WDesktop.UserRequestedAction.RESTART_ME); -// Intent intent = new Intent(); -// intent.putExtra("AxsActivityResult", WDesktop.UserRequestedAction.RESTART_ME); -// a.setResult(2, intent); -// a.finish(); -// }else{ -// requireActivity().recreate(); -// } -// } -// private Button getBrowseBtn() { -// Button btn = new Button(requireActivity()); -// btn.setText("浏览文件夹"); -// btn.setOnClickListener(v -> { -// try { -// File file = new File(dirEnumToFile(parDirArrVals[currentParDir]), tvInputDstDir.getText().toString().trim()); -//// MediaScannerConnection.scanFile(requireContext(), new String[]{file.getAbsolutePath()}, null, -//// new MediaScannerConnection.OnScanCompletedListener() { -//// @Override -//// public void onScanCompleted(String path, Uri uri) { -//// Log.d(TAG, "onScanCompleted: 扫描完成,uri是啥样的" + uri + ", path是啥样的" + path); -//// if (uri != null) { -//// Intent intent = new Intent(Intent.ACTION_VIEW); -//// -////// DocumentsContract.Document.MIME_TYPE_DIR -//// intent.setDataAndType(uri, DocumentsContract.Document.MIME_TYPE_DIR); -//// //如果没有处理隐式intent的应用,用startActivity会崩溃 -//// if (intent.resolveActivity(requireActivity().getPackageManager()) != null) { -//// startActivity(intent); -//// } -//// } -//// } -//// }); -// -// Intent intent = new Intent(Intent.ACTION_SEND); -//// DocumentsContract.Document.MIME_TYPE_DIR -// intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); -// Uri uri = FileProvider.getUriForFile(requireActivity(), BuildConfig.APPLICATION_ID+".provider",file); -// Log.d(TAG, "getBrowseBtn: fileProvider获取的uri为"+uri); -// intent.putExtra(Intent.EXTRA_STREAM, uri); -// intent.setType(DocumentsContract.Document.MIME_TYPE_DIR); -//// intent.setDataAndType(Uri.parse("content://"+path), DocumentsContract.Document.MIME_TYPE_DIR); -// //如果没有处理隐式intent的应用,用startActivity会崩溃 -// if (intent.resolveActivity(requireActivity().getPackageManager()) != null) { -// startActivity(intent); -// } -// -// } catch (Exception e) { -// e.printStackTrace(); -// } -// -// }); -// return btn; -// } - -} diff --git a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/PulseAudio.java b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/PulseAudio.java index f67a336c..45e67eb4 100644 --- a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/PulseAudio.java +++ b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/PulseAudio.java @@ -1,20 +1,19 @@ package com.example.datainsert.exagear.FAB.dialogfragment; +import static android.animation.LayoutTransition.CHANGING; import static com.example.datainsert.exagear.RR.dimen.margin8Dp; import static com.example.datainsert.exagear.RR.getS; +import android.animation.LayoutTransition; import android.content.Context; import android.content.DialogInterface; import android.content.res.ColorStateList; -import android.graphics.Typeface; import android.graphics.drawable.RippleDrawable; import android.os.Build; import android.support.annotation.RequiresApi; import android.support.v7.app.AppCompatActivity; -import android.text.Editable; import android.text.TextUtils; import android.util.Log; -import android.util.TypedValue; import android.view.View; import android.view.ViewGroup; import android.widget.Button; @@ -29,6 +28,7 @@ import com.example.datainsert.exagear.QH; import com.example.datainsert.exagear.RR; +import org.apache.commons.compress.utils.CharsetNames; import org.apache.commons.io.FileUtils; import java.io.File; @@ -36,7 +36,6 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; -import java.util.StringTokenizer; public class PulseAudio extends BaseFragment { private final static File paWorkDir = new File(QH.Files.edPatchDir(), "pulseaudio-xsdl"); @@ -173,13 +172,13 @@ protected ViewGroup buildUI() { Context c = requireContext(); LinearLayout linearRoot = new LinearLayout(c); linearRoot.setOrientation(LinearLayout.VERTICAL); - LinearLayout.LayoutParams paddingParams = new LinearLayout.LayoutParams(-1, -2); - paddingParams.topMargin = margin8Dp(); + LinearLayout.LayoutParams topMarginParams = new LinearLayout.LayoutParams(-1, -2); + topMarginParams.topMargin = margin8Dp(); //顶端简介 TextView tvShortInfo = new TextView(c); tvShortInfo.setText(getS(RR.pa_explain)); - linearRoot.addView(tvShortInfo, paddingParams); + linearRoot.addView(tvShortInfo, topMarginParams); //立即停止和开始 // Button btnRunNow = new Button(c); @@ -200,13 +199,13 @@ protected ViewGroup buildUI() { // weightParams.weight=1; // linearRunOrStop.addView(btnRunNow,weightParams); // linearRunOrStop.addView(btnStopNow,weightParams); -// linearRoot.addView(linearRunOrStop,paddingParams); +// linearRoot.addView(linearRunOrStop,topMarginParams); //是否启动pulse服务 String[] checkRunStr = getS(RR.pa_checkRun).split("\\$"); CheckBox checkAutorun = new CheckBox(c); checkAutorun.setText(checkRunStr[0]); - linearRoot.addView(checkAutorun, paddingParams); + linearRoot.addView(checkAutorun, topMarginParams); linearRoot.addView(getDescriptionTextView(checkRunStr[1])); //输出日志(java的报错也放到这个文件里吧) @@ -216,7 +215,7 @@ protected ViewGroup buildUI() { checkEnableLog.setOnCheckedChangeListener((buttonView, isChecked) -> getPreference().edit().putBoolean(PREF_KEY_PULSE_ENABLE_LOG, isChecked).apply()); checkEnableLog.setChecked(getPreference().getBoolean(PREF_KEY_PULSE_ENABLE_LOG, true)); checkEnableLog.setEnabled(getPreference().getBoolean(PREF_KEY_PULSE_AUTORUN, PREF_DEF_VAL_PULSE_AUTORUN)); - linearRoot.addView(checkEnableLog, paddingParams); + linearRoot.addView(checkEnableLog, topMarginParams); linearRoot.addView(getDescriptionTextView(String.format(checkLogStr[1], requireContext().getPackageName()))); checkAutorun.setOnCheckedChangeListener((buttonView, isChecked) -> { @@ -260,9 +259,10 @@ protected ViewGroup buildUI() { linearEditLine.setVisibility(shouldExit ? View.GONE : View.VISIBLE); }); btnEditPars.setAllCaps(false);//禁止全大写 - linearRoot.addView(btnEditPars, paddingParams); + linearRoot.addView(btnEditPars, QH.LPLinear.one(-2,-2).top().to()); linearRoot.addView(linearEditLine, new LinearLayout.LayoutParams(-1, -2)); linearRoot.addView(getDescriptionTextView(btnParamsStr[1])); + linearRoot.setLayoutTransition(new LayoutTransition()); //强制重启 @@ -298,11 +298,12 @@ protected ViewGroup buildUI() { linearTrShText.addView(tvTbStSub, trShTxtParams); } - LinearLayout linearTblShooting = getOneLineWithTitle(requireContext(), trShTitleStr, linearTrShText, true);//"故障排查 ⓘ" + LinearLayout linearTblShooting = QH.getOneLineWithTitle(requireContext(), trShTitleStr, linearTrShText, true);//"故障排查 ⓘ" linearTrShText.setVisibility(View.GONE); linearTblShooting.getChildAt(0).setOnClickListener(v -> linearTrShText.setVisibility(linearTrShText.getVisibility() == View.GONE ? View.VISIBLE : View.GONE)); - linearRoot.addView(linearTblShooting, paddingParams); + + linearRoot.addView(linearTblShooting, topMarginParams); return linearRoot; } @@ -333,7 +334,15 @@ public static boolean shouldStartByPref(){ @Override public void callWhenFirstStart(AppCompatActivity activity) { - + //移除旧文件 + File oldWorkDir = new File(activity.getFilesDir(),"pulseaudio-xsdl"); + if(oldWorkDir.exists()) { + try { + FileUtils.moveDirectory(oldWorkDir,paWorkDir); + } catch (IOException e) { + e.printStackTrace(); + } + } } @Override diff --git a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/VirGLOverlay_old.java b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/VirGLOverlay_old.java deleted file mode 100644 index 053f7cc2..00000000 --- a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/VirGLOverlay_old.java +++ /dev/null @@ -1,396 +0,0 @@ -package com.example.datainsert.exagear.FAB.dialogfragment; - -import android.annotation.SuppressLint; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.graphics.Color; -import android.graphics.drawable.ColorDrawable; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.provider.Settings; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.v7.app.AppCompatActivity; -import android.util.Log; -import android.util.TypedValue; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.RadioButton; -import android.widget.RadioGroup; -import android.widget.ScrollView; -import android.widget.TextView; - -import com.eltechs.axs.Globals; -import com.eltechs.axs.helpers.AndroidHelpers; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; - -public class VirGLOverlay_old extends BaseFragment { - @NonNull - @Override - public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { - View root = buildUI(); - - return new AlertDialog.Builder(requireContext()) - .setView(root) - .create(); - } - - //以下是从OverlayBuildUI复制过来的 - - public static final String T = "VirGL Overlay"; - //#define FL_GLX (1<<1) - public static final int FL_GLES = (1 << 2); - //#define FL_OVERLAY (1<<3) - public static final int FL_MULTITHREAD = (1 << 4); - public int overlay_position_var = 0, restart_var = 0, protocol_version = 0; - public int dxtn_decompress = 0; - - // private final AppCompatActivity a; - //选项 - EditText socket_path; - CheckBox protocol_version_box; - CheckBox use_gles; - CheckBox use_threads; - CheckBox dxtn_decompress_box; - CheckBox restart_box; - RadioGroup radioGroup; - RadioButton overlay_topleft; - RadioButton overlay_centered; - RadioButton overlay_hide; - Button clearButton; - Button startButton; - - /** - * 添加vo布局到ed布局 - */ - @SuppressLint("SetTextI18n") - @Override - protected ViewGroup buildUI() { - AppCompatActivity a = (AppCompatActivity) requireActivity(); - Log.d("", "OverlayBuildUI: 初始化overlay服务的选项"); -// this.a=a; - socket_path = new EditText(a); - protocol_version_box = new CheckBox(a); - use_gles = new CheckBox(a); - use_threads = new CheckBox(a); - dxtn_decompress_box = new CheckBox(a); - restart_box = new CheckBox(a); - - radioGroup = new RadioGroup(a); - overlay_topleft = new RadioButton(a); - overlay_centered = new RadioButton(a); - overlay_hide = new RadioButton(a); - - clearButton = new Button(a); - startButton = new Button(a); - - - //检查悬浮窗权限 - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(a)) { - Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + a.getPackageName())); - a.startActivity(intent); - } - - //overlay布局的最外层 - LinearLayout root = new LinearLayout(a); - root.setOrientation(LinearLayout.VERTICAL); - root.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE); //显示分割线 - root.setDividerDrawable(new ColorDrawable(Color.BLACK)); -// int padding = AndroidHelpers.dpToPx(10); -// root.setPadding(padding, padding, padding, 0 );//padding 5dp,底部10dp -// root.setBackgroundColor(Color.parseColor("#16B5BAB9")); -// root.setElevation(-3); - - //标题 - TextView viewTitle = new TextView(a); - viewTitle.setText("VirGL Overlay 服务"); - viewTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); - viewTitle.setTextColor(Color.BLACK); - int padding = AndroidHelpers.dpToPx(8); - viewTitle.setPadding(padding, padding, padding, padding); - - //多选项 - protocol_version_box.setText("使用vtest协议2(需要Mesa 19.1.0 v3及以上)"); - use_gles.setText("使用GL ES 3.x而不是OpenGL"); - use_threads.setText("使用多线程egl访问"); - dxtn_decompress_box.setText("DXTn(S3纹理压缩)解压(一些游戏需要)"); - restart_box.setText("自动重启服务"); - - LinearLayout checkBoxRoot = new LinearLayout(a); - checkBoxRoot.setOrientation(LinearLayout.VERTICAL); - checkBoxRoot.setPadding(padding, padding, padding, padding); - addSomeViews(checkBoxRoot, protocol_version_box, use_gles, use_threads, dxtn_decompress_box, restart_box); - - //单选组(覆盖位置) - radioGroup.setOrientation(RadioGroup.HORIZONTAL); - overlay_topleft.setText("左上方"); - overlay_centered.setText("居中"); - overlay_hide.setText("隐藏*"); - addSomeViews(radioGroup, overlay_topleft, overlay_centered, overlay_hide); - - TextView overlayPosTextView = new TextView(a); - overlayPosTextView.setText("覆盖位置:"); - TextView overlayExplainTextView = new TextView(a); - overlayExplainTextView.setText("* 与VTEST_WIN=1一起使用以在X11窗口中绘制,而不是悬浮窗覆盖"); - - LinearLayout overlayRoot = new LinearLayout(a); - overlayRoot.setOrientation(LinearLayout.VERTICAL); - overlayRoot.setPadding(padding, padding, padding, padding); - addSomeViews(overlayRoot, overlayPosTextView, radioGroup, overlayExplainTextView); - - //socket path - LinearLayout socketPathRootView = new LinearLayout(a); - TextView socketPathText = new TextView(a); - socketPathText.setText("Socekt path (/tmp/.virgl_test):"); - addSomeViews(socketPathRootView, socketPathText, socket_path); - - //按钮 - clearButton.setText("清除服务"); - startButton.setText("开始服务"); - - LinearLayout buttonRoot = new LinearLayout(a); - LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT); - params.weight = 0.5f; - buttonRoot.addView(clearButton, params); - buttonRoot.addView(startButton, params); - - //其他说明 - TextView thanksText = new TextView(a); - thanksText.setText("Original APK with native library by mittorn: https://github.com/mittorn/virglrenderer-android; https://github.com/mittorn/virglrenderer\n\nRebuild APk v0.0.9 (mod) by alexvorxx\nThe following code was used in this version:\nvirglrenderer-0.10.0: https://github.com/freedesktop/virglrenderer\nlibepoxy-1.5.10: https://github.com/anholt/libepoxy\ngl4es-1.1.4: https://github.com/ptitSeb/gl4es\nSpecial thanks to mittorn for help and advices. Thanks to gabreek for the useful option: https://github.com/gabreek/Virgl-Overlay-Rebuild_mod"); - thanksText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 7); - - //添加到根布局 - addSomeViews(root, viewTitle, checkBoxRoot, overlayRoot, socketPathRootView, buttonRoot, thanksText); - - //设置按钮监听 - clearButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - onClickClean(); - } - }); - startButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - onClickStart(); - } - }); - - //原activity的onCreate - int flags = 0; - - boolean z = true; - try { -// CharBuffer.allocate(128); - FileReader settings_reader = new FileReader(a.getFilesDir().getPath() + "/settings"); - BufferedReader reader = new BufferedReader(settings_reader); - String[] parts = reader.readLine().split(" "); - flags = Integer.parseInt(parts[0]); - try { - socket_path.setText(parts[1]); - reader.close(); - settings_reader.close(); - } catch (Exception e) { - e.printStackTrace(); - reader.close(); - settings_reader.close(); - } - } catch (Exception e) { - e.printStackTrace(); - } - try { - FileReader settings_reader1 = new FileReader(a.getFilesDir().getPath() + "/settings2"); - BufferedReader reader1 = new BufferedReader(settings_reader1); - String[] parts1 = reader1.readLine().split(" "); - this.overlay_position_var = Integer.parseInt(parts1[0]); - this.restart_var = Integer.parseInt(parts1[1]); - this.protocol_version = Integer.parseInt(parts1[2]); - this.dxtn_decompress = Integer.parseInt(parts1[3]); - reader1.close(); - settings_reader1.close(); - } catch (Exception e) { - e.printStackTrace(); - } - use_gles.setChecked((flags & FL_GLES) != 0); - use_threads.setChecked((flags & FL_MULTITHREAD) != 0); - restart_box.setChecked(this.restart_var != 0); - protocol_version_box.setChecked(this.protocol_version != 0); - dxtn_decompress_box.setChecked(this.dxtn_decompress != 0); - overlay_topleft.setChecked(this.overlay_position_var == 0); - overlay_centered.setChecked(this.overlay_position_var == 1); - overlay_hide.setChecked(overlay_position_var == 2); - -// //root加入scrollview -// ScrollView scrollView = new ScrollView(a); -// scrollView.setScrollbarFadingEnabled(false); -// scrollView.setVerticalScrollBarEnabled(true); -// scrollView.setScrollBarSize( AndroidHelpers.dpToPx(9)); //9dp -// //高度固定130dp -// ViewGroup.LayoutParams scrollParams =new LinearLayout.LayoutParams(-1, AndroidHelpers.dpToPx(130));//130dp -// scrollView.setLayoutParams(scrollParams); -// scrollView.addView(root); -// //底部阴影(20dp) -// TextView tv3 = new TextView(a); -// RelativeLayout.LayoutParams tv3Params = new RelativeLayout.LayoutParams(-1, AndroidHelpers.dpToPx(20)); -// tv3Params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); -// tv3.setLayoutParams(tv3Params); -// GradientDrawable gradientDrawable = new GradientDrawable(); -// gradientDrawable.setColors(new int[]{Color.parseColor("#19D5D5D5"),Color.parseColor("#DD122647")}); -// tv3.setBackground(gradientDrawable); -// //包裹阴影和滚动视图的相对布局 -// RelativeLayout shadowWrapper = new RelativeLayout(a); -// shadowWrapper.setLayoutParams(scrollParams); //借用一下scroll的布局参数,也就是宽高 -// shadowWrapper.addView(scrollView); -// shadowWrapper.addView(tv3); - - -// //添加ov布局到ed布局中(这里改到ex里的时候替换一下) -// LinearLayout layout = a.findViewById(RSIDHelper.rslvID(R.id.ed_main_content_frame,0x7f09006e)); -// if(layout!=null) -// layout.addView(shadowWrapper, 1); -// else -// Log.d("TAG", "buildUI: 没找到挂载的根视图,无法添加设置视图"); - - ScrollView rootScrollView = new ScrollView(a); - rootScrollView.setScrollbarFadingEnabled(false); - rootScrollView.setVerticalScrollBarEnabled(true); - rootScrollView.setPadding(40, 40, 40, 40); - rootScrollView.addView(root); - return rootScrollView; - - } - - - /** - * 点击清除按钮后 - */ - public void onClickClean() { - Context a = Globals.getAppContext(); - if (restart_var == 1) { - writeStop(1); - } - for (int i = 1; i < 32; i++) { - try { - a.stopService(new Intent().setClassName(a, "com.mittorn.virgloverlay.process.p" + i)); - } catch (Exception e) { - e.printStackTrace(); - } - } - Log.d(T, "All services cleaned! resart_var为" + restart_var + "; 若为1则应调用writeStop(0)"); - if (restart_var == 1) { - writeStop(0); - } - } - - public void writeStop(int stop) { - Context a = Globals.getAppContext(); - try { - FileWriter writer3 = new FileWriter(a.getFilesDir().getPath() + "/stop"); - Log.d("", "writeStop: " + a.getFilesDir().getPath() + "/stop 写入值为" + stop); - writer3.write(String.valueOf(stop)); - writer3.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * 点击开始服务按钮后 - */ - public void onClickStart() { - Context a = Globals.getAppContext(); - try { - if (overlay_topleft.isChecked()) { - overlay_position_var = 0; - } else if (overlay_centered.isChecked()) { - overlay_position_var = 1; - } else if (overlay_hide.isChecked()) { - overlay_position_var = 2; - } - if (restart_box.isChecked()) { - restart_var = 1; - } else { - restart_var = 0; - } - if (protocol_version_box.isChecked()) { - protocol_version = 1; - } else { - protocol_version = 0; - } - if (dxtn_decompress_box.isChecked()) { - dxtn_decompress = 1; - } else { - dxtn_decompress = 0; - } - FileWriter fileWriter = new FileWriter(a.getFilesDir().getPath() + "/settings2"); - fileWriter.write(String.valueOf(overlay_position_var)); - fileWriter.write(' '); - fileWriter.write(String.valueOf(restart_var)); - fileWriter.write(' '); - fileWriter.write(String.valueOf(protocol_version)); - fileWriter.write(' '); - fileWriter.write(String.valueOf(dxtn_decompress)); - fileWriter.close(); - - int flags = 0; - if (use_gles.isChecked()) - flags |= FL_GLES; - if (use_threads.isChecked()) - flags |= FL_MULTITHREAD; - - FileWriter writer = new FileWriter(a.getFilesDir().getPath() + "/settings"); - writer.write(String.valueOf(flags)); - writer.write(' '); - writer.write(socket_path.getText().toString()); - writer.close(); - if (restart_var == 1) { - writeStop(0); - } - a.startService(new Intent().setClassName(a, "com.mittorn.virgloverlay.process.p1")); - Log.d(T, "Service p1 started!"); - } catch (Exception e) { - e.printStackTrace(); - Log.d(T, "Service p1 failed!"); - } - } - - - /** - * 向一个父布局中添加多个子布局 - * - * @param parent 父布局 - * @param sons 子布局 - */ - private void addSomeViews(ViewGroup parent, View... sons) { - for (View v : sons) { - parent.addView(v); - } - } - - @Override - public void callWhenFirstStart(AppCompatActivity activity) { - - } - - @Override - public String getTitle() { - return "virgl overlay"; - } - - @Override - public void onClick(DialogInterface dialog, int which) { - - } -} diff --git a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/VirglOverlay.java b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/VirglOverlay.java index 715aeef6..8479394a 100644 --- a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/VirglOverlay.java +++ b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/VirglOverlay.java @@ -60,9 +60,6 @@ public class VirglOverlay extends BaseFragment { * edpatch无法修改xml,所以只能是在原本已经存在旧VIRGL overlay的情况下显示。检查:libvirgl-lib.so,com.mittorn.virgloverlay包 */ public static boolean isAlreadyExist(Context c) { -// if(!QH.isTesting()) -// return false; - if(QH.isTesting()) return true; @@ -82,7 +79,6 @@ public static boolean isAlreadyExist(Context c) { e.printStackTrace(); } return false; - } @SuppressLint("SetTextI18n") diff --git a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/SubView1Mouse.java b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/SubView1Mouse.java index 143e9c64..b4fb58b4 100644 --- a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/SubView1Mouse.java +++ b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/SubView1Mouse.java @@ -1,6 +1,5 @@ package com.example.datainsert.exagear.FAB.dialogfragment.customcontrols; -import static com.example.datainsert.exagear.FAB.dialogfragment.BaseFragment.getOneLineWithTitle; import static com.example.datainsert.exagear.FAB.dialogfragment.BaseFragment.getPreference; import static com.example.datainsert.exagear.FAB.dialogfragment.BaseFragment.setDialogTooltip; import static com.example.datainsert.exagear.RR.cmCtrl_s1_msMoveViewport; @@ -33,11 +32,12 @@ import com.example.datainsert.exagear.RR; public class SubView1Mouse extends LinearLayout { + private static final String TAG = "SubView1Mouse"; SeekBar seekPointerSpeed; Button btnResetSpeed; LinearLayout viewportOptions; CheckBox checkMsViewport; - private static final String TAG= "SubView1Mouse"; + public SubView1Mouse(Context c) { super(c); setOrientation(VERTICAL); @@ -59,28 +59,28 @@ public SubView1Mouse(Context c) { //鼠标灵敏度 0.2~3.0, 设置值从0到280 seekPointerSpeed = new SeekBar(c); seekPointerSpeed.setMax(280); - seekPointerSpeed.setProgress(getPreference().getInt(PREF_KEY_MOUSE_SENSITIVITY,80)); - seekPointerSpeed.setOnSeekBarChangeListener(new SimpleSeekBarChangeListener((seekBar, progress, fromUser) -> getPreference().edit().putInt(PREF_KEY_MOUSE_SENSITIVITY,progress).apply())); + seekPointerSpeed.setProgress(getPreference().getInt(PREF_KEY_MOUSE_SENSITIVITY, 80)); + seekPointerSpeed.setOnSeekBarChangeListener(new SimpleSeekBarChangeListener((seekBar, progress, fromUser) -> getPreference().edit().putInt(PREF_KEY_MOUSE_SENSITIVITY, progress).apply())); //重置灵敏度按钮 btnResetSpeed = new Button(c); btnResetSpeed.setText(getS(RR.cmCtrl_reset)); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { btnResetSpeed.setTextAppearance(android.R.style.TextAppearance_Material_Widget_Button_Borderless_Colored); - btnResetSpeed.setBackground(new RippleDrawable(ColorStateList.valueOf(0x44444444),null,btnResetSpeed.getBackground())); + btnResetSpeed.setBackground(new RippleDrawable(ColorStateList.valueOf(0x44444444), null, btnResetSpeed.getBackground())); } - btnResetSpeed.setOnClickListener(v-> seekPointerSpeed.setProgress(80)); + btnResetSpeed.setOnClickListener(v -> seekPointerSpeed.setProgress(80)); LinearLayout linearSeekNBtn = new LinearLayout(c); - LayoutParams seekParams = new LayoutParams(0,-2,1); - seekParams.gravity= Gravity.CENTER_VERTICAL; - linearSeekNBtn.addView(seekPointerSpeed,seekParams); - LayoutParams btnResetParams = new LayoutParams(-2,-2); - btnResetParams.gravity= Gravity.CENTER_VERTICAL; - linearSeekNBtn.addView(btnResetSpeed,btnResetParams); - LinearLayout linearSpeed = getOneLineWithTitle(c,getS(RR.cmCtrl_s1_msSpd),linearSeekNBtn,true); + LayoutParams seekParams = new LayoutParams(0, -2, 1); + seekParams.gravity = Gravity.CENTER_VERTICAL; + linearSeekNBtn.addView(seekPointerSpeed, seekParams); + LayoutParams btnResetParams = new LayoutParams(-2, -2); + btnResetParams.gravity = Gravity.CENTER_VERTICAL; + linearSeekNBtn.addView(btnResetSpeed, btnResetParams); + LinearLayout linearSpeed = QH.getOneLineWithTitle(c, getS(RR.cmCtrl_s1_msSpd), linearSeekNBtn, true); //再手动设置一下顶部边距为0吧不然距离太远了 - ((LayoutParams)linearSpeed.getChildAt(1).getLayoutParams()).topMargin = 0; + ((LayoutParams) linearSpeed.getChildAt(1).getLayoutParams()).topMargin = 0; linearSpeed.getChildAt(1).setLayoutParams(linearSpeed.getChildAt(1).getLayoutParams()); - setDialogTooltip(linearSpeed.getChildAt(0),getS(RR.cmCtrl_s1_msSpdTip)); + setDialogTooltip(linearSpeed.getChildAt(0), getS(RR.cmCtrl_s1_msSpdTip)); //鼠标绝对位置或相对位置 @@ -95,7 +95,7 @@ public SubView1Mouse(Context c) { addView(linearSpeed); //允许鼠标移出屏幕(视角转动模式) 用户手动调节速度吧 - // + // // seekViewport = new SeekBar(c); // seekViewport.setMax(60); // seekViewport.setProgress(getPreference().getInt(PREF_KEY_MOUSE_OFFWINDOW_DISTANCE,0)); @@ -103,29 +103,27 @@ public SubView1Mouse(Context c) { //类型为鼠标移动时显示选项 对应发送时间间隔。 SeekBar repeatIntervalSeek = new SeekBar(c); repeatIntervalSeek.setMax(100);//5-105 - repeatIntervalSeek.setOnSeekBarChangeListener(new SimpleSeekBarChangeListener((seekBar, progress, fromUser) -> getPreference().edit().putInt(PREF_KEY_MOUSE_VIEWPORT_INTERVAL,progress).apply())); - repeatIntervalSeek.setProgress(getPreference().getInt(PREF_KEY_MOUSE_VIEWPORT_INTERVAL,20)+5); + repeatIntervalSeek.setOnSeekBarChangeListener(new SimpleSeekBarChangeListener((seekBar, progress, fromUser) -> getPreference().edit().putInt(PREF_KEY_MOUSE_VIEWPORT_INTERVAL, progress).apply())); + repeatIntervalSeek.setProgress(getPreference().getInt(PREF_KEY_MOUSE_VIEWPORT_INTERVAL, 20) + 5); //类型为鼠标移动时显示选项 每次移动距离 SeekBar mouseMoveLenSeek = new SeekBar(c); mouseMoveLenSeek.setMax(60); //1-61 - mouseMoveLenSeek.setOnSeekBarChangeListener(new SimpleSeekBarChangeListener((seekBar, progress, fromUser) -> getPreference().edit().putInt(PREF_KEY_MOUSE_OFFWINDOW_DISTANCE,progress).apply())); - mouseMoveLenSeek.setProgress(getPreference().getInt(PREF_KEY_MOUSE_OFFWINDOW_DISTANCE,20)); + mouseMoveLenSeek.setOnSeekBarChangeListener(new SimpleSeekBarChangeListener((seekBar, progress, fromUser) -> getPreference().edit().putInt(PREF_KEY_MOUSE_OFFWINDOW_DISTANCE, progress).apply())); + mouseMoveLenSeek.setProgress(getPreference().getInt(PREF_KEY_MOUSE_OFFWINDOW_DISTANCE, 20)); String[] viewportStrs = getS(RR.cmCtrl_s1_msMoveViewport).split("\\$"); viewportOptions = new LinearLayout(c); viewportOptions.setOrientation(LinearLayout.HORIZONTAL); - viewportOptions.addView(getOneLineWithTitle(c,viewportStrs[1],repeatIntervalSeek,true),seekParams); - viewportOptions.addView(getOneLineWithTitle(c,viewportStrs[2],mouseMoveLenSeek,true),seekParams); - viewportOptions.getChildAt(0).setPadding(0,0,0,0); - viewportOptions.getChildAt(1).setPadding(0,0,0,0); + viewportOptions.addView(QH.getOneLineWithTitle(c, viewportStrs[1], repeatIntervalSeek, true), seekParams); + viewportOptions.addView(QH.getOneLineWithTitle(c, viewportStrs[2], mouseMoveLenSeek, true), seekParams); checkMsViewport = new CheckBox(c); checkMsViewport.setText(viewportStrs[0]); checkMsViewport.setOnCheckedChangeListener((buttonView, isChecked) -> { - getPreference().edit().putBoolean(PREF_KEY_MOUSE_VIEWPORT_ENABLE,isChecked).apply(); + getPreference().edit().putBoolean(PREF_KEY_MOUSE_VIEWPORT_ENABLE, isChecked).apply(); clickedMoveViewport(isChecked); }); - checkMsViewport.setChecked(getPreference().getBoolean(PREF_KEY_MOUSE_VIEWPORT_ENABLE,false)); + checkMsViewport.setChecked(getPreference().getBoolean(PREF_KEY_MOUSE_VIEWPORT_ENABLE, false)); // LinearLayout linearSeekViewport = getOneLineWithTitle(c,getS(RR.cmCtrl_s1_msOffScr),seekViewport,true); // setDialogTooltip(checkMsViewport, getS(RR.cmCtrl_s1_msOffScrTip)); @@ -149,7 +147,7 @@ public SubView1Mouse(Context c) { } - private void clickedCheckMoveRel(boolean isChecked){ + private void clickedCheckMoveRel(boolean isChecked) { getPreference().edit().putBoolean(PREF_KEY_MOUSE_MOVE_RELATIVE, isChecked).apply(); seekPointerSpeed.setEnabled(isChecked); @@ -160,8 +158,8 @@ private void clickedCheckMoveRel(boolean isChecked){ clickedMoveViewport(isChecked && checkMsViewport.isChecked()); } - private void clickedMoveViewport(boolean isChecked){ - viewportOptions.setVisibility(isChecked?VISIBLE:GONE); + private void clickedMoveViewport(boolean isChecked) { + viewportOptions.setVisibility(isChecked ? VISIBLE : GONE); // ((ViewGroup)viewportOptions.getChildAt(0)).getChildAt(1).setEnabled(isChecked); // ((ViewGroup)viewportOptions.getChildAt(1)).getChildAt(1).setEnabled(isChecked); } diff --git a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/SubView2Keys.java b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/SubView2Keys.java index a94c8dba..ecec6e32 100644 --- a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/SubView2Keys.java +++ b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/SubView2Keys.java @@ -1,6 +1,5 @@ package com.example.datainsert.exagear.FAB.dialogfragment.customcontrols; -import static com.example.datainsert.exagear.FAB.dialogfragment.BaseFragment.getOneLineWithTitle; import static com.example.datainsert.exagear.FAB.dialogfragment.BaseFragment.getPreference; import static com.example.datainsert.exagear.FAB.dialogfragment.BaseFragment.setDialogTooltip; import static com.example.datainsert.exagear.RR.getS; @@ -22,6 +21,7 @@ import com.example.datainsert.exagear.FAB.dialogfragment.customcontrols.widgets.AvailableKeysView; import com.example.datainsert.exagear.FAB.dialogfragment.customcontrols.widgets.BtnColAdapter; import com.example.datainsert.exagear.FAB.dialogfragment.customcontrols.widgets.BtnColRecyclerView; +import com.example.datainsert.exagear.QH; import com.example.datainsert.exagear.RR; import com.example.datainsert.exagear.controls.model.JoyParams; import com.example.datainsert.exagear.controls.model.KeyCodes2; @@ -89,27 +89,27 @@ public SubView2Keys(Context c, @NonNull KeyCodes2 keyCodes2, @NonNull KeyCodes3 radioKeyPos.addView(rdBtnSideBar); radioKeyPos.addView(rdBtnFreePos); radioKeyPos.setOnCheckedChangeListener((group, checkedId) -> { - int position = checkedId == rdBtnSideBarID?0:1; + int position = checkedId == rdBtnSideBarID ? 0 : 1; getPreference().edit().putBoolean(PREF_KEY_CUSTOM_BTN_POS, position == 1).apply(); mTwoWaysKeyGroups[position].setVisibility(VISIBLE); mTwoWaysKeyGroups[(position + 1) % 2].setVisibility(GONE); }); - LinearLayout oneLineSpinKeyPos = getOneLineWithTitle(c, getS(RR.cmCtrl_s2_layoutMode), radioKeyPos, true); + LinearLayout oneLineSpinKeyPos = QH.getOneLineWithTitle(c, getS(RR.cmCtrl_s2_layoutMode), radioKeyPos, true); setDialogTooltip(oneLineSpinKeyPos.getChildAt(0), getS(RR.cmCtrl_s2_layoutModeTip)); addView(oneLineSpinKeyPos); //左侧栏按键和右侧栏按键 LinearLayout linearSideColOuter = new LinearLayout(c); linearSideColOuter.setOrientation(VERTICAL); - LinearLayout linearLeftSide = getOneLineWithTitle(c, getS(RR.cmCtrl_s2_LSideTitle), getAddSideBarGroup(c, true), true); + LinearLayout linearLeftSide = QH.getOneLineWithTitle(c, getS(RR.cmCtrl_s2_LSideTitle), getAddSideBarGroup(c, true), true); setDialogTooltip(linearLeftSide.getChildAt(0), getS(RR.cmCtrl_s2_sideTitleTip)); linearSideColOuter.addView(linearLeftSide); - LinearLayout linearRightSide = getOneLineWithTitle(c, getS(RR.cmCtrl_s2_RSideTitle), getAddSideBarGroup(c, false), true); + LinearLayout linearRightSide = QH.getOneLineWithTitle(c, getS(RR.cmCtrl_s2_RSideTitle), getAddSideBarGroup(c, false), true); setDialogTooltip(linearRightSide.getChildAt(0), getS(RR.cmCtrl_s2_sideTitleTip)); linearSideColOuter.addView(linearRightSide); mTwoWaysKeyGroups[0] = linearSideColOuter; - addView(linearSideColOuter); + addView(linearSideColOuter, QH.LPLinear.one().top().to()); //按钮与容器画面重叠(思路有问题,这个废弃) // getPreference().getBoolean(PREF_KEY_BTN_ON_WIDGET, false); @@ -120,7 +120,7 @@ public SubView2Keys(Context c, @NonNull KeyCodes2 keyCodes2, @NonNull KeyCodes3 csPosKeyBtn.setText(getS(RR.cmCtrl_s2_selectBtn)); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { csPosKeyBtn.setTextAppearance(android.R.style.TextAppearance_Material_Widget_Button_Borderless_Colored); - csPosKeyBtn.setBackground(new RippleDrawable(ColorStateList.valueOf(0x44444444),null,csPosKeyBtn.getBackground())); + csPosKeyBtn.setBackground(new RippleDrawable(ColorStateList.valueOf(0x44444444), null, csPosKeyBtn.getBackground())); } csPosKeyBtn.setOnClickListener(v -> { boolean[] condition = new boolean[mKeyCodes3.getKeyList().size()]; @@ -153,14 +153,13 @@ public SubView2Keys(Context c, @NonNull KeyCodes2 keyCodes2, @NonNull KeyCodes3 //getS(RR.cmCtrl_s2_FreePosTitle) - mTwoWaysKeyGroups[1] = getOneLineWithTitle(c, null, csPosKeyBtn, true); + mTwoWaysKeyGroups[1] = QH.getOneLineWithTitle(c, null, csPosKeyBtn, true); addView(mTwoWaysKeyGroups[1]); //设置按键布局方式 两种方式显示一个,另一个隐藏 radioKeyPos.check(getPreference().getBoolean(PREF_KEY_CUSTOM_BTN_POS, false) ? rdBtnFreePosID : rdBtnSideBarID); - } @@ -230,7 +229,7 @@ public void syncKeyCodes2() { /** * radiobutton 选中哪个布局模式 . 0是左右侧栏 1是自由布局 */ - public void checkLayoutMode(int index){ + public void checkLayoutMode(int index) { } } diff --git a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/SubView3Style.java b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/SubView3Style.java index 1779c92d..6ed7ad17 100644 --- a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/SubView3Style.java +++ b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/SubView3Style.java @@ -2,7 +2,6 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; -import static com.example.datainsert.exagear.FAB.dialogfragment.BaseFragment.getOneLineWithTitle; import static com.example.datainsert.exagear.FAB.dialogfragment.BaseFragment.getPreference; import static com.example.datainsert.exagear.FAB.dialogfragment.BaseFragment.getTextViewWithText; import static com.example.datainsert.exagear.FAB.dialogfragment.BaseFragment.setDialogTooltip; @@ -70,26 +69,26 @@ public SubView3Style(Context c) { btnSample.setText(getS(RR.cmCtrl_s3_sampleBtn)); LinearLayout.LayoutParams btnSampleParams = new LinearLayout.LayoutParams(getPreference().getInt(PREF_KEY_BTN_WIDTH, -2), getPreference().getInt(PREF_KEY_BTN_HEIGHT, -2)); btnSampleParams.gravity = Gravity.CENTER; - addView(btnSample,btnSampleParams); + addView(btnSample, btnSampleParams); //按钮宽高 SeekBar seekBarWidth = new SeekBar(c); seekBarWidth.setMax(200); int width = getPreference().getInt(PREF_KEY_BTN_WIDTH, -2); - seekBarWidth.setProgress(width == -2 ? 0 : QH.dp(c,width)); + seekBarWidth.setProgress(width == -2 ? 0 : QH.dp(c, width)); seekBarWidth.setOnSeekBarChangeListener(new SimpleSeekBarChangeListener((seekBar, progress, fromUser) -> setBtnLayout(btnSample, true, progress))); SeekBar seekBarHeight = new SeekBar(c); seekBarHeight.setMax(200); int height = getPreference().getInt(PREF_KEY_BTN_HEIGHT, -2); - seekBarHeight.setProgress(height == -2 ? 0 : QH.dp(c,height)); + seekBarHeight.setProgress(height == -2 ? 0 : QH.dp(c, height)); seekBarHeight.setOnSeekBarChangeListener(new SimpleSeekBarChangeListener((seekBar, progress, fromUser) -> setBtnLayout(btnSample, false, progress))); LinearLayout linearWHSeek = new LinearLayout(c); linearWHSeek.addView(seekBarWidth, generateLayoutParams(eqWidthParams)); linearWHSeek.addView(seekBarHeight, generateLayoutParams(eqWidthParams)); - LinearLayout oneLineWHSeek = getOneLineWithTitle(c, getS(RR.cmCtrl_s3_btnSize), linearWHSeek, true); + LinearLayout oneLineWHSeek = QH.getOneLineWithTitle(c, getS(RR.cmCtrl_s3_btnSize), linearWHSeek, true); setDialogTooltip(oneLineWHSeek.getChildAt(0), getS(RR.cmCtrl_s3_btnSizeTip)); addView(oneLineWHSeek); @@ -145,24 +144,9 @@ public SubView3Style(Context c) { LinearLayout linearCAContent = new LinearLayout(c); linearCAContent.addView(editInColor, generateLayoutParams(eqWidthParams)); linearCAContent.addView(seekAlpha, generateLayoutParams(eqWidthParams)); - -// LinearLayout linearCAOuter = getOneLineWithTitle(c,"按钮颜色&透明度",linearCAContent,true ); -// setDialogTooltip(linearCAOuter.getChildAt(0),"按钮颜色为6位的十六进制颜色,如:FAFAFA。\n透明度为0-255,当透明度设置到0时,按钮背景完全透明,文字保留1/3的透明度。"); - - LinearLayout linearCAOuter = new LinearLayout(c); - linearCAOuter.setOrientation(LinearLayout.VERTICAL); - TextView tvTitleCA = getTextViewWithText(c, getS(RR.cmCtrl_s3_btnColor)); - tvTitleCA.getPaint().setFakeBoldText(true); - tvTitleCA.invalidate(); - setDialogTooltip(tvTitleCA, getS(RR.cmCtrl_s3_btnColorTip)); - linearCAOuter.addView(tvTitleCA); - LinearLayout.LayoutParams linearCAContentparams = new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT); - linearCAContentparams.setMarginStart(20); - linearCAOuter.addView(linearCAContent, linearCAContentparams); - linearCAOuter.setPadding(0, 20, 0, 0); - addView(linearCAOuter); -// addView(getOneLineWithTitle(c,getS(RR.cmCtrl_s3_btnColor),linearCAContent,true)); - + LinearLayout linearCAOuter = QH.getOneLineWithTitle(c, getS(RR.cmCtrl_s3_btnColor), linearCAContent, true); + setDialogTooltip(linearCAOuter.getChildAt(0), getS(RR.cmCtrl_s3_btnColorTip)); + addView(linearCAOuter, QH.LPLinear.one().top().to()); //侧栏背景颜色 EditText editSideColor = new EditText(c); @@ -187,38 +171,30 @@ public SubView3Style(Context c) { SeekBar seekTxtSize = new SeekBar(c); //10sp~30sp 默认14sp . progress在0~20 seekTxtSize.setMax(20); - seekTxtSize.setProgress(getPreference().getInt(PREF_KEY_BTN__TXT_SIZE,4)); + seekTxtSize.setProgress(getPreference().getInt(PREF_KEY_BTN__TXT_SIZE, 4)); seekTxtSize.setOnSeekBarChangeListener(new SimpleSeekBarChangeListener((seekBar, progress, fromUser) -> { - btnSample.setTextSize(TypedValue.COMPLEX_UNIT_SP,progress+10); - getPreference().edit().putInt(PREF_KEY_BTN__TXT_SIZE,progress).apply(); + btnSample.setTextSize(TypedValue.COMPLEX_UNIT_SP, progress + 10); + getPreference().edit().putInt(PREF_KEY_BTN__TXT_SIZE, progress).apply(); })); -// addView(linearTxtSize); - //二者标题 - LinearLayout linearShapeNTSizeTitle = new LinearLayout(c); - LinearLayout tvShapeTitle = getOneLineWithTitle(c,getS(RR.cmCtrl_s3_sideColor),null,false); - setDialogTooltip(tvShapeTitle,getS(RR.cmCtrl_s3_sideColorTip)); - linearShapeNTSizeTitle.addView(tvShapeTitle,generateLayoutParams(eqWidthParams)); - linearShapeNTSizeTitle.addView(getOneLineWithTitle(c,getS(RR.cmCtrl_s3_txtSize),null,false),generateLayoutParams(eqWidthParams)); - addView(linearShapeNTSizeTitle); - //二者内容 - LinearLayout linearShapeNTSize = new LinearLayout(c); - linearShapeNTSize.addView(editSideColor,generateLayoutParams(eqWidthParams)); - linearShapeNTSize.addView(seekTxtSize,generateLayoutParams(eqWidthParams)); - LayoutParams linearShapeNTSizeParams = new LayoutParams(-1,-2); - linearShapeNTSizeParams.setMarginStart(20); - addView(linearShapeNTSize,linearShapeNTSizeParams); - + LinearLayout linearSideColColor = QH.getOneLineWithTitle(c, getS(RR.cmCtrl_s3_sideColor), editSideColor, true); + LinearLayout linearTextSize = QH.getOneLineWithTitle(c, getS(RR.cmCtrl_s3_txtSize), seekTxtSize, true); + setDialogTooltip(linearSideColColor.getChildAt(0), getS(RR.cmCtrl_s3_sideColorTip)); + LinearLayout linearSideColorAndTxtSizeOuter = new LinearLayout(c); + linearSideColorAndTxtSizeOuter.setOrientation(HORIZONTAL); + linearSideColorAndTxtSizeOuter.addView(linearSideColColor, QH.LPLinear.one(0, -2).weight().gravity(Gravity.TOP).to()); + linearSideColorAndTxtSizeOuter.addView(linearTextSize, QH.LPLinear.one(0, -2).weight().gravity(Gravity.TOP).to()); + addView(linearSideColorAndTxtSizeOuter, QH.LPLinear.one().top().to()); //按钮形状(方形、圆形) CheckBox checkShapeRound = new CheckBox(c); checkShapeRound.setText(getS(RR.cmCtrl_s3_btnRoundShape)); - boolean initIsRound = getPreference().getBoolean(PREF_KEY_BTN_ROUND_SHAPE,false); + boolean initIsRound = getPreference().getBoolean(PREF_KEY_BTN_ROUND_SHAPE, false); checkShapeRound.setChecked(initIsRound); - checkShapeRound.setOnCheckedChangeListener((buttonView, isChecked) -> setBtnShape(btnSample,isChecked)); - LayoutParams shapeRoundParams = new LayoutParams(-2,-2); + checkShapeRound.setOnCheckedChangeListener((buttonView, isChecked) -> setBtnShape(btnSample, isChecked)); + LayoutParams shapeRoundParams = new LayoutParams(-2, -2); shapeRoundParams.topMargin = 20; - addView(checkShapeRound,shapeRoundParams); + addView(checkShapeRound, shapeRoundParams); } @@ -243,18 +219,18 @@ private void setBtnLayout(Button btnSample, boolean isWidth, int size) { * 设置按钮形状为方形或圆形,并将数据写入sp * 设置形状后drawable会改变。所以只能每次设置时新建一个drawable设置到按钮背景上了。 */ - private void setBtnShape(Button btnSample, boolean isRound){ - getPreference().edit().putBoolean(PREF_KEY_BTN_ROUND_SHAPE,isRound).apply(); + private void setBtnShape(Button btnSample, boolean isRound) { + getPreference().edit().putBoolean(PREF_KEY_BTN_ROUND_SHAPE, isRound).apply(); // RippleDrawable->InsetDrawable->GradientDrawable 但设置完一次之后insetDrawable就没了?? // 貌似调用了mutate()很多属性都合并了,之前的透明度丢失问题也出现了。 // 那就没法多次修改现有drawable了, try { GradientDrawable gradientDrawable = new GradientDrawable(); - gradientDrawable.setCornerRadius(QH.px(getContext(),4)); - gradientDrawable.setShape(isRound?GradientDrawable.OVAL:GradientDrawable.RECTANGLE); + gradientDrawable.setCornerRadius(QH.px(getContext(), 4)); + gradientDrawable.setShape(isRound ? GradientDrawable.OVAL : GradientDrawable.RECTANGLE); gradientDrawable.setColor(ColorStateList.valueOf(getPreference().getInt(PREF_KEY_BTN_BG_COLOR, Color.WHITE))); - InsetDrawable insetDrawable = new InsetDrawable(gradientDrawable,QH.px(getContext(),4)); + InsetDrawable insetDrawable = new InsetDrawable(gradientDrawable, QH.px(getContext(), 4)); RippleDrawable rippleDrawable = new RippleDrawable( ColorStateList.valueOf(getPreference().getInt(PREF_KEY_BTN_TXT_COLOR, Color.BLACK) & 0x50ffffff), insetDrawable, @@ -274,7 +250,7 @@ private void setBtnShape(Button btnSample, boolean isRound){ // gradientDrawable = (GradientDrawable) ((InsetDrawable)rippleDrawable.getDrawable(0)).getDrawable(); // assert gradientDrawable != null; // gradientDrawable.setShape(isRound?GradientDrawable.OVAL:GradientDrawable.RECTANGLE); - }catch (Exception e){ + } catch (Exception e) { Log.e(TAG, "setBtnShape: 无法获取按钮的GradientDrawable,无法设置形状", e); } diff --git a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/SubView4Other.java b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/SubView4Other.java index 571cd88b..111b41a5 100644 --- a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/SubView4Other.java +++ b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/SubView4Other.java @@ -1,7 +1,6 @@ package com.example.datainsert.exagear.FAB.dialogfragment.customcontrols; import static android.content.ClipDescription.MIMETYPE_TEXT_PLAIN; -import static com.example.datainsert.exagear.FAB.dialogfragment.BaseFragment.getOneLineWithTitle; import static com.example.datainsert.exagear.FAB.dialogfragment.BaseFragment.setDialogTooltip; import static com.example.datainsert.exagear.RR.getS; @@ -50,7 +49,7 @@ * 一些说明。导入导出功能 */ public class SubView4Other extends LinearLayout { - private static final String TAG= "SubView4Other"; + private static final String TAG = "SubView4Other"; TransferCallback mCallback; public SubView4Other(Context context) { @@ -76,7 +75,7 @@ public SubView4Other(Context context) { LinearLayout linear2Btn = new LinearLayout(c); linear2Btn.addView(btnExport, new LayoutParams(-2, -2)); linear2Btn.addView(btnImport, new LayoutParams(-2, -2)); - LinearLayout linearTransfer = getOneLineWithTitle(c, getS(RR.cmCtrl_s4_trsportTitle), linear2Btn, true); + LinearLayout linearTransfer = QH.getOneLineWithTitle(c, getS(RR.cmCtrl_s4_trsportTitle), linear2Btn, true); setDialogTooltip(linearTransfer.getChildAt(0), getS(RR.cmCtrl_s4_trsportTip)); addView(linearTransfer); @@ -90,19 +89,19 @@ public SubView4Other(Context context) { btnSelect.setText("编辑配置"); btnSelect.setOnClickListener(v -> { File[] profiles = CustomControls.dataDir().listFiles(pathname -> pathname.isDirectory()); - String currProfileName= getCurrProfileName(); + String currProfileName = getCurrProfileName(); PopupMenu popupMenu = new PopupMenu(c, v); Menu menu = popupMenu.getMenu(); menu.add("新建").setOnMenuItemClickListener(item -> { - File newPro =createNewProfile("new"); + File newPro = createNewProfile("new"); makeProfileCurrent(newPro.getName()); mCallback.dismiss(); return true; }); - menu.add("导入").setOnMenuItemClickListener(item->{ + menu.add("导入").setOnMenuItemClickListener(item -> { File importProfileDir = null; try { - Log.d("SubView4Other", "SubView4Other: 旧配置名:"+currProfileName); + Log.d("SubView4Other", "SubView4Other: 旧配置名:" + currProfileName); ClipboardManager clipboard = (ClipboardManager) c.getSystemService(Context.CLIPBOARD_SERVICE); if (clipboard.getPrimaryClip() == null || !(clipboard.hasPrimaryClip()) || !(Objects.requireNonNull(clipboard.getPrimaryClipDescription()).hasMimeType(MIMETYPE_TEXT_PLAIN))) { @@ -120,13 +119,13 @@ public SubView4Other(Context context) { mCallback.dismiss(); Toast.makeText(c, getS(RR.cmCtrl_s4_importResult).split("\\$")[0], Toast.LENGTH_SHORT).show(); - }catch (Exception e){ + } catch (Exception e) { e.printStackTrace(); mCallback.dismiss(); //如果导入失败,删除新存档文件夹,恢复旧存档为curr - if(importProfileDir!=null) + if (importProfileDir != null) FileUtils.deleteQuietly(importProfileDir); - if(currProfileName!=null) + if (currProfileName != null) makeProfileCurrent(currProfileName); Toast.makeText(c, getS(RR.cmCtrl_s4_importResult).split("\\$")[1], Toast.LENGTH_SHORT).show(); @@ -136,35 +135,35 @@ public SubView4Other(Context context) { }); SubMenu subSelect = menu.addSubMenu("全部配置"); menu.add("说明").setOnMenuItemClickListener(item -> { - new AlertDialog.Builder(c).setMessage("导出:以文本形式导出到剪切板,请自行保存。\n\n导入:从剪切板中读取文本,保存为新配置。").setPositiveButton(android.R.string.yes,null).show(); + new AlertDialog.Builder(c).setMessage("导出:以文本形式导出到剪切板,请自行保存。\n\n导入:从剪切板中读取文本,保存为新配置。").setPositiveButton(android.R.string.yes, null).show(); return true; }); - subSelect.add("当前: "+currProfileName); + subSelect.add("当前: " + currProfileName); for (File file : profiles) { - if(file.getName().equals("current")) + if (file.getName().equals("current")) continue; String fileName = file.getName(); SubMenu subMenu = subSelect.addSubMenu(fileName); - subMenu.add("选择").setOnMenuItemClickListener(item->{ + subMenu.add("选择").setOnMenuItemClickListener(item -> { makeProfileCurrent(fileName); mCallback.dismiss(); return true; }); - subMenu.add("导出").setOnMenuItemClickListener(item->{ + subMenu.add("导出").setOnMenuItemClickListener(item -> { mCallback.exportData(); return true; }); - subMenu.add("重命名").setEnabled(!fileName.equals("default")).setOnMenuItemClickListener(item->{ + subMenu.add("重命名").setEnabled(!fileName.equals("default")).setOnMenuItemClickListener(item -> { EditText editText = new EditText(c); editText.setText(fileName); - new AlertDialog.Builder(c).setView(editText).setPositiveButton(android.R.string.yes,((dialog, which) -> { + new AlertDialog.Builder(c).setView(editText).setPositiveButton(android.R.string.yes, ((dialog, which) -> { String newName = editText.getText().toString(); - if(newName.trim().length()==0) - newName=fileName; + if (newName.trim().length() == 0) + newName = fileName; File newDir = createNewProfile(newName); FileUtils.deleteQuietly(newDir); try { - FileUtils.moveDirectory(file,newDir); + FileUtils.moveDirectory(file, newDir); makeProfileCurrent(newDir.getName()); mCallback.dismiss(); } catch (IOException e) { @@ -173,7 +172,7 @@ public SubView4Other(Context context) { })).setCancelable(false).show(); return true; }); - subMenu.add("删除").setEnabled(!fileName.equals("default")).setOnMenuItemClickListener(item->{ + subMenu.add("删除").setEnabled(!fileName.equals("default")).setOnMenuItemClickListener(item -> { FileUtils.deleteQuietly(file); makeProfileCurrent("default"); mCallback.dismiss(); @@ -188,63 +187,33 @@ public SubView4Other(Context context) { } - /** - * 创建一个新的配置目录。若已经存在给定配置名的文件夹,则会在name后加_1 - * @param name 理想的配置名。 - * @return 实际创建的配置目录 - */ - private File createNewProfile(String name){ - File newDir = new File(CustomControls.dataDir(),name); - while (newDir.exists()) - newDir = new File(newDir.getAbsolutePath()+"_1"); - boolean b = newDir.mkdirs(); - Log.d(TAG, "createNewProfile: 创建新配置: "+newDir.getName()); - return newDir; - } - - /** - * 将某个配置文件夹链接到current。调用此函数前请确保 此配置名 对应的目录存在。 - * @param profileName 配置名。 - */ - private void makeProfileCurrent(String profileName){ - File newDir = new File(CustomControls.dataDir(),profileName); - try { - File curr = getCurrProfileDir(); - FileUtils.deleteQuietly(curr); - Os.symlink(newDir.getPath(),curr.getPath()); - } catch (ErrnoException e) { - e.printStackTrace(); - } - } - - private static File getCurrProfileDir(){ + private static File getCurrProfileDir() { return new File(CustomControls.dataDir(), "current"); } - private static String getCurrProfileName(){ + private static String getCurrProfileName() { try { - return getCurrProfileDir().getCanonicalFile().getName(); + return getCurrProfileDir().getCanonicalFile().getName(); } catch (IOException e) { e.printStackTrace(); return "default"; } } - private static File getDefaultProfileDir(){ + private static File getDefaultProfileDir() { return new File(CustomControls.dataDir(), "default"); } /** * 文件保存规则:/opt/edpatch/custom_controls下,一个文件夹就是一个配置,内含两个txt(txt不是必须包含)。 * 默认必须存在default文件夹。current文件夹为当前所选配置的对应文件夹的符号链接,默认所选配置为default。 - * + *

* 算了不写了 - * + *

* 保证在读取配置之前,新位置current文件夹有两个txt且是链接 * 1. 如果新位置default文件夹不存在,则创建一个, * 2. 如果新位置current文件夹不存在,则从default链接过去 * 3. 如果有旧文件,挪到新位置default文件夹中 - * */ public static void prepareForProfilesV2() { try { @@ -268,6 +237,36 @@ public static void prepareForProfilesV2() { } } + /** + * 创建一个新的配置目录。若已经存在给定配置名的文件夹,则会在name后加_1 + * + * @param name 理想的配置名。 + * @return 实际创建的配置目录 + */ + private File createNewProfile(String name) { + File newDir = new File(CustomControls.dataDir(), name); + while (newDir.exists()) + newDir = new File(newDir.getAbsolutePath() + "_1"); + boolean b = newDir.mkdirs(); + Log.d(TAG, "createNewProfile: 创建新配置: " + newDir.getName()); + return newDir; + } + + /** + * 将某个配置文件夹链接到current。调用此函数前请确保 此配置名 对应的目录存在。 + * + * @param profileName 配置名。 + */ + private void makeProfileCurrent(String profileName) { + File newDir = new File(CustomControls.dataDir(), profileName); + try { + File curr = getCurrProfileDir(); + FileUtils.deleteQuietly(curr); + Os.symlink(newDir.getPath(), curr.getPath()); + } catch (ErrnoException e) { + e.printStackTrace(); + } + } /** * 初始化时设置导入或导出数据的回调 @@ -278,7 +277,9 @@ public void setCallback(TransferCallback mCallback) { interface TransferCallback { void dismiss(); + void exportData(); + void importData(); } } diff --git a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/widgets/AvailableKeysView.java b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/widgets/AvailableKeysView.java index 542828a9..10af02e6 100644 --- a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/widgets/AvailableKeysView.java +++ b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/widgets/AvailableKeysView.java @@ -2,7 +2,6 @@ import static android.widget.LinearLayout.HORIZONTAL; import static android.widget.LinearLayout.VERTICAL; -import static com.example.datainsert.exagear.FAB.dialogfragment.BaseFragment.getOneLineWithTitle; import android.content.Context; import android.content.DialogInterface; @@ -181,7 +180,7 @@ public AvailableKeysView(Context context, boolean[] preSelect,int joyNum) { linearSetJoyNumParams.gravity= Gravity.CENTER; joyBtnFrame.addView(linearSetJoyNum,linearSetJoyNumParams); - rootLinear.addView(getOneLineWithTitle(getContext(),RR.getS(RR.cmCtrl_allKeysJoyTitle),joyBtnFrame,true)); + rootLinear.addView(QH.getOneLineWithTitle(getContext(),RR.getS(RR.cmCtrl_allKeysJoyTitle),joyBtnFrame,true),QH.LPLinear.one().left().to()); } } @@ -213,7 +212,7 @@ public void showMouseBtn(){ line3.getChildAt(i).setLayoutParams(line3.getChildAt(i).getLayoutParams()); } mouseLinear.addView(line3); - rootLinear.addView(getOneLineWithTitle(getContext(),RR.getS(RR.cmCtrl_allKeysMouseTitle),mouseLinear,true)); + rootLinear.addView(QH.getOneLineWithTitle(getContext(),RR.getS(RR.cmCtrl_allKeysMouseTitle),mouseLinear,true),QH.LPLinear.one().left().to()); // rootLinear.addView(BaseFragment.getOneLineWithTitle(getContext(),"鼠标",)); } diff --git a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/widgets/BtnPropertiesView.java b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/widgets/BtnPropertiesView.java index fb108887..e204a7ed 100644 --- a/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/widgets/BtnPropertiesView.java +++ b/app/src/main/java/com/example/datainsert/exagear/FAB/dialogfragment/customcontrols/widgets/BtnPropertiesView.java @@ -1,6 +1,5 @@ package com.example.datainsert.exagear.FAB.dialogfragment.customcontrols.widgets; -import static com.example.datainsert.exagear.FAB.dialogfragment.BaseFragment.getOneLineWithTitle; import static com.example.datainsert.exagear.RR.dimen.dialogPadding; import static com.example.datainsert.exagear.RR.getS; @@ -54,19 +53,15 @@ private void inflateUI(){ editText.setText(mOneKey.getName()); editText.setLayoutParams(new ViewGroup.LayoutParams(QH.px(c, 100), -2)); editText.addTextChangedListener((QH.SimpleTextWatcher) s -> mOneKey.setName(s.toString())); - LinearLayout renameLinear = getOneLineWithTitle(c, getS(RR.cmCtrl_BtnEditReName), editText, false); + LinearLayout renameLinear = QH.getOneLineWithTitle(c, getS(RR.cmCtrl_BtnEditReName), editText, false); addView(renameLinear); //组合键 Button selectKeyBtn = new Button(c); selectKeyBtn.setLayoutParams(new ViewGroup.LayoutParams(-2, -2)); selectKeyBtn.setText(getS(RR.cmCtrl_s2_selectBtn)); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - selectKeyBtn.setTextAppearance(android.R.style.TextAppearance_Material_Widget_Button_Borderless_Colored); - selectKeyBtn.setBackground(new RippleDrawable(ColorStateList.valueOf(0x44444444),null,selectKeyBtn.getBackground())); - } + QH.setButtonBorderless(selectKeyBtn); selectKeyBtn.setOnClickListener(v -> { - boolean[] condition = new boolean[AvailableKeysView.codes.length]; //预选中自身全部组合键 for(int subKeycode:mOneKey.getSubCodes()) @@ -74,7 +69,6 @@ private void inflateUI(){ if(AvailableKeysView.codes[i]==subKeycode) condition[i]=true; - AvailableKeysView allKeysView = new AvailableKeysView(getContext(), condition, -1); allKeysView.showMouseBtn(); allKeysView.showWithinDialog((dialog, which) -> { @@ -86,14 +80,14 @@ private void inflateUI(){ }); }); - addView(getOneLineWithTitle(c,getS(RR.cmCtrl_BtnEditComb), selectKeyBtn,false)); + addView(QH.getOneLineWithTitle(c,getS(RR.cmCtrl_BtnEditComb), selectKeyBtn,false)); //点击一次 = 保持按下 CheckBox checkTrigger = new CheckBox(c); checkTrigger.setText(getS(RR.cmCtrl_BtnEditTrigger)); checkTrigger.setChecked(mOneKey.isTrigger()); checkTrigger.setOnCheckedChangeListener((buttonView, isChecked) -> mOneKey.setTrigger(isChecked)); - addView(checkTrigger); + addView(checkTrigger,QH.LPLinear.one().top().to()); } /** diff --git a/app/src/main/java/com/example/datainsert/exagear/QH.java b/app/src/main/java/com/example/datainsert/exagear/QH.java index de6e3720..6fe30915 100644 --- a/app/src/main/java/com/example/datainsert/exagear/QH.java +++ b/app/src/main/java/com/example/datainsert/exagear/QH.java @@ -483,4 +483,69 @@ public static File edPatchDir() { } } + /** + * 常见的LinearLayout.LayoutParams构建 + */ + public static class LPLinear { + int w=-1; + int h=-2; + float weight=0; + int[] margins = {0,0,0,0}; + int gravity=-111; + + /** + * 宽为match,高为rap + */ + public static LPLinear one(){ + return new LPLinear(); + } + public static LPLinear one(int w, int h){ + LPLinear linear= new LPLinear(); + linear.w=w; + linear.h=h; + return linear; + } + public LPLinear gravity(int pg){ + gravity = pg; + return this; + } + + public LPLinear weight(float pw){ + weight=pw; + return this; + } + + public LPLinear weight(){ + weight=1; + return this; + } + + /** + * 顶部margin设为8dp + */ + public LPLinear top(){ + margins[1] = margin8Dp(); + return this; + } + public LPLinear top(int margin){ + margins[1] = margin; + return this; + } + public LPLinear left(){ + margins[0] = margin8Dp(); + return this; + } + public LPLinear left(int margin){ + margins[0] = margin; + return this; + } + public LinearLayout.LayoutParams to(){ + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(w,h,weight); + params.weight = weight; + if(gravity!=-111) + params.gravity = gravity; + params.setMargins(margins[0],margins[1],margins[2],margins[3]); + return params; + } + } } diff --git a/app/src/main/java/com/example/datainsert/exagear/RR.java b/app/src/main/java/com/example/datainsert/exagear/RR.java index 8dc6b256..c6d4ecbd 100644 --- a/app/src/main/java/com/example/datainsert/exagear/RR.java +++ b/app/src/main/java/com/example/datainsert/exagear/RR.java @@ -327,7 +327,7 @@ public class RR { zhArray.put(pa_title, "PulseAudio (XSDL)"); zhArray.put(pa_explain, "PulseAudio用于播放音频,可以缓解一部分声音问题。本功能用到的PulseAudio服务端提取自Xserver XSDL,需要手机支持64位。"); zhArray.put(pa_checkRun, "开启pulseaudio服务$在启动容器时一并启动PulseAudio服务"); - zhArray.put(pa_checkLog, "输出日志$将日志保存到 Android/data/%s/files/logs/palog.txt"); + zhArray.put(pa_checkLog, "输出日志$将日志保存到 z:/opt/edpatch/pulseaudio-xsdl/logs/palog.txt"); zhArray.put(pa_btnParam, "修改启动参数$错误的参数会导致无法启动,请谨慎修改。不支持引号排除空格。"); zhArray.put(pa_troubleShooting, "故障排查 ⓘ$" + "检查PulseAudio服务是否正常工作:启动容器后左下角起点 - 运行 - 输入winecfg打开 - 音效,“选中的驱动”显示 winepulse.drv,点击“测试音频”按钮能听到声音。" + @@ -349,8 +349,6 @@ public class RR { zhArray.put(DriveD2_devType, "手机存储$其他外部存储设备$其他外部存储设备(无)"); zhArray.put(DriveD2_parType, "根目录$应用专属目录"); zhArray.put(DriveD2_errors, "请先授予app存储权限 $ 该文件夹不存在 $ 该路径指向的是文件而不是文件夹 $ 没有对该文件夹的读取权限 $ 没有对该文件夹的写入权限 $ 读取该路径时出现错误: "); - - zhArray.put(conSet_otherArgv_title, "额外启动参数"); zhArray.put(conSet_otherArgv_prefValue, "额外命令/环境变量"); zhArray.put(othArg_info, "本页面为全部可用的参数,被勾选的参数会在当前容器中启用。$了解更多..."); @@ -365,7 +363,7 @@ public class RR { zhArray.put(othArg_edit_delConfirm, "确定要删除该参数吗?\n此操作会对全部容器生效。若您想仅修改当前容器,点击勾选框取消勾选即可。\n\n"); zhArray.put(othArg_edit_attrTitles, "参数别名$参数内容$参数类型$新建的容器默认勾选该参数"); zhArray.put(othArg_edit_typeChoices, "环境变量$命令 - 原命令开头$命令 - 原命令执行前$命令 - 原命令执行后"); - zhArray.put(othArg_edit_typeInfo, "环境变量: 作为本次执行命令的环境变量,原命令开头若包含相同名称的环境变量,则会覆盖该参数的值。\n\n命令:若选择 在原命令执行前/后,则此参数的命令与原命令间用一个 & 连接。"); + zhArray.put(othArg_edit_typeInfo, "参数类型分为两种:环境变量和命令。\n\n环境变量: 作为本次执行命令的环境变量,原命令开头若包含相同名称的环境变量,则会覆盖该参数的值。\n\n命令:若选择 在原命令执行前/后,则此参数的命令与原命令间用一个 '&' 连接。"); zhArray.put(othArg_preview_titles, "原命令示例$插入参数后"); zhArray.put(fabVO_checkTitles,"使用vtest协议2(需要Mesa 19.1.0 v3及以上)$使用GL ES 3.x而不是OpenGL$使用多线程egl访问$DXTn (S3TC) 解压(一些游戏需要)$自动重启服务"); zhArray.put(fabVO_radioTitles,"覆盖位置:$左上方$居中$隐藏*$* 与VTEST_WIN=1一起使用以在X11窗口中绘制,而不是悬浮窗覆盖"); @@ -543,8 +541,8 @@ public class RR { enArray.put(conSet_otherArgv_title, "Extra Launching Arguments"); enArray.put(conSet_otherArgv_prefValue, "Extra cmd/env"); enArray.put(othArg_info, "All available params are listed here. Selected items will be applied to the current container.$Learn more..."); - enArray.put(othArg_info_more, "These params will be inserted into the original command when launching the container. Full command can be found at /sdcard/x86-stderr.txt.\n\nIf If the parameter is already included in the original command, the insertion may fail. The actual result can be viewed by clicking \"Preview\" button to enter the test command or viewed in the txt after starting the container. \n\n All available params are stored at z:/opt/edpatch/contArgs.txt, and the parameters enabled for each container are stored at z:/home/xdroid_n/contArgs.txt. However, it is not recommended to modify the txt directly due to strict requirements on the storage format."); - enArray.put(othArg_taskset_useCustom, "Set CPU cores"); + enArray.put(othArg_info_more, "These params will be inserted into the original command when launching the container. Full command can be found at /sdcard/x86-stderr.txt.\n\nIf the parameter is already included in the original command, the insertion may fail. The actual result can be viewed by clicking \"Preview\" button to enter the test command or viewed in the txt after starting the container. \n\nAll available params are stored at z:/opt/edpatch/contArgs.txt, and the parameters enabled for each container are stored at z:/home/xdroid_n/contArgs.txt. However, it is not recommended to modify the txt directly due to strict requirements on the storage format."); + enArray.put(othArg_taskset_useCustom, "Set_CPU_cores"); enArray.put(othArg_ib_autorun, "Autorun_ib.exe"); enArray.put(othArg_serviceExeDisable, "Kill_services.exe"); enArray.put(othArg_preview, "Preview"); @@ -554,7 +552,7 @@ public class RR { enArray.put(othArg_edit_delConfirm, "Are you sure to delete this param?\nThis action will take effect on all containers. If you want to disable it only in the current container, please unselect it from the checkbox.\n\n"); enArray.put(othArg_edit_attrTitles, "Alias$Arg$Type$Enable by default for new containers"); enArray.put(othArg_edit_typeChoices, "Environment Variable$Cmd - in the front of original Cmd$Cmd - before original Cmd executed$Cmd - after original Cmd executed"); - enArray.put(othArg_edit_typeInfo, "Enviroment Variable: Used for the command to be executed. If the original cmd contains a env with the same name, this params will be overridden.\n\nCmd: If it's before/after the original cmd, this cmd and the original cmd are connected with one '&'."); + enArray.put(othArg_edit_typeInfo, "Argument type is either ENV or CMD.\n\nEnvironment Variable: Used for the command to be executed. If the original cmd contains a env with the same name, this params will be overridden.\n\nCmd: If it's before/after the original cmd, this cmd and the original cmd are connected with one '&'."); enArray.put(othArg_preview_titles, "Original CMD$CMD with params"); enArray.put(fabVO_checkTitles,"Use vtest protocol 2 (new Mesa libGL needed)$Use GL ES 3.x instead of OpenGL$Use multi-thread egl access$DXTn (S3TC) decompress (needed for some games)$Auto restart services"); enArray.put(fabVO_radioTitles,"Overlay position:$Top-left$Centered$invisible *$* Used with VTEST_WIN=1 to draw in X11 window instead of overlay"); @@ -728,27 +726,26 @@ public class RR { ruArray.put(DriveD2_parType, "Корневой каталог$Каталог файлов приложения"); ruArray.put(DriveD2_errors, " Необходимо дать приложению разрешение на хранение. $ Каталог не существует. $ Этот путь обозначает файл, а не каталог. $ Приложение не имеет разрешения на чтение содержимого этого каталога. $ Приложение не имеет разрешения на запись в этот каталог. $ Ошибка: "); - ruArray.put(conSet_otherArgv_title, "Extra Launching Arguments"); - ruArray.put(conSet_otherArgv_prefValue, "Extra cmd/env"); - ruArray.put(othArg_info, "All available params are listed here. Selected items will be applied to the current container.$Learn more..."); - ruArray.put(othArg_info_more, "These params will be inserted into the original command when launching the container. Full command can be found at /sdcard/x86-stderr.txt.\n\nIf If the parameter is already included in the original command, the insertion may fail. The actual result can be viewed by clicking \"Preview\" button to enter the test command or viewed in the txt after starting the container. \n\n All available params are stored at z:/opt/edpatch/contArgs.txt, and the parameters enabled for each container are stored at z:/home/xdroid_n/contArgs.txt. However, it is not recommended to modify the txt directly due to strict requirements on the storage format."); - ruArray.put(othArg_taskset_useCustom, "Set CPU cores"); - ruArray.put(othArg_ib_autorun, "Autorun_ib.exe"); - ruArray.put(othArg_serviceExeDisable, "Kill_services.exe"); - ruArray.put(othArg_preview, "Preview"); - ruArray.put(global_add, "Add"); - ruArray.put(global_edit, "Edit"); - ruArray.put(global_del, "Delete"); - ruArray.put(othArg_edit_delConfirm, "Are you sure to delete this param?\nThis action will take effect on all containers. If you want to disable it only in the current container, please unselect it from the checkbox.\n\n"); - ruArray.put(othArg_edit_attrTitles, "Alias$Arg$Type$Enable by default for new containers"); - ruArray.put(othArg_edit_typeChoices, "Environment Variable$Cmd - in the front of original Cmd$Cmd - before original Cmd executed$Cmd - after original Cmd executed"); - ruArray.put(othArg_edit_typeInfo, "Enviroment Variable: Used for the command to be executed. If the original cmd contains a env with the same name, this params will be overridden.\n\nCmd: If it's before/after the original cmd, this cmd and the original cmd are connected with one '&'."); - ruArray.put(othArg_preview_titles, "Original CMD$CMD with params"); - ruArray.put(fabVO_checkTitles,"Use vtest protocol 2 (new Mesa libGL needed)$Use GL ES 3.x instead of OpenGL$Use multi-thread egl access$DXTn (S3TC) decompress (needed for some games)$Auto restart services"); - ruArray.put(fabVO_radioTitles,"Overlay position:$Top-left$Centered$invisible *$* Used with VTEST_WIN=1 to draw in X11 window instead of overlay"); - ruArray.put(fabVO_btnTitles,"Clean Services$Start Services$Allow Drawing Overlay"); - ruArray.put(fabVO_startResults,"Services start successfully. Now you can try to start the container and run games.$Services start failed."); - /* + ruArray.put(conSet_otherArgv_title, "Дополнительные Аргументы Запуска"); + ruArray.put(conSet_otherArgv_prefValue, "Дополнительные cmd/env"); + ruArray.put(othArg_info, "Здесь перечислены все доступные параметры. Выбранные аргументы будут применены к текущему контейнеру.$Подробнее..."); + ruArray.put(othArg_info_more, "Эти аргументы будут добавлены в основную команду запуска контейнера. Полную команду можно найти в файле по пути /sdcard/x86-stderr.txt.\n\nЕсли аргумент уже включен в исходную команду, добавление аргумента может быть неудачным. Фактический результат можно просмотреть, нажав кнопку \"Предварительный просмотр\", используйте её чтобы ввести тестовую команду аргумента, или для просмотра аргумента в текстовом формате. \n\nВсе объявленные аргументы хранятся в Z:/opt/edpatch/contArgs.txt, а параметры, включенные для каждого контейнера, хранятся в Z:/home/xdroid_n/contArgs.txt. Однако напрямую изменять txt не рекомендуется из-за строгих требований к формату хранения."); + ruArray.put(othArg_taskset_useCustom, "Выбор_ядер_CPU"); + ruArray.put(othArg_ib_autorun, "Автозапуск_ib.exe"); + ruArray.put(othArg_serviceExeDisable, "Отключить_services.exe"); + ruArray.put(othArg_preview, "Предварительный просмотр"); + ruArray.put(global_add, "Добавить"); + ruArray.put(global_edit, "Редактировать"); + ruArray.put(global_del, "Удалить"); + ruArray.put(othArg_edit_delConfirm, "Вы уверены, что хотите удалить этот аргумент?\nЭто действие повлияет на все контейнеры. Если вы хотите отключить его только в текущем контейнере, просто снимите флажок.\n\n"); + ruArray.put(othArg_edit_attrTitles, "Имя Аргумента$Аргумент$Тип$Включить по умолчанию для новых контейнеров"); + ruArray.put(othArg_edit_typeChoices, "Переменная среды$Cmd - перед исходным Cmd$Cmd - до выполнения исходного Cmd$Cmd - после выполнения исходного Cmd"); + ruArray.put(othArg_edit_typeInfo, "Тип аргумента - ENV или CMD.\n\nПеременная среды: используется для выполняемой команды. Если исходный cmd содержит окружение с тем же именем, эти параметры будут переопределены.\n\nCmd: Если он находится до или после исходного cmd, этот cmd и исходный cmd соединяются одним знаком '&'."); + ruArray.put(othArg_preview_titles, "Оригинальный CMD$CMD с параметрами CMD"); + ruArray.put(fabVO_checkTitles,"Использовать протокол vtest 2 (требуется новая библиотека Mesa libGL)$Использовать GL ES 3.x вместо OpenGL$Использовать многопоточный доступ egl$Распаковка DXTn (S3TC) (необходима для некоторых игр)$Автоматический перезапуск сервисов"); + ruArray.put(fabVO_radioTitles,"Позиция Оверлэя: $Левый верхний угол$Центр$Невидимая *$* Используется с VTEST_WIN=1 для рисования в окне X11 вместо наложения."); + ruArray.put(fabVO_btnTitles,"Очистить Сервисы$Запустить Сервисы$Разрешить наложение Оверлэя"); + ruArray.put(fabVO_startResults,"Сервисы запускаются успешно. Теперь можно попробовать запустить контейнер, и запустить игры.$Не удалось запустить Сервисы."); /* diff --git a/app/src/main/java/com/example/datainsert/exagear/containerSettings/ConSetOtherArgv.java b/app/src/main/java/com/example/datainsert/exagear/containerSettings/ConSetOtherArgv.java index 2ac6b4f8..8f51bb8a 100644 --- a/app/src/main/java/com/example/datainsert/exagear/containerSettings/ConSetOtherArgv.java +++ b/app/src/main/java/com/example/datainsert/exagear/containerSettings/ConSetOtherArgv.java @@ -109,12 +109,14 @@ public static void buildDialog(EditTextPreference preference) { Button btnAdd = new Button(c); btnAdd.setText(getS(RR.global_add));//编辑 QH.setButtonBorderless(btnAdd); - btnAdd.setOnClickListener(v -> allArgsAdapter.buildEditArgDialog(v.getContext(), -1, -1)); + btnAdd.setOnClickListener(v -> allArgsAdapter.buildEditArgDialog(v.getContext(), -1, -1,getS(RR.global_add))); + btnAdd.setAllCaps(false); Button btnPreview = new Button(c); btnPreview.setText(getS(RR.othArg_preview));//预览 btnPreview.setOnClickListener(v -> buildPreviewDialog(c, contId)); QH.setButtonBorderless(btnPreview); + btnPreview.setAllCaps(false); LinearLayout linearArgBtns = new LinearLayout(c); linearArgBtns.setOrientation(HORIZONTAL); @@ -129,8 +131,8 @@ public static void buildDialog(EditTextPreference preference) { infoBuilder.append(infoStrs[0]).append(" ").append(infoStrs[1]).setSpan(new ClickableSpan() { @Override public void onClick(@NonNull View widget) { - Log.d(TAG, "onClick: 点击tv"); - new AlertDialog.Builder(widget.getContext()).setMessage(getS(RR.othArg_info_more)).show(); + new AlertDialog.Builder(widget.getContext()) + .setMessage(getS(RR.othArg_info_more)+"\n\n"+getS((RR.othArg_edit_typeInfo))).show(); } }, infoBuilder.length() - infoStrs[1].length(), infoBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); tvInfo.setMovementMethod(LinkMovementMethod.getInstance()); @@ -189,6 +191,7 @@ private static void buildPreviewDialog(Context c, int contId) { linearRoot.addView(QH.getOneLineWithTitle(c, titlesStr[1], textNewCmd, true), marginTopParams); //插入参数后 new AlertDialog.Builder(c) + .setTitle(getS(RR.othArg_preview)) .setView(QH.wrapAsDialogScrollView(linearRoot))//QH.wrapAsDialogScrollView(linearRoot) .setPositiveButton(android.R.string.ok, null) .setCancelable(false) diff --git a/app/src/main/java/com/example/datainsert/exagear/containerSettings/ConSetRenderer.java b/app/src/main/java/com/example/datainsert/exagear/containerSettings/ConSetRenderer.java index 6b6743d1..30c5cd01 100644 --- a/app/src/main/java/com/example/datainsert/exagear/containerSettings/ConSetRenderer.java +++ b/app/src/main/java/com/example/datainsert/exagear/containerSettings/ConSetRenderer.java @@ -32,7 +32,7 @@ import java.util.Map; public class ConSetRenderer { - public static final String DEFAULT_RENDERER_TXT_CONTENT = "" + + public static String DEFAULT_RENDERER_TXT_CONTENT = "" + "# 每个key代表一种渲染方式,该值不能随意修改。name代表环境设置中此选项显示的名称。env代表选择该选项后,启动容器时设置环境变量。其中LD_LIBRARY_PATH路径可以存放libGl.so.1等文件。删去某个key及其对应name,env行后,该渲染方式不会显示在选项中。" + "\n# Each 'key' represents a renderer, its value shouldn't be changed. 'name' represents the name of this renderer option in container settings. 'env' is the env variables added when launching container. LD_LIBRARY_PATH is the path where libs like libGL.so.1 are placed. Delete 'key', 'name', 'env' lines and its corresponding renderer will not be added to options in container settings." + @@ -69,15 +69,16 @@ public class ConSetRenderer { "\n env:VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/freedreno_icd.i686.json" + "\n env:GALLIUM_DRIVER=zink" + "\n env:MESA_VK_WSI_DEBUG=sw"; + public static final File configFile = new File(QH.Files.edPatchDir(), "renderers.txt"); /** * 1: 初次添加 * 2: 路径和名称存在/opt/renderers.txt中。点击选项下方有文字提示修改了哪些内容 * 3: renderers.txt 中,改为存储环境变量,以便用户可以自定义 (icd,为dxvk的tz指定不同的libvulkan_freedreno.so) * 4: 支持未知渲染(没有在enum中定义的) + * 5: txt存储路径改为/opt/edpatch/renderers.txt */ - private static final int VERSION_FOR_EDPATCH = 4; + private static final int VERSION_FOR_EDPATCH = 5; private static final String TAG = "ConSetRenderer"; - /** * 从/opt/renderers.txt读取并存储到map. *

@@ -87,7 +88,6 @@ public class ConSetRenderer { * 存入pref中的数值为key,所以要求key不要随便修改 */ public static Map renderersMap = new LinkedHashMap<>();//要求有序,否则顺序会乱 - // static { // ConSetRenderer.readRendererTxt(); // } @@ -101,20 +101,23 @@ public class ConSetRenderer { * key是key,value是name和path的bundle */ public static void readRendererTxt() { - File configFile = new File(((ExagearImageAware) Globals.getApplicationState()).getExagearImage().getPath(), "opt/renderers.txt"); - renderersMap.clear(); try { + //迁移txt位置 + File oldFile = new File(((ExagearImageAware) Globals.getApplicationState()).getExagearImage().getPath(), "opt/renderers.txt"); + if (oldFile.exists()) + FileUtils.moveFile(oldFile, configFile); + //若没有该文件,自己创建一个并写入默认内容 if (!configFile.exists()) { FileUtils.writeLines(configFile, "UTF-8", Arrays.asList(DEFAULT_RENDERER_TXT_CONTENT.split("\n"))); } List lines = new ArrayList<>(); - for(String s: FileUtils.readLines(configFile)){ + for (String s : FileUtils.readLines(configFile)) { String trim = s.trim(); - if( !(trim.startsWith("#") || trim.length() ==0)) + if (!(trim.startsWith("#") || trim.length() == 0)) lines.add(trim); } @@ -174,7 +177,7 @@ public static void buildRendererDialog(ListPreference preference) { //如果该值在txt中未记录,就不显示介绍。如果在txt中记录但不属于enum中已定义的,可以显示环境变量 Bundle rendBundle = renderersMap.get(keys[i].toString()); - if(rendBundle == null) + if (rendBundle == null) continue; LinearLayout linearInfo = new LinearLayout(c); @@ -185,7 +188,7 @@ public static void buildRendererDialog(ListPreference preference) { StringBuilder stringBuilder = new StringBuilder(); ArrayList envList = rendBundle.getStringArrayList("env"); - assert envList!=null; + assert envList != null; for (String s : envList) stringBuilder.append(s).append('\n'); @@ -199,7 +202,7 @@ public static void buildRendererDialog(ListPreference preference) { //每一项太长了,先默认缩成一行,点击展开 for (String oneStr : stringBuilder.toString().split("\n")) { - if(oneStr.equals("")) + if (oneStr.equals("")) continue; TextView tvInfo = new TextView(c); tvInfo.setTextIsSelectable(true); diff --git a/app/src/main/java/com/example/datainsert/exagear/containerSettings/otherargv/AdapterHelper.java b/app/src/main/java/com/example/datainsert/exagear/containerSettings/otherargv/AdapterHelper.java index 6251f67e..8a8a70ce 100644 --- a/app/src/main/java/com/example/datainsert/exagear/containerSettings/otherargv/AdapterHelper.java +++ b/app/src/main/java/com/example/datainsert/exagear/containerSettings/otherargv/AdapterHelper.java @@ -5,6 +5,7 @@ import static com.example.datainsert.exagear.containerSettings.ConSetOtherArgv.KEY_TASKSET; import static com.example.datainsert.exagear.containerSettings.ConSetOtherArgv.VAL_TASKSET_DEFAULT; +import android.animation.LayoutTransition; import android.annotation.SuppressLint; import android.content.Context; import android.support.annotation.NonNull; @@ -88,6 +89,7 @@ class AdapterHelper { linearRoot.addView(linearPart1); linearRoot.addView(linearPart2); linearRoot.setLayoutParams(new ViewGroup.LayoutParams(-1, -2)); + linearRoot.setLayoutTransition(new LayoutTransition()); return linearRoot; } diff --git a/app/src/main/java/com/example/datainsert/exagear/containerSettings/otherargv/AllArgsAdapter.java b/app/src/main/java/com/example/datainsert/exagear/containerSettings/otherargv/AllArgsAdapter.java index 2983d8b5..251be079 100644 --- a/app/src/main/java/com/example/datainsert/exagear/containerSettings/otherargv/AllArgsAdapter.java +++ b/app/src/main/java/com/example/datainsert/exagear/containerSettings/otherargv/AllArgsAdapter.java @@ -57,10 +57,6 @@ public AllArgsAdapter(int contId) { mData = Arguments.all; } - public List getALlData() { - return mData; - } - @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) { @@ -95,10 +91,7 @@ else if (holder.getItemViewType() == TYPE_TASKSET) { mData.get(holder.getAdapterPosition()).setArg(""); //显示或隐藏核心数 - TransitionManager.beginDelayedTransition(holder.root); - ViewGroup.LayoutParams params = holder.linearPart2.getLayoutParams(); - params.height = isChecked ? -2 : 0; - holder.linearPart2.setLayoutParams(params); + holder.linearPart2.setVisibility(isChecked ? VISIBLE : GONE); } }); if (!isTypeMulti) @@ -109,11 +102,9 @@ else if (holder.getItemViewType() == TYPE_TASKSET) { holder.ck.setButtonDrawable(null); holder.ck.setOnClickListener(v -> { boolean isFolded = holder.ck.getRotation() == 0; - TransitionManager.beginDelayedTransition(holder.root); holder.ck.animate().rotation(isFolded ? 90 : 0).setDuration(300).start(); - ViewGroup.LayoutParams params = holder.linearPart2.getLayoutParams(); - params.height = isFolded ? -2 : 0; - holder.linearPart2.setLayoutParams(params); + TransitionManager.beginDelayedTransition((ViewGroup) holder.linearPart2.getParent()); + holder.linearPart2.setVisibility(isFolded ? VISIBLE : GONE); }); } @@ -160,8 +151,7 @@ else if (isTypeMulti) { } //只有cpu核心且勾选了它的时候才显示第二布局,否则均隐藏(初次构建布局就没必要加动画了吧) - holder.linearPart2.getLayoutParams().height = (isTypeCPU && holder.ck.isChecked()) ? -2 : 0; - holder.linearPart2.setLayoutParams(holder.linearPart2.getLayoutParams()); + holder.linearPart2.setVisibility((isTypeCPU && holder.ck.isChecked()) ? VISIBLE : GONE); } /** @@ -172,13 +162,14 @@ else if (isTypeMulti) { private void buildItemActionMenu(ViewHolder holder, View v, int subInd) { PopupMenu popupMenu = new PopupMenu(v.getContext(), v); popupMenu.getMenu().add(getS(RR.global_edit)).setOnMenuItemClickListener(item -> { //编辑 - buildEditArgDialog(v.getContext(), holder.getAdapterPosition(), subInd); + buildEditArgDialog(v.getContext(), holder.getAdapterPosition(), subInd, getS(RR.global_edit)); return true; }); popupMenu.getMenu().add(getS(RR.global_del)).setOnMenuItemClickListener(item -> { //删除 int adapterPos = holder.getAdapterPosition(); Argument argument = subInd == -1 ? mData.get(adapterPos) : mData.get(adapterPos).getGroup().get(subInd); new AlertDialog.Builder(v.getContext()) + .setTitle(getS(RR.global_del)) .setMessage(getS(RR.othArg_edit_delConfirm) + argument.getArg()) .setPositiveButton(android.R.string.ok, (dialog, which) -> { if (subInd == -1) { @@ -201,7 +192,7 @@ private void buildItemActionMenu(ViewHolder holder, View v, int subInd) { * 显示一个dialog,用于编辑一个参数的必要信息。可能为新建(oriPos=-1),也可能为修改现有(oriPos=其在mData中的位置)。 * subInd不为-1,说明是参数组中的某个参数,否则表明这是个单参数 */ - public void buildEditArgDialog(Context c, int oriPos, int subInd) { + public void buildEditArgDialog(Context c, int oriPos, int subInd, String dialogTitle) { boolean isNew = oriPos == -1; Argument currArg; if (isNew) currArg = null; @@ -270,6 +261,7 @@ public void buildEditArgDialog(Context c, int oriPos, int subInd) { linearAddRoot.addView(checkEnable, marginTopParams); new AlertDialog.Builder(c) + .setTitle(dialogTitle) .setView(QH.wrapAsDialogScrollView(linearAddRoot)) .setNegativeButton(android.R.string.cancel, null) .setPositiveButton(android.R.string.ok, (dialog, which) -> { @@ -283,6 +275,12 @@ public void buildEditArgDialog(Context c, int oriPos, int subInd) { Argument newArg = Arguments.inflateArgument(currArg, checkEnable.isChecked() ? "e" : "d", typeNPos[0], typeNPos[1], editAlias.getText().toString(), argContent.trim()); if (!isNew) { + //TODO 即使是编辑现有,也可能从单参数变为参数组或参数组变单参数。这里缺少判断 + // 要不就全部读取完参数库列表后,再统一调用一次函数,将参数合并成组。这样这里直接插入列表,然后重新合并一遍. + // (函数考虑:单参数合并组成参数组,单参数加入已有参数组,已有参数组的子参数个数只剩一个退化为单参数,已有参数组的子参数有变化应移出该参数组) + // 遍历两遍。第一遍遍历,检查已有参数组,其子参数是否还应留在此组,该参数组是否可以变成单参数。 、 + // 第二遍遍历,检查单参数是否可以加入到已有组或和其他单参数组成参数组 + // 但是怎么获取插入位置? notifyItemChanged(oriPos);//Arguments.inflateArgument会直接修改现有arg对象,不需要移除再添加了 return; } diff --git a/app/src/main/java/com/example/datainsert/exagear/containerSettings/otherargv/Arguments.java b/app/src/main/java/com/example/datainsert/exagear/containerSettings/otherargv/Arguments.java index 8d8af344..9fbb439c 100644 --- a/app/src/main/java/com/example/datainsert/exagear/containerSettings/otherargv/Arguments.java +++ b/app/src/main/java/com/example/datainsert/exagear/containerSettings/otherargv/Arguments.java @@ -206,6 +206,11 @@ public boolean isEnableByDefault() { return VAL_TASKSET_DEFAULT.length() == 0; //是否默认启用,取决于其单独设置的默认值 } + @Override + public String getAlias() { + return super.getAlias(); + } + @Override public boolean isChecked() { return getArg().length() > 0; diff --git a/app/src/main/java/com/example/datainsert/exagear/controls/axs/gamesControls/GestureMachineMix.java b/app/src/main/java/com/example/datainsert/exagear/controls/axs/gamesControls/GestureMachineMix.java index f08c0c67..a516e58b 100644 --- a/app/src/main/java/com/example/datainsert/exagear/controls/axs/gamesControls/GestureMachineMix.java +++ b/app/src/main/java/com/example/datainsert/exagear/controls/axs/gamesControls/GestureMachineMix.java @@ -296,8 +296,9 @@ public static GestureContext create(ViewOfXServer viewOfXServer, TouchArea touch //2. 第二个手指按下监听动作,监听第三个手指. 相对移动从子分支开始都只需要写REL的吧 fSM.addTransition(gsMesSpd1stF, StateMesOneFSpd.FINGER_TOUCHED, gsMesSpd2ndF); fSM.addTransition(gs1FMouseMove, State1FMouseMove.NEW_FINGER_TOUCHED, gsMesSpd2ndF); - //2.1 第二个手指松开 二指点击事件 = 鼠标右键点击 + //2.1 第一/二个手指松开 二指点击事件 = 鼠标右键点击 fSM.addTransition(gsMesSpd2ndF,StateMesOneFSpd.FINGER_TAPPED,gsRightClick); + fSM.addTransition(gsMesSpd2ndF,StateMesOneFSpd.FINGER_WALKED_AND_GONE,gsRightClick); //2.2 第二个手指移动 = 鼠标滚轮 fSM.addTransition(gsMesSpd2ndF,StateMesOneFSpd.FINGER_WALKED,gs2FScroll); fSM.addTransition(gsMesSpd2ndF,StateMesOneFSpd.FINGER_FLASHED,gs2FScroll); diff --git a/app/src/main/java/com/example/datainsert/exagear/controls/widget/JoyStickBtn.java b/app/src/main/java/com/example/datainsert/exagear/controls/widget/JoyStickBtn.java index 762243bf..795150e0 100644 --- a/app/src/main/java/com/example/datainsert/exagear/controls/widget/JoyStickBtn.java +++ b/app/src/main/java/com/example/datainsert/exagear/controls/widget/JoyStickBtn.java @@ -2,7 +2,6 @@ import static android.graphics.Paint.Style.FILL; import static android.graphics.Paint.Style.STROKE; -import static com.example.datainsert.exagear.FAB.dialogfragment.BaseFragment.getOneLineWithTitle; import static com.example.datainsert.exagear.FAB.dialogfragment.BaseFragment.getPreference; import static com.example.datainsert.exagear.FAB.dialogfragment.BaseFragment.setDialogTooltip; import static com.example.datainsert.exagear.RR.getS; @@ -351,8 +350,7 @@ public void onClick(View v) { linearRoot.addView(check4Direct); //编辑位置状态下点击,设置四个方向的按键 - LinearLayout linearCustomOuter;//用于控制自定义按键显隐的布局 - LinearLayout linearCustomKeys = new LinearLayout(c); + LinearLayout linearCustomKeys = new LinearLayout(c); //用于控制自定义按键显隐的布局 linearCustomKeys.setOrientation(LinearLayout.VERTICAL); int btnSize = QH.px(c, 50); LinearLayout linearLine1 = new LinearLayout(c); @@ -368,7 +366,6 @@ public void onClick(View v) { linearLine3.addView(get1SetKeyBtn(false, -1), new ViewGroup.LayoutParams(btnSize, btnSize)); linearLine3.addView(get1SetKeyBtn(true, 1), new ViewGroup.LayoutParams(btnSize, btnSize)); linearCustomKeys.addView(linearLine3, new ViewGroup.LayoutParams(-2, -2)); - linearCustomOuter = getOneLineWithTitle(c, null, linearCustomKeys, true); //选择预设按键,或者自定义 Spinner spinKeys = new Spinner(c,Spinner.MODE_DIALOG); @@ -379,7 +376,7 @@ public void onClick(View v) { spinKeys.setAdapter(spinKeyPosAdapter); spinKeys.setOnItemSelectedListener(new SimpleItemSelectedListener((parent, view, position, id) -> { mParams.setPresetKey(spinValues[position]); - linearCustomOuter.setVisibility(mParams.getPresetKey().equals(CUSTOM) ? VISIBLE : GONE); + linearCustomKeys.setVisibility(mParams.getPresetKey().equals(CUSTOM) ? VISIBLE : GONE); })); //设置当前选中 for (int i = 0; i < spinValues.length; i++) { @@ -387,11 +384,11 @@ public void onClick(View v) { spinKeys.setSelection(i); } spinKeys.setLayoutParams(new ViewGroup.LayoutParams(-2, -2)); - LinearLayout oneLineSpinKeyPos = getOneLineWithTitle(c, getS(RR.cmCtrl_JoyEditKeys), spinKeys, false); + LinearLayout oneLineSpinKeyPos = QH.getOneLineWithTitle(c, getS(RR.cmCtrl_JoyEditKeys), spinKeys, false); // setDialogTooltip(oneLineSpinKeyPos.getChildAt(0),""); linearRoot.addView(oneLineSpinKeyPos); - linearRoot.addView(linearCustomOuter); + linearRoot.addView(linearCustomKeys); Log.d(TAG, "handleEditingClick: 显示对话框"); new AlertDialog.Builder(getContext()) diff --git a/patchapp/build.gradle b/patchapp/build.gradle index 215de63b..dc596792 100644 --- a/patchapp/build.gradle +++ b/patchapp/build.gradle @@ -11,7 +11,7 @@ android { minSdk 21 targetSdk 27 versionCode 10 - versionName '0.1.2' + versionName '1.0.0' resourceConfigurations += ['en', 'zh', 'ru'] testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } diff --git a/patchapp/release/output-metadata.json b/patchapp/release/output-metadata.json index c0e72a84..37bebc85 100644 --- a/patchapp/release/output-metadata.json +++ b/patchapp/release/output-metadata.json @@ -12,7 +12,7 @@ "filters": [], "attributes": [], "versionCode": 10, - "versionName": "0.1.2", + "versionName": "1.0.0", "outputFile": "EDPatch-beta.apk" } ], diff --git a/patchapp/src/main/java/com/ewt45/patchapp/fragment/FragmentPatchStep1.java b/patchapp/src/main/java/com/ewt45/patchapp/fragment/FragmentPatchStep1.java index 9a74faf6..1f85de75 100644 --- a/patchapp/src/main/java/com/ewt45/patchapp/fragment/FragmentPatchStep1.java +++ b/patchapp/src/main/java/com/ewt45/patchapp/fragment/FragmentPatchStep1.java @@ -11,10 +11,12 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.constraint.ConstraintSet; import android.support.design.widget.CoordinatorLayout; import android.support.v7.widget.AppCompatCheckBox; import android.text.SpannableStringBuilder; import android.text.style.RelativeSizeSpan; +import android.transition.TransitionManager; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -27,7 +29,6 @@ import com.ewt45.patchapp.R; import com.ewt45.patchapp.databinding.FragmentPatchStep1Binding; import com.ewt45.patchapp.thread.DecodeApk; -import com.ewt45.patchapp.thread.SignalDone; import com.ewt45.patchapp.widget.ActionProgressDialog; import com.ewt45.patchapp.widget.SelectApkDialog; @@ -43,6 +44,10 @@ public class FragmentPatchStep1 extends BaseFragmentPatchStep { * 首次执行,在刚进入时,若检测到已解包apk,不跳转step2。若是选择了apk之后解压成功,则自动跳转 */ private boolean isFirstEnter=true; + /** + * 标记是否点击了选择本地文件按钮,即当前正在选择文件。因为选择文件用的别的activity,回来之后会重新走一遍onStart刷新视图,导致还没解压完的时候就刷新视图了。 + */ + private boolean isSelectingNewApkLocalFile = false; @Nullable @Override @@ -52,6 +57,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c binding.btnSelectApkFiles.setOnClickListener(v -> { + isSelectingNewApkLocalFile=true; Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("application/vnd.android.package-archive");//仅显示apk类型 @@ -77,14 +83,16 @@ public void onStart() { getFAB().setImageResource(R.drawable.ic_arrow_forward); getFAB().hide(); setStepTitle(R.string.patchstep1_title); - updateApkInfo(null); + if(!isSelectingNewApkLocalFile){ + updateApkInfo(null); + } AndroidUtils.showSnack(requireActivity(), R.string.tips_backup); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { - //获取选中的,想要修改apk + //获取选中的,想要修改apk。 if (requestCode == REQUEST_PICK_APK_FILE && data != null) { updateApkInfo(data.getData()); //只有不为null时才执行。 } else @@ -115,10 +123,16 @@ private void updateApkInfo(Uri uri) { builder.append(infoName).setSpan(new RelativeSizeSpan(1.5f), 0, infoName.length(), SPAN_EXCLUSIVE_EXCLUSIVE); builder.append('\n').append(infoPkgName).append('\n').append(infoVersion); binding.appInfo.setText(builder); + + //解压成功后,显示提示语 + //TODO 为什么没执行完,dialog还在的时候就会走到这里?原来选择文件后跳转回activity,会执行一遍onStart + changeConstraintSet(true); + binding.btnReselect.setOnClickListener(v-> changeConstraintSet(false)); //要不解压完直接跳转? // getFAB().performClick(); } else { + changeConstraintSet(false); getFAB().hide(); binding.appIcon.setImageResource(R.drawable.ic_apk_document); binding.appInfo.setText(R.string.patchstep1_tv_noapkfound); @@ -139,13 +153,28 @@ private void updateApkInfo(Uri uri) { FileUtils.deleteQuietly(PatchUtils.getExaExtractDir()); } AndroidUtils.showSnack(requireActivity(), noError ? R.string.tips_backup : R.string.tips_action_failed); + + isSelectingNewApkLocalFile=false; updateApkInfo(null); - }, new DecodeApk(DecodeApk.EXAGEAR), new SignalDone()); + }, new DecodeApk(DecodeApk.EXAGEAR)); } catch (Exception e) { e.printStackTrace(); } } + private void changeConstraintSet(boolean selectDone){ + if(selectDone){ + ConstraintSet set = new ConstraintSet(); + set.clone(requireContext(),R.layout.fragment_patch_step1_newselect); + TransitionManager.beginDelayedTransition(binding.getRoot()); + set.applyTo(binding.getRoot()); + }else{ + ConstraintSet set2 = new ConstraintSet(); + set2.clone(requireContext(),R.layout.fragment_patch_step1); + TransitionManager.beginDelayedTransition(binding.getRoot()); + set2.applyTo(binding.getRoot()); + } + } } diff --git a/patchapp/src/main/java/com/ewt45/patchapp/fragment/FragmentPatchStep2.java b/patchapp/src/main/java/com/ewt45/patchapp/fragment/FragmentPatchStep2.java index b01b93ab..a536bf7f 100644 --- a/patchapp/src/main/java/com/ewt45/patchapp/fragment/FragmentPatchStep2.java +++ b/patchapp/src/main/java/com/ewt45/patchapp/fragment/FragmentPatchStep2.java @@ -25,7 +25,6 @@ import com.ewt45.patchapp.thread.DecodeApk; import com.ewt45.patchapp.thread.Func; import com.ewt45.patchapp.thread.SignApk; -import com.ewt45.patchapp.thread.SignalDone; import com.ewt45.patchapp.widget.ActionProgressDialog; import com.ewt45.patchapp.widget.DividerGridItemDecoration; @@ -81,7 +80,7 @@ public void onStart() { boolean useDefaultKey = AndroidUtils.getPrefs().getBoolean("use_default_signature", true); torunList.add(new SignApk(requireContext().getAssets(), useDefaultKey));//签名 } - torunList.add(new SignalDone()); +// torunList.add(new SignalDone()); Log.d(TAG, "setOnClickListener: 点击fab后,执行action:" + torunList); ActionProgressDialog.startActionsWithDialog(requireContext(), noError -> { diff --git a/patchapp/src/main/java/com/ewt45/patchapp/thread/FuncFAB.java b/patchapp/src/main/java/com/ewt45/patchapp/thread/FuncFAB.java index 47b8395a..00444a42 100644 --- a/patchapp/src/main/java/com/ewt45/patchapp/thread/FuncFAB.java +++ b/patchapp/src/main/java/com/ewt45/patchapp/thread/FuncFAB.java @@ -50,6 +50,7 @@ public int getLatestVersion() { pulseaudio 2:保留 deamon.conf + 3: 将工作目录 以及 日志输出 移动到 z:/opt/edpatch/pulseaudio-xsdl xegw 1: 为xegw2.0准备的更多选项, -legacy-drawing 和关闭电池优化 @@ -60,7 +61,7 @@ public int getLatestVersion() { return 0x3 //自定义d盘的版本号 | 0x3 << 4 //自定义按键的版本号 - | 0x2 << 8 //pulseaudio + | 0x3 << 8 //pulseaudio | 0x1 << 12 //Xegw | 0x1 << 16 //VirglOverlay ; diff --git a/patchapp/src/main/java/com/ewt45/patchapp/thread/FuncRenderer.java b/patchapp/src/main/java/com/ewt45/patchapp/thread/FuncRenderer.java index 24c1a014..efc2322a 100644 --- a/patchapp/src/main/java/com/ewt45/patchapp/thread/FuncRenderer.java +++ b/patchapp/src/main/java/com/ewt45/patchapp/thread/FuncRenderer.java @@ -19,7 +19,7 @@ public int getInstalledVersion() { @Override public int getLatestVersion() { - return 4; + return 5; } @Override diff --git a/patchapp/src/main/java/com/ewt45/patchapp/thread/SignalDone.java b/patchapp/src/main/java/com/ewt45/patchapp/thread/SignalDone.java index 16419955..a3bb2417 100644 --- a/patchapp/src/main/java/com/ewt45/patchapp/thread/SignalDone.java +++ b/patchapp/src/main/java/com/ewt45/patchapp/thread/SignalDone.java @@ -2,6 +2,7 @@ import com.ewt45.patchapp.R; +@Deprecated public class SignalDone implements Action { // public static int SIGNAL_DONE = 54321; diff --git a/patchapp/src/main/res/drawable/otherargv.jpg b/patchapp/src/main/res/drawable/otherargv.jpg index e93c47cc79398e83362cf6b4eb6563d7c91fc7ee..ba34e849bf67362d2d386a4c65adb644d5097c7b 100644 GIT binary patch literal 74434 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 literal 50465 zcmeFZ1wfrk(ja@B82uBh`%kcwy|q2? zp26Sl*R!_$4PF7l@)qU}ztQ@w{Kheyfu({R@K+i5!3Ed>z5+x5{6P4BYWY*1R@ndm z+YJB!_We(sZV~{{;12*`F8zrk%>)1t{Q!Xa32Pl&oxd>y4*Ui+Gz0)H3jhFk6#xL` z2LJ%0_6MVXw*B*2{KZ(=fNgMrDTPzyIy; z+cH1^01gKB+Z!AV90D910ulxa5?J8h!9c?x!XqIe!XqLeqhO*UzsGowfQW{RhJl5J zgM)*FibsHlO@N7wgZ*14Am9)XkPwh?P*8B#$cV_;|J~)S8-NTA1_c2C10e>0B7=Y- zgS_6$0CzI=5aui6i+iq1G%jqF}Yy99f|H|e3#B4U%)%Mjq-+c|Eu~Gh$ z79YFfFzxb$zl=nPYnx^X(ZK`8e#V56**-5pV;th-8z7^-9cVTGqXKdP!@U(@J^?qH zPihds2b9{Mj|*(5zZwBiW{ykl7ce?%4lAVA7l`>;EDK02%`th@~Zq}to%AJC@5``H@+=+ClzxLCiq z?;H4bun~_R$GE0?sL?E|cRKadzsjXSq1z`^m)_j&c~w!|G0$|xUaiX2=!~#Of}rBo z)3-*6o{{DOeW7@a#@LqTmFsxFOgOu^w=0tqbIP?ktmQnvX=u-K?_m_r#)g6Kl@smc zvJxtGy1CcM>2c`v<@EB-EepV(dYraKpgh0-r#x(ftk35dSmq$H58ZGgGO;?MEZxN(n?Q5$m}%OQn})uV!lu9_wJ2d8$M-IL=jywqANGzsOxvlClH zFYHwnE_6?*%B!a~7qqlh0+rs$*@GmdHqGj?x!b1*M6>yR_B4w&;=rZj4cmuR%__C| z`P+2()ifbqqn2`)R{T{c+B6H_lt?9)zAEG1Ew{@B#h2BpgL215sBv@r@yVZ=8cjQn zKR531tbt;4=Z|#GNnz|^{1}X-_Z=uRpy1Gdvu}_<2ZdSS0ERmAz}p2;^2ZC=xT%J3 z;jSqsjSOZ((W~tR?y0PiLaYCz)<(h(Mz*Rt!AGNv6b*!Q`PIH+lX`(wW-EGI1rH-H z>;bkmF0}0ZQoGQef#d&r0)TCyy7l2Mreh^ZijLrV(+B%vCel^Tms0H00iYlwtqbwo znDHO&S2UycFI}G@1ZD>-Q#{l&R5s?dXV|!9Ksts_&f~G~ydoHf5k1^mdRg6=-6nX- zp6wkPW#@Z$U0=4^@G3qJ9`vS`a^fH;z5xtlc;F)t5ku=K*CIyKak`HF%_p?dg|AKMEAlWn2zc8>+L51(1?Io0_eu9nNxuid!Q!Akm% zE~E+E{B0O|`cAphEa3|aEiQK*IZ{2dO7s}2V~hq=&mT8ZH9**{yW9Mz{2DIY($ zigW}YZR2Tn@Xjd%f;%r{?;POUlIP|3OwFj#EXRWEnz5ukbx5U~5&q|6)A9(pkTtqGfk~!>Sv&2oaizsGbYe z%#90L-#tamegmsMm$|QHcz8m3BbG7#bJt>>%j+|rZU;ZC!Xos9_BES-(v+~Q>Ds9O zEOMi6O^Mqw9urklbilr<1=Z@@)+`=zBp5fgI_A$qy^span(>2OL$=$2fom0@P{v~$ zUi`>ahqIfrho6yY#+b8y9Y-C%jy1Zq?!Jd1<7U!%YUzdY_c&yhX)w;?fAVk> zdwkE$^972aYL_ym)ah7@rwt#-9UNmhHuGH*g<6(e{a>*62l`h&1!#)Y6B&5<%2WH# zEx8*@`u=NIP6L#0*X3AhkE}T5^6Yox$Tkl(!Gqh7N8>MhuLao26xxEJP3gsny$0Y13#{k%bHn%JpZcviphU& z=ltRuju$n2VE)g@zlQ%WQl-CU=wEC8(^3CxtG~YbmEi@qLHIegPd2gSx?-8sw7H9p zK~So{rR|iu_FeB=Eif{G>uyx;4wlEY4x*#fMxhhI2c+YpzAn4}*Ytj``IVFrGiFw!UN+|AEC;`M=Be(ddy3SgJ3O{JbA-G5>=|UO!_d<97*i?2gf{{yDwHwn$r(9ETDW%qmz@2|az7049;#%JooUhY zhz&pGLk&}5xJL$=J*7hpwEJpDH;F&?LowF8cV7;?RpzlcX^)J%JB@ZvnZMq=(#k%L zNxZ&?AM712F}RLhDOa1o_yS}GZ5gS6ddlSbzvSyz68p0;wiAM<=4OEQpO{}l|5>NM z?BZW4|3ka^FKvEt@t-O?5-?o&AC+J6hXx~dtJKRAt&+jKouTcXaS&Ju^e>HU3V!oJ zK`F+W4sjZs&pE^uvmfHHXWTl0SZ6kfCdKN%S~LH_(XSTI4@|sSvXQhu_B(_=th8rP z?Y|gpcc`+XE#m>|Z7JJ&Rs&P^1Cx`aoAE4_C=MXB29zq(%hyq4?XyoW(^OWkNcLA= zS>+$SQk+t~LHc&=n{sl-kK%!x1LQsMy=*3T+?dif{=vz=2Y#gmFbN#bl&@x@B^K3) z>FcZr7N)0c&k~709R>V5O4;jDIyddgx{D5~5b!+jDcjcyD{RYq2oMEOQs{HnD-dNh z$Ct@;yIO&CLG~(Ch1@#6|9ckx#Qy3L{dpGvI_mvDUHuCDmGpnr?yu_pXSyze-v7lu z`mdPyxA^V~<1EvZ*)5X``M~Q41a|F`&Aafm3%7+NdP%t0?KtVx4 zK%l@uK_LE?ssIBAg#dt{Ln6ONL8W72MnWUBCeo%SCS_p!LXt@)1Wa8(0}~n`5TI{> z^KoR+?Rg3MHXFG;G@k$e>;GIC{1lI3be-`cc@!vmc>|P*Tx#WVdfK3<+CYL%h}2crnYHFOCg!z5zFC+@rEK(yC0h+{)0YF+J=?4 zn`jPZkJWNdTJlf8Flp#^2TgWaj3e`Tu6dm?4P=G+C+Rx7S_VJnGJ&E6>a?npGs>PB zsMJPc?IJl-FI9Mg!&wx@lvt>J^ z<;*Z@8=BIT=4Sk&>TuHM06ItSVFF`tED}dI>Ds)mx`Xk7;hK7DM>Fc6Kne$MA*b$> zro9|Z@!<+c1&DadAeniL1m_%;^I;hxyw{0_+}VpMZS-?|nM+iuTmZzfJseN9- zy=@~pUzHGaj$r$#CCA=Yg1oeX;%q>vh6peF487}Y3&F=3iFG>nwo!lI+gd{3$h0YX$}gMTm|k<%4|%G|LnrmK=-OnD`tVKu{^)jJP

IrZM>%UzSfjJmCc9Lbuoo@`PKO==$(H)oWY~;M2}#&IDT7oLhN%LS>|`; z3=o3eL6^goEZ)$y$Y-kYe#kzAnesFbWEaJG$q*LSM+!VG;TnGNHo^9}FH6kuP z`s%uFR}l~Xw=!_I9C+W>{AN|v5}`#yaH_A!45x_t7JNxK<&e>>{X129%%OksBpSjB zjB=KOAsNC~A-z*Wj$%0_S=AgBAq%}g7#(V;sy`U64=rq{XGUA)N$xjP=0}(Mp6;9t zzLb$+Q$|j_h^`9}oK3niZ9_sWtgD|kqZPI-OiXt;ZyQ7<&E7rTssS>Vqu`U>a-l@iAE5zOfa-Mo6HTWMNdOzM5~ zAXVm9TQ_XqsHZlbiFGX5l>5w2Hv1wLl`fzRA{4HZmr1zo%*VV zZ-yI3v=>70(8{P19gDx8%^mB{K+h<5m3v?hSg#>}hcVDLh_l=*gA3{U5dwFls$M+T zk5jHH-u1dwrb6=pW^B{9N>Q0GSo=q2PJt1&GBTmadgRkr3!O2C0BX!C8lSbEO7sca zIL~OU;hB6;s>*CitIloxh*OKw5v`Bx!pIV4)+mi3^!wuwn+KqMm|gb_B~?H?=-7?K4BT?bYQWJ@!fbxcLScn%8xT zGnW!TumF6q*+N(ej6Otq#ZNOyE4E0UsXz_Xm~shUNH?#(h(>~5xiD$kTd*!3oUj_G zis5mpUH)1|hfEp^mthPBb{dtqQO^MDiHpuxIx&5i;dLbIp0M3br)!o4vDa}ygdz>i zpv$StVWMp|tc)U*^7+T7&JSq9bBhj*0`>GO#NNEK`V4~m-(yV122QnlGY@kV0i_w< ziIDxu6e!SU$IPX}%yuOhk5qA}Tc|E=Na1M{Blgv)Uy=3JS(NCn+ep z!dd$EO{3J$UW;;vIEdKv@q$mfPloNZU?lwnwa7VJGS0GZST!(IS&$O`g=ll}(+5n`ps!Y* z277*>{dU|g5Y&)s`<3VTZ-CFaIs?KVF`c*0%~`L2d6a_`C|o7JS9k?&cd{~)-G!uU z@!|zvlle1`M=ivWvcKMTi{BxV6ALE5fVmk$_l(Xzhc{eG zU+aaO$<|hX*s2q5Ei&&2q$ooND@e@FmP^SgUXko?;md!fqvw`neq52iZvOi^z902* zaI!pA2V4LNUL)Lo(kIH8N5{IS8wHs(5EYRM&l)N%E%_6;p_iHWHOJ;>2aMz&+|uI% z%beB@vg*5mLDY&9-DpPU0e+o&IgFKkR!K(kS#vWYBOpwfg8{qWNjGv(g zWant_*^p$4FDRs&~)kbL1??E8hAU1ttSrGi2Ed=%!%Ic_#`R z?u=aunLG@yyuJBeYDoE)8n|Tete8K!R2c+e{bAl-i2m>}hAt(Q&A|9IDcn$w&piub zH&~YJ`Z>!aVHnnZo;Vd8jXFrQs82|fVg$5LgZ4-~xpF6LRE~p7NcNZU5=>w&r|Y;n z37ABY_n_+uO_D7oHz+M*!Bq#Bhz+BBb?+OpR{>^oY}7(U{UG4DL3b3o4q>DCwjv;S zu6jCd?+&tX3^9_uBr~K2Or`n*;H61kTmHdVR{{t-<}1y`hnSWdp5R6<;l9w~1tE}@ zWqrIfL$23Y87mjnNl6grvWFqj=qkiZh*t)b?*|b@ekHamT_!83oIg`{+MJ8sLpj-S z9o4Y1%3w{-Y#`S}h^I2_rU!4ACE9}%Shg@L$NWedm)Z@L`g0v_-`A6)FW#j*Bvn9` z)>g74w=X}Q{oxc+$Wt;X-DAB0jw)`+oNN+sWT;k%-uaX^oTilb?@zqBC2Dejza)aE*ly=x(D`N`d6Pu!@5)%^yT zS2|YZC=nTa&sL>i$npm07Q{+UFut>R13Y1nMI=z|=tOk$f68SFT{k|B*8I|)-rvfa zNyXam(M$bzd$_}PxAo~;H)9d%7Kk$lvF(|kD)eh$87##UzjK*&3?oc9T4u9fkIN+OU0SOO;-eu@<#+m}8UL-JS>CvJVQm&@x{ne)(cbcDUcrMe(_)Dn+- ze|RhSw>7qNHN6pzd!cYMKdGXK;9t0uos-t*UBAvaU>&-Sy#X*u_?8}TUqnSiIM(t? zXX>aHN$`YaQ$5p8jNG(D(ZPq%ku$a#Iy+P(zJyV{7vK_g^yGYH?2Y{4?_GC&GG|^n z=koo`Ha@5Pwxu#v4D&tsaB{qCVhTw^2> z_@a!V5*iBAt4a)DPo6Pr(aef%y9LpIIIibMw(qd?U5iXF4Z4W{C3GBBJ4McDlJpDd zlCN>>A3YfoTCi)LTbye-9UdOGa)udNX`U;;- z{RSYCd0o%TJ_oc~y@#t>n>yqpsb2U=6xkER>8BG1$tU=gOwjTja?V!T02qmKF}Hs# zQ(#=)>AlyF-?xPOOVz~CQ>ACLJNAv_Bue>G;gHyCQ?dM^=$B#M+z&R6h?W#Y_YK%I zyDX7xU5pCmaPKznziUp759#IO7}zs1(LvVQk)CoFb{r;{#iN}9uyy-1e2P`4-fKsj zkfVhaw3&J$yJyN>(*MZaCgJWXF?P<==fFWZk7wqsrc6fR6_(0`ls(NJ_oG_7PD$Vy zt=EYTUi1^2I%{p1%#v`a_wL+YxIq)Bj65)O802PzH`RYr2BOB3raPd9I=nUaf)W^4UQig4f8_@FRH>m$uj0@BaSe<kHeDg0^K&|Wm!N*U@FDNly}8bzk|VPG0AuN>j3bd9F{l(N5eT9?Tn{FSdnIf6eJGncV4T+WnrJ+Uv+4T@MfC z&-I_2DuIrzbHUsdW8^OvWsqOX^zQ=X^xu!S1N{O}YQEe@!h{us^mjFM`6dv)h;*W)b@x*`jyO5(4fw6k%5ju{1$ee(M`8b*POaN zEuz#y8o83E3>QPJ1+~9eFO@^ucgwZo*})I($x5QR+Mz@}?%mYAFW4OU?7BD%d4*wX z92%PRVb}Xt@_FOe>~&|)@YcJ$el~woi$lKS%enPg*S~vV54>Nejhb@o6=vlv5~ubl{lab_ z$oalw`pMRSUsbp`;Ur5gj|mehzZI6^kXd^tQl>~R^SU(NhiUuE_VF@k`cE+T8ZW>l zZTXK!vZxYJ2}&Nq731ya*EtcQ{H|Lv3KjB)I6>R|1~rPI*H19xqMN%|dM70_m*uEb zqY8etOLK9ZN)bQ#B z<+XP$@Omc3yEVN2D)fp`aGNprhg2OR-A=k|?D$QGhG?f$*9zlv8m28WcRnZEGCOoe z6*oI6)Qg6Z<)gR0$ih3l7KadQ6+b>0%9r5!Ys5Jmdo%ksHYoh_hOsJ3&k|Xm_o_K)GE-UnX&8f0GYm!iL16ZH{${-B z?zIkM$ZKQJHQvR-Fg~J2b*`iSzYPL)i2e^@F35OB&(64{b_+_+%s7``C;nki*H-FW z57u%`8r5!0;;TxkslznuE1zl{?}Fn-D0=}-EMGhw73s>r$<_ml*d0A_<}HKQaGx#* z=|n9Ixtt%Rm?3oPwP^S|Gvgc9=5H+jJ_t`G;uB`EPn3Pt3g)re3sqH2nnlfub2M6% z<{UE~c{}-s(>Sc(R_lh)bsg&!gc{m)IH3sYOGPUp&~}^65dnLzKb5ZS1j7IB8Ok4n-zPEAh2-V%-xXS6ffd;C8YrBhQssA`vm*fgqHfI zwe0r+RJ76>V_t`=zq?6g&(}`7>B*`#g8>CHI?>b#a_Z9z7*<8eicJJ24yeO5>3Riq z#t3hKuT8?a*T>A|g$~a3m5D^(X21U^rtw-{eBUK2SbP){A0<_}YD>#4raNBh+Mwx} zW%>h)W0Oo))lc6)ZeNcl%QjprjP8eT$Ac%r#EX|8#2Q7e)h!DPVazv^#6p-#b679M zKcX2Yq*Pc{xjKpcrTD`2ISMgF#ZT_XpPsMKnW&YKtbc4Q={i$hH&ezP?i_;`ND*g= zsW+()&VFJ|=VKw(p{s6wq4C-EEHe9$GhLLew2x9rEPps3&e1oe=|Q2zfSo4y&5v(t zs^Cj-*)(*i)kVO(lb4EBji%^T!gm&gW{n(te*)3$;H=vu0T3mSiN}sVma_A^@|8p< z+%pN4*Cy?r#g~HrW7aQI%Ob8|PZH2IH;0|O_!&o6TF{`0o>LBih$4h{;*Y*FEmUHc z9X%~{gd51;5-w4 zGUqlP7l>~TJ~4}GOASBXwlX4dW5-z>TpJg@wPmgO|B?S^3j}joJL46&^#wI}&St^Kpfmo}tzp%t%$_BGQ^AgqXPv8g@gj0^8x{$ z)B4-VEO1~NlZb(s9)g7Kv#bpgDk1+@9cxByUE3&9CcAH0RcK%2qPqkjeSBjwvnR>; z1od)$PjEu=0u!7+#ut9B?38$`b+4hHH~6}n*XxB=^9;fRtZ}4bo5q&1 zvybIPZA(p@HV{(!r=hSKGMxJ1=YG99FTXpg0~oye>1t?`R=%qweZ~RH(TwY-;448HEZ4Dp6HE3) z%PJ0Zj-rzV;o#cO;rdZ&Rr^^H*_bJzpR;Ryrs8!k<-<}Gzc!p{U!H8;uJ0z#H{*_W z92v-x33!Ln&pqT1$YA;AY<-Nf_qE%v=)5|uP;o0mE3f|e&49!u|1Zh){GOFE6*WWmPuYH4oV>z7 zmx~$IVSFTBCwN|^_OTah?EO!jtvu#7MxXc2Y7U0NhX10Osq-V^6PpPqJ+`MqrjH|sVLX(8eD(q1!S>*-fGB^AK@3wGKHt$M-mcY%K z+>*RvwVO^qtlaVQ_geZa?X+(v!WgxfCuUU5hLEh2adIVA_6y5(* zHr%h2$11Ng_h~46PTneXC)WdVl(dv69;Q^zE+mIlkQy8mC$>kJ2E43j#yZBY5;6jt zDP{@B=b`s$N;m?o(}#LN@9@UZTQ%~yi~Glm(Z*jp{2UEiH|N+XzKb zN61SK0&TaS!M&dGtmLB!jVh|869cl{n73m116}Rm&$Yz;!Kn1}GvzH-8IyV(>p1C2 z3!xSHhib^G7KJTG!q8mGxu8Q&#At-D948$o+cB3dGv{drOST(+dUqjV9J25mDWANC#E+fmI5AO!u2t# z9iy_PkC6g?#iBPGg$JWqw>+np`ZqPvp+wE;;wDzeXy+;w!-$aT!@ zo=g73J{4O>mQKvjZFsWvedzWlG4*Azs*+>=muxN~-Kb6oSId0zy9^io*&Ex)qkY=% zi>{M+LbrtXW8J-1+TnS)F*Q3|{R%nGHn#|P;!hB_AEPjx(}tL@Dz~^gm37Vh{F&Gz zY3d7^gikyWJDDugQytrj3I>+Q^y*@;g;uT#a(4tDRM{J;Y_cCvw9K>?TE+qkW=~Gn zUMGz?B0Rt2nu|AWx6gcvB5hN40_`3G`Jm%JwcdqfvaJ_MEvFVm8hQ3<{M&`gt=>pO zX!TfOADo^c8rOJi^OHi|Ktc#GLu$x%2_vAqEP3TgruG3HaXTlXRvEebW`>28?y6TV zGl0z-cV#*oe%QO#Si@5SB?(2(sZ-tu(v-E0wdlyA^M)|am(9e!3jlKORcv129IXX~ z2il8|zf%NzEULV5Y8? z16oMyc08}bKFK`}H86Rkcbwyi3gajMyFTPvFQP)88%N~;UuEcB%)3c&uWHx7ei|r? zc&M}>@EAv9jJaZ^oq{j$&SjFluCkWN`BOn+-vF6km?|EMhT;V{^>){q?Fy|iT%A7~I-tAu@0Y#C&jEr_au_RB!>{Wj>10(~F1)pAPsLA!7G`7T4 zyNdNPrj>RWmyZ!J-F+rXwbQ0#%{83tQ!^KG{hA?Hz_z5 z_Lb`mU_Z%4P3_dP;)hx~8v6zi#8SY-;6N|D?!5!?FXRx#R&`4mC9h7VlIA|$M$swN z`|LzK8-?n;A{>e)rmTWoF@$cIEipG? z)h)Oh&e|?J=n%U(XQbuF0p5z=sDA+P_)QLxH_OZOX@&e8b5`46vS>;y=jvL7o;7=E z6?Bhq=hkX(g;I&O*#t4?OzgQJY|2^|LnQ{=!XgR@=A# zcm&t0I4pC9zr+zynIlS_@LvDB>Qb{DbhBFdCaLbAZ#nRFHqvfMR8zcb)mGqDLzruz zmf8qmPcJWtzpWJ)?Bn=CdS4_@@f}IdKrF z{Cs1EbbYsC(dCssq^O2XXifgXz-DA~>9~_qV}p+3+P?2XYs*_SDzRtIp_|rHW_i~B z{o4V+e{#WNPPNxvS+^?dOnaq>TiQOmvuE6lkgTNFK$$bg#a*DdsOMo!~Ad}FF%;KUn!lbD2ylDXR#n3#t^)wK==l@L4)9QAe;Y`eZ`(tQT?*HpM>XzZz@LW1PhT|tSVOH zU`cxU(w884Ni?`UYLc}t{qd&wLbrbH8K7v@N1 z&XZgzl#h*tKvKU5>49Xv2(qO_(DDMKT>rce=c)m0esEP?!uCt~L_eoK34mb%!*W<4tyGfUX2Pap9r;T1;uq6+krq(JX3 z>A7B8uEo+22Fe3m|b)JMN_{I;nS2le|ES^zw&2 zX=mxj3kOKt;#6~Ai2>iyL~ZK7AzcKu7)uA_sw$bnRF{;7m{iaiIu zQ7Ve)(#H!sn#-xr4ef&K%I4a}cynl|s#=}YsnkyVj&pnacA6~^|IXC!h9MYM$lpJv zV0SCuC9VgjoT`0I=8mc%ReXzOeMnd+xvLRm3^^@;ZtUn3=oonW`RgFsB0sg{7vKkKmCxTVTxfRzFYq+FX5wwx>m(o zCZ}%t4y=hsaUJKOl);an|B{D71Foy^3}(FdEXj7nx#bI&WrK|^#JpLcn^cTOullN` zddrF`DGc2U=mg0rvx;F94!V@z1T z1Ef*Xt-{e(C8Br!zIKs*0GVpXHgRw5gagS}zdh}6l!iC)@e>(^82k$uc#_$j|5JC% z&cI?M%^Gbs32@C{HZjkpzmkM6hQi=@nh+Wr&g{O=eFwS zxqAAonFIB6x_yqiTVQ&B2o_}vm!A zObU73shz{rShFGf%5j5cH<|J?;qeMeDd13TNMLR&LSz~K`+IR37r0Wf0lK4~p#670 zBe$2SRo(zsLJO{~T$R*Vde6*3PK$;xrTJ>{s3W5y@4BBqW(^>BO*{}^nAbiA2v32z ztm<{HC}3ZS%&FpRE4^Yz#pqHu5Nj2Ao6a02z{>l$FQ)4(gGeXmik%Yk;7F~o#dwRuNR1ux4 zSuS9vZtP3n04teD%dmQsuUjK`6NEV-oX`kY4&YIYIC|)EV}k7_njl%H$P)D` z>)*F`Wn{Z;P9xRDV+nOH)KlzS+D>B0s1Tjmj=kq#U0V4#YC?g*@FhHdgP2`|`BMCW z?h-*NZe@80qxz!pidt1ck~bNVarg}o^)Vuy%8; zBYi`OSLm1EQyw$0e)3BZBA@qeOJV+}QG0EJqe5%4_WHdt-5steH-fwE63?1p0}hcF zwp8EMsVW>qlE}#i8cz3tKFo1bnfNX@j?a%w+>LkFJL{2YZJ1Vl8^Jb}Fej||DgBn* z)d%p&X#F{p-In1KG-fDL0|m)@`)s)I-_26NB8g5?8=%x=q*gOOkFuIvYa!kC=V%FS zv)nRUD~?(`&#suGQyy$p(XEht>s-z#NL2Oc0>%q8V$1a-$IttVM!V(EwVLd?CFL=; z@Www^YelmOp86+SuN)SW<&BypQ}>EzQgrFYja%X?OC@L|9~<6+?+3!ob-P>UMocs~ zk`57mf2X$UY23wAHMoj;5|hwqnTUPF6}plM&u8Nq-yL`YuLrfs_c$W@910#mvI`$C zY~Dzx<)WMuueSd4V+EpHF#c6}&WIzNNHUd&Hua~`GIZ!9X_BDOBHSKljk0#re4QME z6?ta~Yw8_8gzX2ixNT4orga7PJDT~giP#S{?1x+BO96u88yl(nCB(h2C+H?cCT=1= zeWcmK&wlS$ zh&BqcKka<=+Vg;>+9s+(H4mh(lT*s-4*YMS0(F?qA6EOt4)Saj65m8-005+%im@>C>O_ZrR8m^7DC-orP9VNo0W^hzKZX@qnZwtXDe9p zIFV1%c>{0>eQirq#z1jC415^Pk6M*~>8F@R6Vt6<8q+3;g9ghYp|JuN8PiJ@sB*eDZHH>32C3)l*() zX-mwj`_Kf4jYcUjX)9wU)SREb4D^5c$tJU+}}|-tjzM5JE8JyaBL^Du-~ZqG@jv1V!m} z-i-z~riDg(9B3HVIw1*XU0^P#<<01_Zm>xgS5@<3jqE0+b#w^PXs&2k1LLX3*UOx{*Jstmk>Se7`#$xDbw zO8#^7eLh3@2@jcGaS8GTuzUDOk0{rTSw8)s2*lICC zh@NPI#C(2L=av^5w-%oXcPU!Cis#t(EaW?l7axv07jj>Lf4dq)+|>dT!fL#+Ozi0y zKZJhkC9fB^fVT#NJnay<4NzBGu{;y=5nIN2s90A{NmA|xX(q;^p*Hge7+Y~mB)kFq z-vCV_32`;A$zD6kd54>GJzEO2-)%sZIhYHa^X`6ejeT?M5K)kvD#?Ke^I_W7l2(p)W1yut5u3)Kie7kh&gP=nF-eLRq zf~bMEV1ry+1Gu38b(1cZ1wvIF*$eBFI?j#PDqBCNtm$A&&|zJu;4D%$N+Cl-=-S6r znjwrr%b3*p_c36jh77fTUMNL1D63MT=-ag83rrh@`ujzonHdKVxlt=lK2qmgD~2h% z;Yz`JgB)v&L6}?Z*Rx)$6Av|o_XS1+DM4*u24?D7oD3;nDkpa$X0ms0+iGYx*FgC6 z-(I+6;*2~$|4RY@EPj1;W4sz4iCq85{@0p zLKdD64fR%f1IW7RC!E(0ZKX$51lh86yFF^sOaE|oXfC@+j=-Jvd4-*03jbhhiTQLA;$WuLhPk?CO>&zPIC%-QWsekN@l){;BZbbJ>EADCXb56 zFe$SOgg4gU`F(`lhI7QDk!O_WWl^(%JXByTtSOzSH3Ut8vl+%cLr2~ZsgCOwS2SVd z*RM>e>waA$j~gxPgOpfY*+;g3a{^np?Z2%yMD*7+x*~80{4I9Be!fT&zIxxCF-MV4 zzc~*pUNBggkGz3t!<2J$79r*ZMTQE=2Ajvl^>OSVC^H%nfFU;gXo$-wid8@+N{Ky< zuGLziJ7hMJhb4%>KP@ikUhb5G^iroI?b;W~~htGpe0Y10Acpt>g8k-Yiy5Rc)^ zSMD;5N&k0?)RYh>x>Nbd4P?_TNntAX{`N~v(b@)2Q4xlLRV!Wc=3$WZHLNnb8EK4k zn;M_)Ko_>b`+3AuE{h4afCv0i537%T$L=kGCnmTsZN#>VbG~atcm#cA&E9rcI396tibMUG5{Qved#2N_5u?1yh=7Vc znQ7|b-#Br{$N2ff&Ykja+G22SA3HO4uL_!Wc3`q&rdAtpShO}CUl?4jO_T|bvMx7; zqEH(l117{QcnLZPscvzhK?0YUIHrNln>JGsBk+O2tLcl7{HO);+DN_%3YdTa`h#`B z&b8YooHPoYiVK>^u{;Z!0*jkTd9HLS7NgN3lib5Y%mIyv-5R0;v4iFC6?hPXnHip< zb(C2RW+f$ffs6jFup04Ymn(UhsxGSV9}k(EqRS6)3NnD%$;C`^{=I-P4A^7^csvrn zNV5x`)xnwJ({jwy{#P;)YBaj!T%YCi6LAMAcb|&fR5q1!3MC#{rmItumhFNA>A{Z(xRiZL!)2*gmdejbAc3yYFe?sd z)?nD< zT&ci_^jgRZyCy<-7mb4TWuz|Pq#<|kmi>QY?=7I?+Oc-QGCO8wW@hG?nVA`5j+vR6 zF=l3FW@e6Kra0y}wqrZ5a{vF{?%dbiue)b@-pra;t5zMAj=n7&X=|S?X=^J^5Uj3t zy>O3j%Y{brmDmg&jvZUxo^u^H`V_zYavA&7j4ooc;Np(|u31@#z&@B!JJDj6y$ZIo zo8$7Hi{78%a@oePcKTxpSGKX=uAcX0yt~ue`Y4d!n7}Vd*HXRUvv`ewj6&Bw@KH~~ zfqLZ=2~bDw3IAhY_%|c#P-e&4*Z`T=;{&hJj464A$yeXqsWZ?oQR|WohzI7Us!k3N zqV}|xho7pDR9Ph4!A>&fCl=OXvNbN1Udx`ksuQ=ap6nJKHy)}htsC3CbOg);YjK0Z zKGp+e_?Jco*~)R7vS|q!tGPeubBFH1&vHITlkRrDUDw{$xRjo{}TS*}kD$OH-YWXMuU`;>18v)kEN8JrW-%2nzoJ75=n6+8jHw+chMK2TqZjaCEH?h5*#`kUyL0rU(k}5=twJv z$#OwN(5krFp412Iz&WdOlEF`npWGP_JN$6(h!5!mYK%$znIQ?I#`@$n4$iR{e&~p`SM`%( zo;Nyjy!KJU1e9D+NDzv^qz{j)%iFDq(pMt+-ht+a*^l`@n{PBER3vMR0`ZDl0s32J zF;qUeJ;*Am8rOkCMP!f~nq9`mRaWUJ+=$!CRmv;QSng>Zh~suX^1vxYEUl69G@WlN zx_aZ#wx#)dmD-1pB}f{|k%y0i{#t5lHmP~NfvJgj@*fCrb&kr@uPxYv<`-g8NfxPh z9#698CC|dQZXDR6ngxrVq%!OWEeo#H6yHY+)O_AxKby&O5y>hf1K0A2Ppk&oqIYD_ zLB5a;#t{x3N*UmJxLi3KUCPGf5S%&ta`p@nM>&zMQ+Cc9GSqw-ZL}3*+-U6_2GNk; zxvxU58-((T^R&So^V#^hi24bsw`3ZFAV;FqQb)L69p*voyB>F?pn_cY^1YEyx-NXH z&E&-nuy6eUkStrOcT@}9|73^X=3V|~_xej@?}SIll+W?cT(&9Zc?$SA8Bjn>wXN_u zvG=BNtnl$CjMTH45WSH+_WHx>t@6!T*>_q)29w7w#brb72b#PMzM z!mVQ+#{n`g!+{o#4W!6Ak@J(s>wA7Tuz2s@$@0|`ZJd1ZRlrLbW$gGV4mM4@NtM^i za9p3oB=6OQCn`H(tGpg*EXEDc;t(8DMxH+ME?a|tB-mZ{P8tTUj(C*Npdsd0m3Mit z^+Elpp@x=VY&&Sbm;YSJ9y3gu6Ou1RRzIwSmf9AVrK*}tH&vO`_Pv7eS_yS0VP%-G zqui?81jTd6jlilIodokbTJ!Ck9?s;I;ZQ+UO7v9HM@6$nmJ%;RjSUiZa7fN8J7N^#+M8l@m`!`VwY00WmT?N@zO-Wlo#q6qN6UX^~%BSda<% z3fn!8CF(HizD5f&SYw~MAE$*>Jyuv7j*Ks$x*@!kpp*(XE%mCB;a~b`V)2saLxk`; z-T&RlwohrxAjZ&rt{J0K7m@U$?dLkeWZ_pwdBG)@4*Kt3J(igJYydnHxla` zC)@tiL#4B2hLQ=}sEmqynn1r_hF`n9d{uo3vs77az1TQ8@u;Vly$&;Vv-5?luW_g z0XUpTSMdqb3hwO7qUexX!@1DDRRb-_Um8$%vBQ5V!&O;8@VeHE;aKJ+DP8_-g27mN`>D zDN~EmUgkzmk}FgWqZux4b2WhUJm7SAiCWW8aGm=r5`j0w|LIg6P`%vR>UH%*BYVFumokZyVLXc*bewLD@? zGqcOh6-9kl;6#}n1u@aIhdt3FtiP5E-H?DTaDH^!D{B%jWJPJYyOf7x*Q(boe>uiN zf7e)DPm%lsNdtvB)fZDTP>IcW?_mERYpuxy$YJvlGVh!biM@vDWd20=`ZbkxFa@l} z2u|uN;RO@Nb_7n%j+MBOhIq91mqy4;Taa0d8YyX!TS->>11B4F3@$G!rr2@L9wzZ^ zp3Gi^Z2Cg0N9~BqE}68Pjr8%l3>6Q?a~@@l1E;|G~(FGA~kXr`es)zkQ^E}lzE|X4h2+l z=cx9=jr*&U%oD%RyHo+kw9(cM1iEuy7{Y-|;k*awqZoRh$gS|PtsaS>+zfxd(*s0b z+S)5Ql}}@ORcG?ktH)LM>`>zpstWu6tv~z#Fl=#$4!KpD>)Gq9eC_`K z(2s#-&pbA{qjQ|!YiJzM&W#QU00saBfIKoUlq-BcU7Hj{pDPzoJgLdJ7va>_^J?2D^pkuGilT_P7RZdtj7*0N|-5zWS^_ zM9nf^DW~-gwj|rDeDn+NJ@I^557-eVp4}9(d}vQBlOqkq>H62xF5#n&An9>D4etS4AzRNQr3b)#2eBC zXZ?%HL?3IW%NbcOBKeowiWNFIf`>p><`2(VarDY7GDSw89v%D@ln#|4R_I6yB zr>2i7*`BasZ6@h-^&)`U95$)C?1!DZqi2jzvcizsyFOdS7#H(}J`OBU9Cp?c!w^Z} ze3R(jr#kdZ^kZIIK8k5~H1kj~yKZo2gz|e|j-KdeR=tAZ4W2!2CBZb?0KL@wv70k$ z0?+dsZ{SrIzqlAu*4xQ$_sC`9!mJ?a4^b^mBKoNFqN146~;cJR5F)U!d#1FmE^{_U+a^hC0dc#8*IEN z3L}Ml+~J4wB$##lB%~lf(fI>VsG39*lcm5R%NMJoy|kbLo1&_!+?<7_tL;6aD!adT zB{>K?Jd!$MSC%|zZ-e~_bO?4d(hX_AQ|C65cu8z!Y?W`^2Yf~(S1Cvjd$G#)vuuKs z0_(utEz<0p+Ip;^kq;o*edW!@YG0y7yyRh;Zd;gZETdh}8r7(>-;l$|lBE&*JHkK0 zZ_o2@?x(RCqaruYxHK*H#dKL{kLyxAiGY`@>*RX$oh*E6#-WP}q3O~bJJ9Jn)bZsK z1{rk}aYMjz5FJZ2FMCz223z;D`TEuyS}&@z&lBs8KX<=p)o4Jec`^1xO%!i>bfp3!9zU|wCCk7Jzpy+(!`QH#L0#>B z`#aHGv>LZpR*2@I&4s9pIfEx*>m;YM8DA1RxB6LElu~?b#njlvn2-5rb4J%P#(dLe z*Q3u&Q%xxb!4f0-`1)Q1w_S~zo2hL#N9G^3?DVn9RAnD**`01lV+$FLm9p(^tP~z7 zC_`5!PAmCEU%@ofpJ(`nRU7nePaW*jp90mdZDSJA6(Z%1hgYb?LIj(i@_N7-hW}{G zQ$BD24MmpQIo9owgC5BcDz)vn_r6FAH`jA7tX+aDo16Op5{~NTz%`l_BZFCcj>gbw zcHmroEU8hU0c4nu6tbT4E1_n{5JNImqeNbras3TrlJ{4X=8#F`%j!X z`LJ-xI-cHK2hxcPyNov1ndE_FEA^cd)4pQZj*htB4Ju%FgwOT1!RAKu&%fb+bNSGJ zPm8Nkx$p4`@fD6N4h(7T0<;I3uAnixXAFk=%~T;&IcY!Qn}P`fjxAv(sx$32zroMK zG|#r2eh(DOh5MWR!khN`+Iw_?D%8m72-Bw4)g(p(HhTN*-%*U(7m2?_j_Qa&n>`$oj8#)e;9?=Ijp4{LXyPcVoN#9}-;EfADok-dqx!;03)EGSQi#Jg` zkDti<-?u|&kX%*W7~>$kTy<y z&DTV?5hT_$aqldhr7LNtVqGHv)p#S8|AuqzNxx`f+amph%4NT z*M87R@13o*_Mo)Iy#QHzeZV8Uo&Bg5o1XPmSAiAHdu=l9Yl@amO6+WcV`RAPddQ*G zmLWoGt5DVy|5^qxo?-Pg$E_MXM&$Cg7+n_ys3)Ll7v17jF5+n40yS|7waQY;;Z$~A zjeU4&>ZWDk26fWj=O2Ka@>VSooH2#&;jxgh$7aIx{X}G!{k3sgM`D}8g7~tHtX$dU z#DybMxO1Q31I?XG(UlM8a*k)66FsY8v>O2(mLhc|Rk9lM#+`=hMFvkKOz#sO6=*^8 zhRovxLz!XTvsL03r5^qO5dOl^goBN-Y$WjRSCt;UeK9zlRuswEm~7I@_xtV6NN4jN z>EJCC%pp%$WpWh<$waK&at?C0W0l1eD`8iBgZ8kG1xJ0!<{4)_n5Nj7n>JpLL;!tn;+uS#&e)8D}O)EZnTeH`B$87I`tlr#ddJ_e(;lAWujPC$^=(?)P@E-tvif+bd zjM(hbRL+3d&jXU;13`}HMF_5qr<*Bb6*B0s(lBYckz!IR%HXLgG!o{?vNt zHw<)66`PQo-GpKI?sQ*Wah{`Us}a7*b-h|6P!^S13DQit+lxc*Y;KY;TRMkasA}IS zM{2kh4hx5fZGphVPHSsJNka!Sar={8Q(`&Pqfbw40k$8Z9YS1-GS+IJtZh9^-|qxF z`Y?a5P>ZHaUNsbQspZI3=NCiwNJ@EuPfZ`34HdO$ur0ME5N%7@dX7$&UHBSg0Kv7Y zyr_Xl7Gkxhk|AdAN_HV`NwzVdp89Y=@6j7@dQ%(WYTnNf3>Uo6Dl?hBMo%vY5H~Dz z-I5vdnlv`43Y%1Zs9@1QY)Ts3J)(%XwQEUWMBeE%Kd600Mf9l!?M=0E_JB5;+7xZ` zgtJgg)UzL5TBGZ9mp5Kl?z~h_?T}u!0ZaC@ZB2+qDJ92zL6PY+*;ZU3l(QnH4npX9 zWAP`6pH?X21s`g9m~GF8GC-C_XXT}cImCUQ$1uKm!!1%fojTWy z{?=he9X@um_VBiPfn6~?*TzFv+&xq=Wdw6KQ}SNAEI}Wd-_r_p zsY3CLW?V^5+QZqnNL=d5cBTCknvioQ0qD+7m8!EV8@8Q7@g5pNq|frvM1G8 z0izx<1l!6z?KyGZmz1>pYIXL8TfNJiR&C*}ShgITu4V+CoT2)-cKT@Lv;@0F$) ziS*uMgz`{3#0p-sLk}bsy^o-Ukk4uCgMY-DrR}SCf|L&IE63kFBCH;7D6cseb9t+sD;MR}P}r z!TN$+Vbz*Ny3|$b>w$IHUuZ?X!UT*}FW5rS+E#H@$&#I9;_%hhcVq@k@*z5pBYVF~E>jxs*i9laq?k_bDPkOQ zk?MFyHW&6|WW04r&xlxzad!mL4EqBPhCZoDEk(;mP36bv4-{3<+Fs(c!6?Rl3m~(M2YX(9`#9K6DdwPC$KNSvFZ=Y_O8b5XJo1k%qbdk$`4{*$+6UVB`^0Sf!xvQ7B+j~Iq2vXE^=)Bc zQS5$ETwQzIiG;Sdc!pW~9Dwc6o^v1)Us2Z>;VoM{ocd62FPY=OjN8F@C5VJO#W?7Gb2cBl6mJ^1AtyepqR-Ls zoypd%XeYENBsiRy^hg+G2K42Pa7waDgMGMVSCEU9^SKjPM~BoA^HTxkmWNV@XVjR| z&L}Lr^Yytr|6Pm;*QfAjSE&PYx=AG*R(jsSu#=eqEjh0Fcb2FLu+}>~f@@b{T}vCx zvqdS`7*$EOz9CD6XvEyTlD95c^I=g?n4sdmA~ctCi6L4wCE_!PZ~74qv)(P&%cp3* z1np}i*)q=#uFRmJlrofIc%SLORLTZx#$Bd!?du<_*itS(H^TA{g{gzf8*e z*YxK&X_bsuE-cNcl7~n4XbiD@<|+zdWtFQ?>j=i+9_-GXC zs~fTij^Z@TLQ~e5X^disA@6SaH(Re1y3{v}h$^5k5-{$G0opH!fop0WzI>8Gyn|Oa zEb%BG5KM>_;C1)H<|+18!x+Fij+9l+HLN=o$dCEJW1NPK80UGV6FAx*VTh3U>qvH?qT(2Y{buWc?*t=PlzG;#4 z@Ov_fQ?HN-=KTVWj2lfMx%Gl@qPpSNf2H+4tT8?$Vv=_R5*l4X{V{sgs#p+hR)H4L zj(w0KukPq2TV!y$h_vTmduresYgIi({u)K8Xt%g+l`^CzO&3ay~xMZIm&~o9}UN@ievizKx1zoKE&I*{FZ~c=+P= zi&TnzPVXn-cy=Q3q)Kk==W_CH%S|N<>lTx?I=$yG|7t2ykiwy-(qMg&-gY+HT5snK z8K3?+C_WK)J~TTrCpxx_X(Tk^*3s7-zRb3A_-cm@teecmM`BUNMsJ5=@SUw%{VuBI z?n`Q>@w+cYVI*7;^gwMI5+_DXFLEFPvLaP`A>9<(lB_K>4Kpqwb0jNch*WZi)=W2k z^PB4j${iA$akkbm<98kT+rl$U;wiE0>_tSyuH>?6eFCCny(ovO*^2|u4s_zu$C(+p zl{Z)By48vbIY?XqhU)F|5Rf883*Le|`+9O!m6w66jXHY#vtvitDDpaoqw$|>RvU6$ zw5qR7P9>{qxG*lK&Mvt9^!_vn5ZV@yk)vb#SU+M-9EcVZd(0rfqUr$HJo>I;7c9=% zGeYBSz6&%Cop!Oo;P5`Wha*-d}RF=AK3dF(5jyR)nd zQT^43U3_oDVW-PSZkQ8!Pe$&5B4#HqT)|Aqob84IC0~0kd=e2^51fG>O~8D0Ew@zr z8;c8!>Nd^~KoCx}>IXD(G>o=kjZ-;TB(mCo_+Wl{-RGck7fqJ{s;bI>+-$sQn37j` zl>05?D_Un4Z>PqG*Uq!R2c%9+H~%~46EFVJYu-aab9|VTAAq`fnk|Vntl(Y>8?^H7 z`+jUIwkuZ$c|2iUTMm+{kLI*XB0?rM z#=PpKwRg*G)N{^;5r)wASA;7f9PS={9#vF{Z|= z605GhGIb?yTeqFN+#jnRbWJoq?zAh68_YR%!|{^q#FpNWlXPMe5EPrWUgjSXCoeZY zwxh0~JVVPXX(vl#ke*lfu;rG~H6lMmsHim!RmtdKU{tUatey|$J1ZO{vW}zn^Z7LL zvdqWxZJEg65vWJmiDn=1(-m#X#!#?p4;Va&7czUB_pXzSz)0|oYBkhhj?xve>az5} zq~jH+gm}EEtu97S={d~8G>j+*vvL-dKz)K{Q^8h%6BB zz;b+&lax&0V1tV?i8D&oLe?PdW9#eufQEMT0n&`TE>KPS*wNvRos=@}Ah%dXeR`ky z2&NI4t`yaEh##W!4y$>(Wv5pIQvS2xVw%u_Sf&7~kQ%5x!MNo_XwY9$C&`RA4z`$*ctjDzd z0Eh@X)bJzCyo_YulJn?G;6Bmd8?R6GYKb25C?!f&Oem{P((lZ<{{Z-hljrK_o3IoY zWC!<{M8TZ-Ri zCK?~Pep4o;o&7_z^7OWW^<{fn)GLBVKGzBt!Y!1_GuE}-tCxNfH3Q@$JT{s%>jG9H ztW+FlAO}jR3LZDYx56O4uV*B5^kl?@I;7SKg5bg+H8F@f5P;EOxx8BFt<gz z^DZ6v@3>%1qtGHa9znR$9}mThs3RuFKGCest*wYZhJhG}E{`u=Ay?{JV|553YW3FrGLXR^DBTMd6tnsTwV+c&zy|5s|^yG@99M(48VB)y< zv*;-92*69S(U3WK+?f&@mrPzt$>@r2%$K(|5=6(h3Vwh6bp{Z_bzps{Quz}Gm$0N1 zs!l0037V2Sc(b}YEKO);*W9wq!Xu1DCUGa@*K}K4Nz41PjH22^90d=ik>&m($O>PK z52_Sn*^%$Nf)h2BoX+h~0=0$31~lA(YLk26=M|-V$aZ4^21$XcUI;|k@5X1lMT{gp zWPwFjqF4!x?JYh`hD(h;p=P!+y)KTsa23VjSC_T8tr<>jo;t>yiEcJIlXNpZ2 zJ`nMC0lMat0fWPlD(N!TL~6CQ)TwnWYhP&7mx6=2M=(GH$yzQK0EP6va^n2~D4xAL z@Cy>Wrd@lWJ9}f6{*9iqor`>|{9LL=$=Mo*u=SgrbI%*6J;sWII5nFFY353wF*~wv zxs>b7Yz5laCKJs=z`Zl5gGMbA6&`cXNf?$P${*sGVR1Fh7hkJ?tymv+nWpOpe5rTK zkV_NQ({P+nh4j=wM_EKCI&wI1;{hfS&2EkMeu)*&DX<-YjgK zg@gPwBO^YEO?=m*pfD&lR!2*>*c_J)X)#yW(cM{tGZ{#uj53a&#_H>jR8U9D(hiXZ zG2xanr6`{X?)6KvUm^QVs44h7YWnU39a(Ir4KM^DrW1&18ZKIA<6pdunsmuK93QcH z20hm1VUX6_JG~=EPGjYlD8x4SNy8ApeC4nXheEB$+IlW*)3Y%;QLV~Dn=LvtzQT87ZrkL0_ROU46fvNfvm9J)NP*N{l1l7@3>cEHNU-%PBlZ zrb4h~9)vW{EaW1-9{n=ea{)m`(={i`r=4UmBf6|a((!E9Oq08j%NjLT@3MzVX|A|$ z@J-f&&vaUY>&gc6?-_l8XHxR4ryxQeUGIgWnc_IDlHBQz^T>}Ytf9)4w;sK^`bmBPC=a&JmfCSk((RHWxr zeICK^K!@|wQ|qt&s4woVzUqv9_;;hiW29v*EJb|VN>h4j>9dr~gm`1hBhIX=od`uY z<90UEMk*x=_lU@<)|~Uqy=U_)=`n$gMQ+wRlxFr2`Z(OVf+{eyA!+@$ejMit>+ z`1nU_D;#UDH)28NYuVdzGs1<&Yd#iH6N2g9om#_zF_|`ZA_^om*H+RM6hmjj*=9V+xvL(?T zN`rhQm&8A_HL$~L5v`IsYSM?kimwugl3@8+{HjI*cLibIfB0oAC^+Qv%OLs(0QpzU zv&1h<6n9Pdui=5V^~!5=H$z`oegNM6O1fw33TyKn7=1UE-CNXMCA+X8-$jcEYH^{r zJ=Bp4G3E)~tO+>To$b=Z2UeT)Gxjr3k zOfB>qIdUasG=LURUz?DXFF$)~@!>XFM71eAefot1@b9y*Wotvl*G&@}WX2^f1wOJ> z=p01~tJNnQStNb<MIRxnZN@;d(*6>zF;wGz7Tt-bx*zLH zD*p*OmYVu;E$l2c4*q(7U2A+@qq6>jfnD8-&!h@r#C@Fe18To(sHU0fNGV+IY#*iX zC_2!}nJB9te)lV0)lIcetnKdBHdbkK@Li`Xjak+!dxU9bOPZqh#jV2ZROX=FhCFWx zad<1aor*jnpA~!7&9_HQT;T|25{v4XdV< z*x|OfGYHQF8TxyCTw{5K3s&T*lad%?TdG#K)>W8$lUoE5e_=DqsV~FRZx!sZ&{I2?ChcT;r+I) zEh)Md>6=ocL2~#c!h_yAjij~lhh*vTVdfE5Bh-F9zsw=@{qMo52MtNDVD55)Im*n_)Om%XN zz0^`S4=AGQ^{ftF^_>L!l2^a>{@Pm~WUlZVh!4$ChN8Y({L(4@r`6j3w043j?4X6) z96;)UrIYhn}hC?uDYm_#ShCM1Ej|RI{{XnCS=SGnP_V$XgX;At%t@l62zYmk!8alY_xge* zDZ}*8U*A+o$dT`5Z9n^f>)o8Ksw=zMEPcQgk;=yR^@gA*NGw(MhKxaGH^Utj5SKP za<$Qc)|~f@#|xTr7)3QDjxQL9K1j1J%Ju$O{x?-RJmu1o@IuI@m>P;oG#twk+O-fH zcIr3F`WS>|=|Ou6B+fTwN$nDOBfX#uQ0kHZk!F5-YtK(Kz2&m z&fnD$1Pz}6U!S^cGXgom1nh->=*VoWS#<^W~mBh+$`GX3b`CWJb=W-v&1W+Vo#>%)m9Z zQ-kw+Ws12PT-lQ=G$LHySs8`<%6)1+cz}6qEe10OY?X$^55=!@hu)ZM5#%M>BaWIL zALA5zb05ex>xPGGk2LSGnSQ$tUwgH^YCf0?Em(VnF{C=Yf1b{WGk3j=eTWgFtNeb0 zMZBsL@@Nf{Z@yH1eZ*0-B*l!fbXahl-Cm}wfT{-Bg_S5-7am@{mg!h(Z?nCkWu({0 zr?Cq1H6XccFI9ASs5ge$puQeIcY1&;aA+fKH-Y}ojSbvV7ZN8zW0J&%?@_RKE26y> zOsDXL;Fr;Z-*tf(iNQwqe^!5ZhRK-AaPI}JwWT)QB-G~W+9Jxu9y0c!vk1eWwHn!s z)gjsrA8dPv>Gw;wjl04xi2h>zP!6e0f2lPNiLbut>_Uzt8BoS4>Xo#(e19+J3G_1iH-f^e z%-?=pgZKde`OvVE6>1n>;LfjI>tE5a z;Oq^67JxrTj>JF{LCt+k+mS8c=m%LC#igVjDVX6K$mjYP45}pw9GmdsqPA9p z@>ToS9KXiedzaUl-u2b*JU;*y2Irq&{!iThU3IYZ&i3F1I2qoMMRy9$0Az#D%`r&9 z#L&Y3kslPKpZ1^M|5N0Vf{TEpU5VX}P5*OQ5JM~M{l_Zkw_10i^mQF@m0$bMv;k7^ zc}~)U#k>Dl4dsll3r7A&*yq290)2Y{t;ONMKz^E*1O2oj{o$+i|LFkeznh^D0K^~e z-vcv20#G4{{yl7i1eJ0m)4zvx>?2Z+1VX`y0^tC{K##T1Oo9I_rJFz`Y#Bp z6d9yM1w3NWe;x}gGcYk+U=&|`08u;yn^V9)jg9;-EYQ6!kO0wJXd(dgzl=2=85EI^*gQI3m6hzvyvNQ)~E1dXX597F;fNdy`YLL?mhlm5+r=Swsn%|#^3 z74()Y=q*Q#`5g-ok%A+RflCl&tBc}O6bB$h;q6K=1&rcd&l3GT@E=$( zII2Y$I?y+C*P>X;QveW1a3DryfG^*l>+iAbAK1S~{2#>szX^-R)b|fc`j=aOl=&(M z4OJeCWPr(V2B3rhOaN~9msEc{^gEX9s-Mn3jx1pWEiee+@Dq!)^S2RyiTxe>mlyyz zR^MO!`v<|lf&B-mf4%j;9ZNI-4*UWOWeEG5xc-Y<@Lvo1SO0!5Gu2`w-EANmQy3l* z1b_&b0O;lWfA#qt%asTYo)Cy85=`YUh6MzHKoR|~pnvq=ze@P8%eub;|Fgm0%lyx# z|Lb&r1N&1_|5Kmev2Z_i0Fa-L3IaeI@CRPO|DL$`gYNHGv_K)OLRdEDC^(Tm0EiIq zK9$2CiT+ODcPtT5A_BmF<}C6CE$FwzeSZh?NA&O5KO+8x!2b^H&szQW@yIiZT~J9*d#*#HuksXxCsX;4OC2naR2%jS~(D0IhL#N-+;og6$n8K{np$61*Z5t zX@3kA=)bE63rPV0|Fop|J;UFx&_54rAVdbL;visuCE!2+zisn0jIXQj|KpGbq#I*H z;3Dj%oG2QME$Hs?nBnEg1Uk(gXRp6V3#)w*Ns+?<4E4DqkRs7fiU5fJnWB+ld_rCQ zZzO*nz<_jbY~s(IL74>tsNl7t>2N6i%n-e30%0krMA>(ZF9p9B89Pe&+fLM;Nh)9*{ALZgE-ubGS++-0ZuRWKH9&!j$|DVYJXoVD*LA~=H;CwJd zazrp8K!i{zprRFnehUSHz=(n68&L#_^cI|WI1UULhE^L$fWq1v^?$*jLD0^hHt7=- zL&WWD70AZALL~Iroy{FjY^X|2$HqHVP+A9Rb@vWGVw&o>_ z*QolPdDFtC`g>tL4DDpWOOT$YvPVl2Y(G5{{pNoEm*&*19YY%xn}_gRNT#La`tPwE zv@r!@ir~`D>ws36;!}|A6Y;#;cS2PhI4mb{+Taj_cX>W*8T}e$17|Mfdf;!}1SMr|$Xw$IW*O4kfwV`s--aNF*Yht8Ej|xkW;$33lxARu z)>((mhCiSp%c(1W0cF@YTXL087#-{a?XE2@Xd{41ve5$fkPFXWP~JTJ;18F7rKqS3 z%O79p`@(<)7V`cL9Iq*a^}}76Qa~}w`Sb0X5Q4zToj(@sc@zBs5r=eBZ3e%idG_l zY^C#rnKrq44BW0x(!H93_-_D3wp4d8xX@TK3BCzP>lDC^)ke%8gago?rxgwgT?{K`C#)<;+A$$d@j;Ihz+(J*% zK#I$3eM!vGB@&$KOA(KLQ@Ri_50#(IR+p1fpQFhbMe?Qx_kE8_$z0ioZEC3I`J!he znb1YeLQTS$3?&W4$jh7yO}-9cR+UBJ7gZs1R@^p^{oT^lrFlc2VbM*H$n>fqA$*Qzh@fX_qOR3`|EP9rMk>pFc$*-9 zbd-HEdd*Rc+Wxc9WHw?NlTFGk7>b~WNhJLt^M|0`cx4<9xKK$$xO+(-)IZhxj5xNP zCP?xC8}3;Ur*Rg6eq)s?n`{^Kcnso_lF=5w1|Jw5GEU_DEi`Ih9n=}&6WM&E5=Wk{ zQZoBueaxpjW13795~W30ZYc6!6eZelC^84x$T`(H^G~F!tsjuGEN+!Pt$x=(+)s=Jiz0Z- zRH}Nx$v^y>fdCRh%^r)1E0k`&&OWascV)A8092OHPa1-+z;bFLgkVC1h z(V<3`Zs7qUo#5{1o}2m&Cg{jkDODeyiqN)*yq&JWQ^@;<$2#+hVg!LDiASc1wC&<9 znCbXhsnAYk_L}xfI-Y13cyYdujcRMT7tGly7;n8s83r!>gPYiF3fcn^kyrCawfMB_ zzoJOwNgG$^P^v^Bf?VRi<*Ck<1$snC5AeX;dP_*1QA%F7m8y@p{>nc&N{$DG!53&H z*P8U8M`i6PS1!WlxX<;Xe5-mQOx$WvrnWK!!%U z&gFgXE5A1;sMg;3Td^V6XdFjqW^v>-e*wyQKoEETy1Pg-Arn#KB_sPX4k?tXZy~x^ zRf77{N2m#{O%B~s1$WhW2l&DZIcdIdqU!4fE0{~n;X}*%n+(OUnS4l}=R~?Gh6kbD z1sHZ%6UmK_T6xM>iKvd_NfPT-y(t4V;Y|FDYq!*AJKbqQn6k)lO+kzyCrzeW^N*p> z%H8Ad*gp4e@`}!ImOz@E)ool9;2QDlAcEjL@hLA{Vj>!`hclLyO`26mY7NjM3*Pm~ zy6#X)sJ^wM^gr2npK)Yha!t#}`*sNO2Vj9snpM0TGkDnU!~>jWELdNJDVt@%Gs4D@ z;EI2*m*O2%d$KfSZl46zH$$dWm4P@2edy`hitYmxjZGdv5P&WR!2hU7ExE8Kj6Jde(K2z>ujbAbb?jqI!7uvQCCrQ1VQRqoMT_$g^&oScPh>u}=MLp00tSIY7|7Iwi1twft2m?w!KxF#LPY1Ki6oxp&4>|#MM&I|gIdr6cm$g<=sIs<&26G*? z2)OKUk$VrK?oY8tq?p|ZaU;pyM<<4pFIuY}u90WkA3bjk-$UecG7bS3xIsprmsv*( z3Sm8i%OGE5H?Lfz{?yE@c=(>gcs{tGt>SR$Yfc+;F=r}>n*#j<@@*`*uqWp7mhnMI0oJI+pZ{${E5pn!Xo*>&Rz`G1Jch$VAW%;Mg~@r4&k* zUximM512XVf{0ZZ2)+3h!w-*W(nY(&=tY!~>$#GHIAsNj+OMEFMcIqTb_pyAUQ{b} zN$443xGaEqDC(lz=?9=6dz}$NsFX=$Wl`p)KwUYXHz3W$^{E^>ovGe1GL;LoD&aIu zKNOOri;klBDx6M)H%8H6vfzNR3hXQbnn}n9xh0#bVJ_V8Q$sEkQX}kDXr(0R0!U`O zB8rkvpW|cl&43xq9Gi#A9l;f400ylk`Mt=RkbvzcfWN5^_zwWVU%$4WHAjlQSuQcM z%5l(6(x`Ow9uclZCrPRc^%IaySyw;F5l^t!tBa5gBzJ(@FNxzWxEaDfkk%v;`d-Zg z@^EA;$ZL(v%_34)y(d`d!NxI@Ds^>NT51XdGYVL)ro#%EnYIO)Ylu#4o}?=~tY|W5(&(&8qgs7FgYiW`?r{|E>OH}W- zl@{{;y7eX{a76;=A~G?8w_hX~@??ZP-_CybRWv>#Hj*70mUgOS)-&-hsfb}W!g>dy zn9kNutXPM2)|~kTNkTljE8D(iHJye106)#4_B788p*>x2mFPVm@`Y-vmRS|(EzKe_ zF1;%b13}A#idH)Mfw(0)I=$x1~7sxrEU zT02bT)t(}9c1 z$buOqE2)<5Dw^&>M3>^>J1rSqi7?bSHLDrRBgD2DmgY6hB=70<&sRqDT4TWFK3n@v ziGUrZ1`HjigGa8IFaEbg{{97!J-pryvfslLQrPlQT#xhofk1TGQU7cw46U?Cfu= z0;)Q(I2~+}LRFc+muP(ueG{Z!Yy;0Tx2^%_pzkcoaNr4|Z@htjZIeaWHE)X4h1K)U zl~fB#3vTxzWJ6(zNDLw~;hYuU*oBt1az%5WEkry2#f$F!YpLu!&D0147dXwq9iP$`lC0qHeV z=}L*9paKehKmZ{~Gbkt^HMGz}RX{Kx0@9=lCCgFhUf+sP*lfli83PpOj;kKF`O3cDy-rw?5Q9Kcb={$SJ$4(S%ZAk&|A>$ z5hfS(a6eWd;qsdnP`bQ65Y2K*R%&$57`)o%mOD|FO^J%> zfFbw*It%+4#jU3w1FbHj!+`f{Ii?V(H}1ie!v}Yde`%)}B77tZM%5!B zKKT;)J~nSMC#sZZl7oeR4Ljv?fGrVtT$KgHk0_`H>N&N)-iHQ zxdG#!vuYxBUzB{w6J=X@Y3wjOD(vtq*wf4D6q5|o4wJ5N2_x_=g z=IP&l5`sl;uZ8G(d&_6qYHKW%Z{Rk?A!%K<3aU%3gRf*KzZR?l-;|{uxyoA0N$512 zN_AM38QO|iPrf0ZVm4;9;^sn>9avqyC-Da`W<8u#jcC{kDSUAfXVDI;`|TT59@zxo@#yu>Phqc51If8uij8=WG_ zKC!9%yzqowlO}=hyknnHUexkAf|8GYA?U1ws(7T|OHto)OFWJl6R^&~&~I_6m>e(j zjWp&>YM8GO=&=Qsb6QO-scY)oSy4Ad8@QhjFZgO7wv+Z$#D$#Zo z--b`?@Qd{DD7sZnB_EtWC!mUZJ{_HZXG65m*@>Wc23&+{@2@fx%cD6|DHLQ3yOL(( z)+}u8T2N&BEVXjjl$YGMDrkkDezU?RRxnO8VHJ5@cewCMaWF7z2O5`%=-rOVHS|;U zi*13~=P`EKGN~l;cr$;cE8-vO?k~^Dq)%l!d(ls!MfnMRCe^2ZHXn|B#|^nCklfe#domqQ+h zbWAOHG{EDDo0Kt!-OtVwJi4VhhT~FNQPTpmI4pLu1y@uSitAxuQoqledCdw>>hOrU zWd{Y$`Ey2+>^iS^n0ne*+^)7PvsZlKvJWpC6TSt4D!Mv^I(dM0m9|hMi3GjY4a~Z> zZJb+X=*zqx$MJIK4Efb2&863b?s`W#r?($tV$m2AP85ef=`uf*^&CUg>%$`UFS{~; zm?YBKD}9T%hPPh`OSt^C&wud`AOd+N3K>Zo7j6BBjk`v+P_QXeVGue74Yd{MsSKUg z959fldIb4=$a{cL$wi#@(DaTCcj*~?ok#U(*6cM$@IENPoWhcx)@zAz7+G2tJVY-j zKjYdrh^?ZUo>d{mjHy_|M}MX8>6;mw>R$9?H{PMxp+5kL;8p$64&VG?Cti>;#DXmNJzZU!PUA|;uTynh z$-6w=+xSoHa-JOT&2Q+v^;$Jn`vkUh9D5hj-Ge96x?f_Ng~B_={joEOk0mL!?H^Dt zW$wA%JB5f23tWodxD$(YB4L_;o6NfP5!g2`3~xCjyx8K@Yv7wQc=n46);MaFM7QEn0QtYK!%hxG}+fah9u5x=@0B zKV{zxUo!`EG_rC1RS$088>tt1nj3$h|9MKWU1vya!-%H&nY$9p(atCSRj-C5HxZ4l zb8I{&@fmj09+zNpm||(DX@5{d*>?QU6LjNn!BZjlGqGjW`a zUNU8O`0+gF#@;2eZ*SVm8G{(+_6nfH6P?YfbM%Rgj@iO#_9(A=A^@Acp^oP6&~W7f zMVj#UNv=2TSB7#(t?MroCu!sbN**HTnX`5JCLerqN=?f)3e52=jT?tN@|g0%ME$bR zkRV{kL9Ug$hjhfzl7oX26E4m53kN-rNUoLY~ z^bDu|@ATElydfLaQ^u{<;wo-N&|q)>pE8peE#h)S;q1o+Ip#1W=v*-#tpfF7N`;z^ zLb3t0?SYwA^SpICLLt$e(Wl3(g3naQXpG+T8?LeTiXcx@lL?H$9bkbCqD+Uu^gZ#% zj6Y)h%eZ!n{+g67WMIg1OCbAzB150Q6ZdT)1mFZ!uqv$vWIP|!?0rpS&8;IR+}yD0 z(KW$KubSRG+OX(nNLAij*EAgSMgDs92cQNAg~E6gvUi@g?Bf=%?f5Q21?@(x@OdT> zGB14^^Lu*z=T60aWo44%lZiCRN@1BS}84Q+LIVYn?FI@p)vexa07V zi#`GCM2+J_bXf3syC3Qu+3?k$cz7+kZ#3Oc-4qfE5$P8B*}u*@(VUKv=&Wbqu}LQ zRHk`u#MXs}^H13xUFpB*{+zXH)yjTt+b>9Poua5OFVaD~=J)zSFn`(O71lTtO!uh| z^nx{4Zt{aiUs!nSxUru?fls+N%~RX>qsEQ}JiGfMH@Z@|{18bMT7f+0m2 z%IRxMXT&AHFF!x#rNuXue1`WL2$y!)F>UnjcNUBy zom1dZMe8b8(WceO3V*_cg@_4t_=7wsa`?vK~)RQx43L{ z{ktv9rS29=WPa={#d?IDjAe%KT}{LnGe+(k+BN;O(vV7;&reRl(b7~?W-*)}_*~qP zV(-C{vrH{Jw08Q#u)N#R$_13!Osoyh>Mf9tqVosd1{HM!Bz_H|=@L z6|BH~9vJjD2qFZ|` zJMVDxc;5dJ(omC+3)3F}ql8sDEDOq-`~KXq9xw|SqoAC)f{e4r{6u@*=!gYW$0Ea# zrU{#l-r2GmzU@qu+WZWz%ro1@IADmxV7xVVffHhTMFNCKFmil(n=Rg}rc73oxlLy) z<7t}blYN=id;SXI@3&Cj+@>b3{{buqzzI?PnUZUzDRGl5l}?+J28Yj%SNGOP^Epv@ z8CmDATCc#N8s||^)=+)r+Rg6E?MV=k?$J*({<_SC>Py^brj`h|=}ZZ=QwDVB_kbmK z_Wro6oCY*+MkkvU*M+cD427#)hv6#xFFOUxx_!!;S_owEFHXg&5n~U~`Fp*Yj&$}^ z%dI%B#aU~ihK-BLjhd2-m^}%eYtld3Mq7lH%vuE{Oa{a^fc*iwzTF}nf`LNp!}Y-o zN1IEwI^;_o@q2-atExCpZ&xI_=_2M201@GMTq&q6?l2&jz$!2@4!Zk5XkdMx(HZE}Y%79p#lY6;L_vr7=U!H+81!DCMMKX9sO55L^(ze%4Z#7{!- zR4q)X>GA4KSt8MWt3~XVG?sB9qx_CPnu{K~X$2@mLi8GlH@o!sE=Uy4{(|Eqg_#L_$NxpI4Qa(7gzrsD?xsC_;_+*_Q-w$n_iFt?-hty z;aHYDyczLLWJ~we!P67`0?Y!nq;gcnjflsP#!?HtwnU0-=%nt5s#4}P>|o$M*)hcJ zcnx7Bx}Ow2ic^TH_x?>s_MNvI^2nrBAA0$vhIfGh%i-ZMpEBN_JmJHboZI!?v6>tg z9R#Xdict#C-a=fgmv-*nZ95K0gKqsh9QCzC!mXyOFXLjqboI%8RgQ}3^09x;$>a7= z-jJt4bIN_rpcuO_M|oH5dqE3!Epg+KxKR!Du~}q>AB)oC6pfI1u7UdH+fUAvNa==k zXgw}loJA4(8_z!OUJ$PvOt7mC42;q&L@cw`d@}#ZY-e&c@%>easHjOL5Lqg!OSd@A zZUqz-Q>~XRFPBHx1l%^2QyRh1s>E-aCSHlCnb_CU&TzJoMtz~kl#s%NBh`SqY4Lp( z-$^!B@_ACpyNsZ4o-C5LH>7o zq>C&_v}`j$l6j%TnS6s;farVMBd z-GWF#&df+}eUtY1a?a*T!&oXWMT!lr-sd)}dZ(BtQCRWUz^Q{alb~uJUwZEDy5Wh- z`V4lZJL;XOoxdi*LurUJo<`VhKO7vZjI6H@x<{lNzqnsq28~ z0ZE1kS{0E_lN4aJqy106IB$~tej0`+HY&W}V=Yl<5+g|7Wd;L)`uNST<1l(C_NZ5L zZz141y~DZ=@(L{lS$}+rHg_#sIF@iYetc~FuQmVB-9!1~@1`<4w92?H`@P@h>)47K z4!dBOv_3M}ReK3duhPL$p&F(D~D`VdH8i5_lxenJ`sP zGck^-dMj^8@iz-9@cd9u)E}K|+28Wsx=~;)^4GaJC{=XxftTfc$e<%KR4iH${Mf@xIcZ}8i&(uEvxllWy diff --git a/patchapp/src/main/res/layout/fragment_patch_step1.xml b/patchapp/src/main/res/layout/fragment_patch_step1.xml index cbd08035..18d1090b 100644 --- a/patchapp/src/main/res/layout/fragment_patch_step1.xml +++ b/patchapp/src/main/res/layout/fragment_patch_step1.xml @@ -6,12 +6,12 @@ android:layout_height="match_parent">