Move all common UI methods into ControlLayout

This commit is contained in:
artdeell 2023-05-06 22:35:04 +03:00
parent 76494960da
commit 616399906c
4 changed files with 171 additions and 176 deletions

View File

@ -1,31 +1,21 @@
package net.kdt.pojavlaunch; package net.kdt.pojavlaunch;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.provider.DocumentsContract; import android.provider.DocumentsContract;
import android.view.View; import android.view.View;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView; import android.widget.ListView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.drawerlayout.widget.DrawerLayout; import androidx.drawerlayout.widget.DrawerLayout;
import com.google.gson.JsonSyntaxException;
import com.kdt.pickafile.FileListView;
import com.kdt.pickafile.FileSelectedListener;
import net.kdt.pojavlaunch.customcontrols.ControlData; import net.kdt.pojavlaunch.customcontrols.ControlData;
import net.kdt.pojavlaunch.customcontrols.ControlDrawerData; import net.kdt.pojavlaunch.customcontrols.ControlDrawerData;
import net.kdt.pojavlaunch.customcontrols.ControlLayout; import net.kdt.pojavlaunch.customcontrols.ControlLayout;
import net.kdt.pojavlaunch.customcontrols.EditorExitable; import net.kdt.pojavlaunch.customcontrols.EditorExitable;
import net.kdt.pojavlaunch.prefs.LauncherPreferences; import net.kdt.pojavlaunch.prefs.LauncherPreferences;
import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -33,7 +23,6 @@ public class CustomControlsActivity extends BaseActivity implements EditorExitab
private DrawerLayout mDrawerLayout; private DrawerLayout mDrawerLayout;
private ListView mDrawerNavigationView; private ListView mDrawerNavigationView;
private ControlLayout mControlLayout; private ControlLayout mControlLayout;
private static String sSelectedName = "new_control";
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -55,12 +44,12 @@ public class CustomControlsActivity extends BaseActivity implements EditorExitab
case 0: mControlLayout.addControlButton(new ControlData("New")); break; case 0: mControlLayout.addControlButton(new ControlData("New")); break;
case 1: mControlLayout.addDrawer(new ControlDrawerData()); break; case 1: mControlLayout.addDrawer(new ControlDrawerData()); break;
//case 2: mControlLayout.addJoystickButton(new ControlData()); break; //case 2: mControlLayout.addJoystickButton(new ControlData()); break;
case 2: load(mControlLayout); break; case 2: mControlLayout.openLoadDialog(); break;
case 3: save( mControlLayout, this); break; case 3: mControlLayout.openSaveDialog(this); break;
case 4: dialogSelectDefaultCtrl(mControlLayout); break; case 4: mControlLayout.openSetDefaultDialog(); break;
case 5: // Saving the currently shown control case 5: // Saving the currently shown control
try { try {
Uri contentUri = DocumentsContract.buildDocumentUri(getString(R.string.storageProviderAuthorities), doSaveCtrl(sSelectedName, mControlLayout)); Uri contentUri = DocumentsContract.buildDocumentUri(getString(R.string.storageProviderAuthorities), mControlLayout.saveToDirectory(mControlLayout.mLayoutFileName));
Intent shareIntent = new Intent(); Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND); shareIntent.setAction(Intent.ACTION_SEND);
@ -69,7 +58,7 @@ public class CustomControlsActivity extends BaseActivity implements EditorExitab
shareIntent.setType("application/json"); shareIntent.setType("application/json");
startActivity(shareIntent); startActivity(shareIntent);
Intent sendIntent = Intent.createChooser(shareIntent, sSelectedName); Intent sendIntent = Intent.createChooser(shareIntent, mControlLayout.mLayoutFileName);
startActivity(sendIntent); startActivity(sendIntent);
}catch (Exception e) { }catch (Exception e) {
Tools.showError(this, e); Tools.showError(this, e);
@ -79,8 +68,11 @@ public class CustomControlsActivity extends BaseActivity implements EditorExitab
mDrawerLayout.closeDrawers(); mDrawerLayout.closeDrawers();
}); });
mControlLayout.setModifiable(true); mControlLayout.setModifiable(true);
try {
loadControl(LauncherPreferences.PREF_DEFAULTCTRL_PATH, mControlLayout); mControlLayout.loadLayout(LauncherPreferences.PREF_DEFAULTCTRL_PATH);
}catch (IOException e) {
Tools.showError(this, e);
}
} }
@Override @Override
@ -88,140 +80,6 @@ public class CustomControlsActivity extends BaseActivity implements EditorExitab
mControlLayout.askToExit(this); mControlLayout.askToExit(this);
} }
public static void dialogSelectDefaultCtrl(final ControlLayout layout) {
AlertDialog.Builder builder = new AlertDialog.Builder(layout.getContext());
builder.setTitle(R.string.customctrl_selectdefault);
builder.setPositiveButton(android.R.string.cancel, null);
final AlertDialog dialog = builder.create();
FileListView flv = new FileListView(dialog, "json");
flv.lockPathAt(new File(Tools.CTRLMAP_PATH));
flv.setFileSelectedListener(new FileSelectedListener(){
@Override
public void onFileSelected(File file, String path) {
setDefaultControlJson(path,layout);
dialog.dismiss();
}
});
dialog.setView(flv);
dialog.show();
}
public static void save(final ControlLayout layout, final EditorExitable exitListener) {
final Context ctx = layout.getContext();
final EditText edit = new EditText(ctx);
edit.setSingleLine();
edit.setText(sSelectedName);
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.setTitle(R.string.global_save);
builder.setView(edit);
builder.setPositiveButton(android.R.string.ok, null);
builder.setNegativeButton(android.R.string.cancel, null);
if(exitListener != null) builder.setNeutralButton(R.string.global_save_and_exit, null);
final AlertDialog dialog = builder.create();
dialog.setOnShowListener(dialogInterface -> {
dialog.getButton(AlertDialog.BUTTON_POSITIVE)
.setOnClickListener(new OnClickExitListener(dialog, edit, layout, null));
if(exitListener != null) dialog.getButton(AlertDialog.BUTTON_NEUTRAL)
.setOnClickListener(new OnClickExitListener(dialog, edit, layout, exitListener));
});
dialog.show();
}
static class OnClickExitListener implements View.OnClickListener {
private final AlertDialog mDialog;
private final EditText mEditText;
private final ControlLayout mLayout;
private final EditorExitable mListener;
public OnClickExitListener(AlertDialog mDialog, EditText mEditText, ControlLayout mLayout, EditorExitable mListener) {
this.mDialog = mDialog;
this.mEditText = mEditText;
this.mLayout = mLayout;
this.mListener = mListener;
}
@Override
public void onClick(View v) {
Context context = v.getContext();
if (mEditText.getText().toString().isEmpty()) {
mEditText.setError(context.getString(R.string.global_error_field_empty));
return;
}
try {
String jsonPath = doSaveCtrl(mEditText.getText().toString(),mLayout);
Toast.makeText(context, context.getString(R.string.global_save) + ": " + jsonPath, Toast.LENGTH_SHORT).show();
mDialog.dismiss();
if(mListener != null) mListener.exitEditor();
} catch (Throwable th) {
Tools.showError(context, th, mListener != null);
}
}
}
public static void showExitDialog(Context context, EditorExitable exitListener) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.customctrl_editor_exit_title);
builder.setMessage(R.string.customctrl_editor_exit_msg);
builder.setPositiveButton(R.string.global_yes, (d,w)->exitListener.exitEditor());
builder.setNegativeButton(R.string.global_no, (d,w)->{});
builder.show();
}
public static void load(final ControlLayout layout) {
AlertDialog.Builder builder = new AlertDialog.Builder(layout.getContext());
builder.setTitle(R.string.global_load);
builder.setPositiveButton(android.R.string.cancel, null);
final AlertDialog dialog = builder.create();
FileListView flv = new FileListView(dialog, "json");
if(Build.VERSION.SDK_INT < 29)flv.listFileAt(new File(Tools.CTRLMAP_PATH));
else flv.lockPathAt(new File(Tools.CTRLMAP_PATH));
flv.setFileSelectedListener(new FileSelectedListener(){
@Override
public void onFileSelected(File file, String path) {
loadControl(path,layout);
dialog.dismiss();
}
});
dialog.setView(flv);
dialog.show();
}
private static void setDefaultControlJson(String path,ControlLayout ctrlLayout) {
// Load before save to make sure control is not error
try {
ctrlLayout.loadLayout(path);
LauncherPreferences.DEFAULT_PREF.edit().putString("defaultCtrl", path).apply();
LauncherPreferences.PREF_DEFAULTCTRL_PATH = path;
} catch (IOException| JsonSyntaxException exception) {
Tools.showError(ctrlLayout.getContext(), exception);
}
}
private static String doSaveCtrl(String name, final ControlLayout layout) throws Exception {
String jsonPath = Tools.CTRLMAP_PATH + "/" + name + ".json";
layout.saveLayout(jsonPath);
return jsonPath;
}
private static void loadControl(String path,ControlLayout layout) {
try {
layout.loadLayout(path);
sSelectedName = path.replace(Tools.CTRLMAP_PATH, ".");
// Remove `.json`
sSelectedName = sSelectedName.substring(0, sSelectedName.length() - 5);
} catch (Exception e) {
Tools.showError(layout.getContext(), e);
}
}
@Override @Override
public void exitEditor() { public void exitEditor() {
super.onBackPressed(); super.onBackPressed();

View File

@ -111,10 +111,10 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe
case 0: mControlLayout.addControlButton(new ControlData("New")); break; case 0: mControlLayout.addControlButton(new ControlData("New")); break;
case 1: mControlLayout.addDrawer(new ControlDrawerData()); break; case 1: mControlLayout.addDrawer(new ControlDrawerData()); break;
//case 2: mControlLayout.addJoystickButton(new ControlData()); break; //case 2: mControlLayout.addJoystickButton(new ControlData()); break;
case 2 : CustomControlsActivity.load(mControlLayout); break; case 2 : mControlLayout.openLoadDialog(); break;
case 3: CustomControlsActivity.save(mControlLayout, this); break; case 3: mControlLayout.openSaveDialog(this); break;
case 4: CustomControlsActivity.dialogSelectDefaultCtrl(mControlLayout); break; case 4: mControlLayout.openSetDefaultDialog(); break;
case 5: CustomControlsActivity.showExitDialog(this, this); case 5: mControlLayout.openExitDialog(this);
} }
}; };

View File

@ -1,21 +1,29 @@
package net.kdt.pojavlaunch.customcontrols; package net.kdt.pojavlaunch.customcontrols;
import static android.content.Context.INPUT_METHOD_SERVICE; import static android.content.Context.INPUT_METHOD_SERVICE;
import static net.kdt.pojavlaunch.Tools.currentDisplayMetrics; import static net.kdt.pojavlaunch.Tools.currentDisplayMetrics;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.*; import android.content.Context;
import android.util.*; import android.os.Build;
import android.view.*; import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.*; import android.widget.EditText;
import com.google.gson.*; import android.widget.FrameLayout;
import java.io.*; import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import androidx.appcompat.app.AlertDialog;
import net.kdt.pojavlaunch.*; import com.google.gson.JsonSyntaxException;
import com.kdt.pickafile.FileListView;
import com.kdt.pickafile.FileSelectedListener;
import net.kdt.pojavlaunch.MinecraftGLSurface;
import net.kdt.pojavlaunch.R;
import net.kdt.pojavlaunch.Tools;
import net.kdt.pojavlaunch.customcontrols.buttons.ControlButton; import net.kdt.pojavlaunch.customcontrols.buttons.ControlButton;
import net.kdt.pojavlaunch.customcontrols.buttons.ControlDrawer; import net.kdt.pojavlaunch.customcontrols.buttons.ControlDrawer;
import net.kdt.pojavlaunch.customcontrols.buttons.ControlInterface; import net.kdt.pojavlaunch.customcontrols.buttons.ControlInterface;
@ -23,8 +31,13 @@ import net.kdt.pojavlaunch.customcontrols.buttons.ControlSubButton;
import net.kdt.pojavlaunch.customcontrols.handleview.ActionRow; import net.kdt.pojavlaunch.customcontrols.handleview.ActionRow;
import net.kdt.pojavlaunch.customcontrols.handleview.ControlHandleView; import net.kdt.pojavlaunch.customcontrols.handleview.ControlHandleView;
import net.kdt.pojavlaunch.customcontrols.handleview.EditControlPopup; import net.kdt.pojavlaunch.customcontrols.handleview.EditControlPopup;
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
import net.kdt.pojavlaunch.prefs.*; import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class ControlLayout extends FrameLayout { public class ControlLayout extends FrameLayout {
protected CustomControls mLayout; protected CustomControls mLayout;
@ -40,7 +53,8 @@ public class ControlLayout extends FrameLayout {
private EditControlPopup mControlPopup = null; private EditControlPopup mControlPopup = null;
private ControlHandleView mHandleView; private ControlHandleView mHandleView;
private ControlButtonMenuListener mMenuListener; private ControlButtonMenuListener mMenuListener;
public ActionRow actionRow = null; public ActionRow mActionRow = null;
public String mLayoutFileName;
public ControlLayout(Context ctx) { public ControlLayout(Context ctx) {
super(ctx); super(ctx);
@ -55,6 +69,7 @@ public class ControlLayout extends FrameLayout {
CustomControls layout = LayoutConverter.loadAndConvertIfNecessary(jsonPath); CustomControls layout = LayoutConverter.loadAndConvertIfNecessary(jsonPath);
if(layout != null) { if(layout != null) {
loadLayout(layout); loadLayout(layout);
updateLoadedFileName(jsonPath);
return; return;
} }
@ -62,9 +77,9 @@ public class ControlLayout extends FrameLayout {
} }
public void loadLayout(CustomControls controlLayout) { public void loadLayout(CustomControls controlLayout) {
if(actionRow == null){ if(mActionRow == null){
actionRow = new ActionRow(getContext()); mActionRow = new ActionRow(getContext());
addView(actionRow); addView(mActionRow);
} }
removeAllButtons(); removeAllButtons();
@ -355,7 +370,7 @@ public class ControlLayout extends FrameLayout {
// When the input window cannot be hidden, it returns false // When the input window cannot be hidden, it returns false
if(!imm.hideSoftInputFromWindow(getWindowToken(), 0)){ if(!imm.hideSoftInputFromWindow(getWindowToken(), 0)){
if(mControlPopup.disappearLayer()){ if(mControlPopup.disappearLayer()){
actionRow.setFollowedButton(null); mActionRow.setFollowedButton(null);
mHandleView.hide(); mHandleView.hide();
} }
} }
@ -372,7 +387,7 @@ public class ControlLayout extends FrameLayout {
mControlPopup.disappear(); mControlPopup.disappear();
} }
if(actionRow != null) actionRow.setFollowedButton(null); if(mActionRow != null) mActionRow.setFollowedButton(null);
if(mHandleView != null) mHandleView.hide(); if(mHandleView != null) mHandleView.hide();
} }
@ -410,9 +425,131 @@ public class ControlLayout extends FrameLayout {
public void askToExit(EditorExitable editorExitable) { public void askToExit(EditorExitable editorExitable) {
if(mIsModified) { if(mIsModified) {
CustomControlsActivity.save(this, editorExitable); openSaveDialog(editorExitable);
}else{ }else{
CustomControlsActivity.showExitDialog(getContext(), editorExitable); openExitDialog(editorExitable);
} }
} }
public void updateLoadedFileName(String path) {
path = path.replace(Tools.CTRLMAP_PATH, ".");
path = path.substring(0, path.length() - 5);
mLayoutFileName = path;
}
public String saveToDirectory(String name) throws Exception{
String jsonPath = Tools.CTRLMAP_PATH + "/" + name + ".json";
saveLayout(jsonPath);
return jsonPath;
}
class OnClickExitListener implements View.OnClickListener {
private final AlertDialog mDialog;
private final EditText mEditText;
private final EditorExitable mListener;
public OnClickExitListener(AlertDialog mDialog, EditText mEditText, EditorExitable mListener) {
this.mDialog = mDialog;
this.mEditText = mEditText;
this.mListener = mListener;
}
@Override
public void onClick(View v) {
Context context = v.getContext();
if (mEditText.getText().toString().isEmpty()) {
mEditText.setError(context.getString(R.string.global_error_field_empty));
return;
}
try {
String jsonPath = saveToDirectory(mEditText.getText().toString());
Toast.makeText(context, context.getString(R.string.global_save) + ": " + jsonPath, Toast.LENGTH_SHORT).show();
mDialog.dismiss();
if(mListener != null) mListener.exitEditor();
} catch (Throwable th) {
Tools.showError(context, th, mListener != null);
}
}
}
public void openSaveDialog(EditorExitable editorExitable) {
final Context context = getContext();
final EditText edit = new EditText(context);
edit.setSingleLine();
edit.setText(mLayoutFileName);
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.global_save);
builder.setView(edit);
builder.setPositiveButton(android.R.string.ok, null);
builder.setNegativeButton(android.R.string.cancel, null);
if(editorExitable != null) builder.setNeutralButton(R.string.global_save_and_exit, null);
final AlertDialog dialog = builder.create();
dialog.setOnShowListener(dialogInterface -> {
dialog.getButton(AlertDialog.BUTTON_POSITIVE)
.setOnClickListener(new OnClickExitListener(dialog, edit, null));
if(editorExitable != null) dialog.getButton(AlertDialog.BUTTON_NEUTRAL)
.setOnClickListener(new OnClickExitListener(dialog, edit, editorExitable));
});
dialog.show();
}
public void openLoadDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(R.string.global_load);
builder.setPositiveButton(android.R.string.cancel, null);
final AlertDialog dialog = builder.create();
FileListView flv = new FileListView(dialog, "json");
if(Build.VERSION.SDK_INT < 29)flv.listFileAt(new File(Tools.CTRLMAP_PATH));
else flv.lockPathAt(new File(Tools.CTRLMAP_PATH));
flv.setFileSelectedListener(new FileSelectedListener(){
@Override
public void onFileSelected(File file, String path) {
try {
loadLayout(path);
}catch (IOException e) {
Tools.showError(getContext(), e);
}
dialog.dismiss();
}
});
dialog.setView(flv);
dialog.show();
}
public void openSetDefaultDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(R.string.customctrl_selectdefault);
builder.setPositiveButton(android.R.string.cancel, null);
final AlertDialog dialog = builder.create();
FileListView flv = new FileListView(dialog, "json");
flv.lockPathAt(new File(Tools.CTRLMAP_PATH));
flv.setFileSelectedListener(new FileSelectedListener(){
@Override
public void onFileSelected(File file, String path) {
try {
LauncherPreferences.DEFAULT_PREF.edit().putString("defaultCtrl", path).apply();
LauncherPreferences.PREF_DEFAULTCTRL_PATH = path;loadLayout(path);
}catch (IOException|JsonSyntaxException e) {
Tools.showError(getContext(), e);
}
dialog.dismiss();
}
});
dialog.setView(flv);
dialog.show();
}
public void openExitDialog(EditorExitable exitListener) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(R.string.customctrl_editor_exit_title);
builder.setMessage(R.string.customctrl_editor_exit_msg);
builder.setPositiveButton(R.string.global_yes, (d,w)->exitListener.exitEditor());
builder.setNegativeButton(R.string.global_no, (d,w)->{});
builder.show();
}
} }

View File

@ -348,7 +348,7 @@ public interface ControlInterface extends View.OnLongClickListener {
default boolean onLongClick(View v){ default boolean onLongClick(View v){
if (getControlLayoutParent().getModifiable()) { if (getControlLayoutParent().getModifiable()) {
getControlLayoutParent().editControlButton(this); getControlLayoutParent().editControlButton(this);
getControlLayoutParent().actionRow.setFollowedButton(this); getControlLayoutParent().mActionRow.setFollowedButton(this);
} }
return true; return true;