This commit is contained in:
wheremyfoodat 2024-01-16 20:58:35 +02:00
commit 150ca43cf0
13 changed files with 64 additions and 34 deletions

View file

@ -35,6 +35,7 @@ public class PandroidApplication extends Application {
case GlobalConfig.THEME_BLACK: case GlobalConfig.THEME_BLACK:
return R.style.Theme_Pandroid_Black; return R.style.Theme_Pandroid_Black;
} }
return R.style.Theme_Pandroid; return R.style.Theme_Pandroid;
} }
@ -46,6 +47,7 @@ public class PandroidApplication extends Application {
case GlobalConfig.THEME_LIGHT: case GlobalConfig.THEME_LIGHT:
return false; return false;
} }
Resources res = Resources.getSystem(); Resources res = Resources.getSystem();
int nightFlags = res.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; int nightFlags = res.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
return nightFlags == Configuration.UI_MODE_NIGHT_YES; return nightFlags == Configuration.UI_MODE_NIGHT_YES;

View file

@ -22,6 +22,7 @@ public class BottomDialogFragment extends DialogFragment {
Dialog dialog = super.onCreateDialog(savedInstanceState); Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.getWindow().setGravity(Gravity.CENTER | Gravity.BOTTOM); dialog.getWindow().setGravity(Gravity.CENTER | Gravity.BOTTOM);
dialog.getWindow().getAttributes().y = Math.round(getContext().getResources().getDisplayMetrics().density * 15); dialog.getWindow().getAttributes().y = Math.round(getContext().getResources().getDisplayMetrics().density * 15);
return dialog; return dialog;
} }
} }

View file

@ -26,7 +26,7 @@ import com.panda3ds.pandroid.view.code.syntax.CodeSyntax;
import java.io.Serializable; import java.io.Serializable;
public class CodeEditorActivity extends BaseActivity { public class CodeEditorActivity extends BaseActivity {
private static final String TAB_CONTENT = " "; private static final String TAB = " ";
private String path; private String path;
private String fileName; private String fileName;
private CodeEditor editor; private CodeEditor editor;
@ -34,7 +34,6 @@ public class CodeEditorActivity extends BaseActivity {
private View saveButton; private View saveButton;
private boolean changed = false; private boolean changed = false;
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -56,9 +55,10 @@ public class CodeEditorActivity extends BaseActivity {
new Task(() -> { new Task(() -> {
String content = FileUtils.readTextFile(path + "/" + fileName); String content = FileUtils.readTextFile(path + "/" + fileName);
editor.post(() -> { editor.post(() -> {
editor.setText(content); editor.setText(content);
editor.setSyntax(CodeSyntax.obtainByFileName(fileName)); editor.setSyntax(CodeSyntax.getFromFilename(fileName));
editor.setOnContentChangedListener(this::onDocumentContentChanged); editor.setOnContentChangedListener(this::onDocumentContentChanged);
}); });
}).start(); }).start();
@ -78,7 +78,7 @@ public class CodeEditorActivity extends BaseActivity {
((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0); ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
}); });
findViewById(R.id.key_tab).setOnClickListener(v -> { findViewById(R.id.key_tab).setOnClickListener(v -> {
editor.insert(TAB_CONTENT); editor.insert(TAB);
}); });
} }
@ -115,14 +115,16 @@ public class CodeEditorActivity extends BaseActivity {
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
private void onDocumentContentChanged() { private void onDocumentContentChanged() {
title.setText("*" + fileName);
changed = true; changed = true;
title.setText("*" + fileName);
saveButton.setVisibility(View.VISIBLE); saveButton.setVisibility(View.VISIBLE);
} }
public void save() { public void save() {
title.setText(fileName); title.setText(fileName);
saveButton.setVisibility(View.GONE); saveButton.setVisibility(View.GONE);
changed = false; changed = false;
new Task(() -> FileUtils.writeTextFile(path, fileName, String.valueOf(editor.getText()))).runSync(); new Task(() -> FileUtils.writeTextFile(path, fileName, String.valueOf(editor.getText()))).runSync();
} }
@ -131,10 +133,12 @@ public class CodeEditorActivity extends BaseActivity {
public boolean dispatchKeyEvent(KeyEvent event) { public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_TAB) { if (event.getKeyCode() == KeyEvent.KEYCODE_TAB) {
if (event.getAction() == KeyEvent.ACTION_UP) { if (event.getAction() == KeyEvent.ACTION_UP) {
editor.insert(TAB_CONTENT); editor.insert(TAB);
} }
return true; return true;
} }
return super.dispatchKeyEvent(event); return super.dispatchKeyEvent(event);
} }

View file

@ -55,6 +55,7 @@ public class DrawerFragment extends Fragment implements DrawerLayout.DrawerListe
if (drawerContainer != null) { if (drawerContainer != null) {
drawerContainer.removeDrawerListener(this); drawerContainer.removeDrawerListener(this);
} }
super.onDetach(); super.onDetach();
} }
@ -104,7 +105,7 @@ public class DrawerFragment extends Fragment implements DrawerLayout.DrawerListe
} else if (id == R.id.exit) { } else if (id == R.id.exit) {
requireActivity().finish(); requireActivity().finish();
} else if (id == R.id.lua_script){ } else if (id == R.id.lua_script){
new LuaDialogFragment().show(getParentFragmentManager(),null); new LuaDialogFragment().show(getParentFragmentManager(), null);
} }
return false; return false;

View file

@ -27,7 +27,6 @@ import java.util.ArrayList;
import java.util.UUID; import java.util.UUID;
public class LuaDialogFragment extends BottomDialogFragment { public class LuaDialogFragment extends BottomDialogFragment {
private final SimpleListAdapter<LuaFile> adapter = new SimpleListAdapter<>(R.layout.holder_lua_script, this::onCreateListItem); private final SimpleListAdapter<LuaFile> adapter = new SimpleListAdapter<>(R.layout.holder_lua_script, this::onCreateListItem);
private ActivityResultLauncher<CodeEditorActivity.Arguments> codeEditorLauncher; private ActivityResultLauncher<CodeEditorActivity.Arguments> codeEditorLauncher;
private LuaFile currentEditorFile; private LuaFile currentEditorFile;
@ -47,6 +46,7 @@ public class LuaDialogFragment extends BottomDialogFragment {
openDocumentLauncher = registerForActivityResult(new ActivityResultContracts.OpenDocument(), result -> { openDocumentLauncher = registerForActivityResult(new ActivityResultContracts.OpenDocument(), result -> {
if (result != null) { if (result != null) {
String fileName = FileUtils.getName(result.toString()); String fileName = FileUtils.getName(result.toString());
if (fileName.toLowerCase().endsWith(".lua")) { if (fileName.toLowerCase().endsWith(".lua")) {
new Task(() -> { new Task(() -> {
String content = FileUtils.readTextFile(result.toString()); String content = FileUtils.readTextFile(result.toString());
@ -66,6 +66,7 @@ public class LuaDialogFragment extends BottomDialogFragment {
break; break;
} }
} }
orderByModified(); orderByModified();
}); });
} }
@ -90,6 +91,7 @@ public class LuaDialogFragment extends BottomDialogFragment {
}).setTitle(R.string.create_new) }).setTitle(R.string.create_new)
.show(); .show();
}); });
((RecyclerView) view.findViewById(R.id.recycler)).setAdapter(adapter); ((RecyclerView) view.findViewById(R.id.recycler)).setAdapter(adapter);
((RecyclerView) view.findViewById(R.id.recycler)).setLayoutManager(new AutoFitGridLayout(getContext(), 140)); ((RecyclerView) view.findViewById(R.id.recycler)).setLayoutManager(new AutoFitGridLayout(getContext(), 140));
FileUtils.createDir(FileUtils.getResourcesPath(), "Lua Scripts"); FileUtils.createDir(FileUtils.getResourcesPath(), "Lua Scripts");
@ -117,6 +119,7 @@ public class LuaDialogFragment extends BottomDialogFragment {
adapter.addAll(file); adapter.addAll(file);
orderByModified(); orderByModified();
}); });
return file; return file;
} }
@ -137,6 +140,7 @@ public class LuaDialogFragment extends BottomDialogFragment {
private void loadScript(LuaFile file) { private void loadScript(LuaFile file) {
dismiss(); dismiss();
Toast.makeText(getContext(), String.format(getString(R.string.running_ff), file.name), Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), String.format(getString(R.string.running_ff), file.name), Toast.LENGTH_SHORT).show();
new Task(() -> { new Task(() -> {
String script = FileUtils.readTextFile(file.absolutePath()); String script = FileUtils.readTextFile(file.absolutePath());
@ -148,6 +152,7 @@ public class LuaDialogFragment extends BottomDialogFragment {
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
openDocumentLauncher.unregister(); openDocumentLauncher.unregister();
codeEditorLauncher.unregister(); codeEditorLauncher.unregister();
} }

View file

@ -102,6 +102,7 @@ public class FileUtils {
return true; return true;
} }
public static String readTextFile(String path) { public static String readTextFile(String path) {
if (!exists(path)) { if (!exists(path)) {
return null; return null;
@ -189,16 +190,22 @@ public class FileUtils {
public static void updateFile(String path){ public static void updateFile(String path){
DocumentFile file = parseFile(path); DocumentFile file = parseFile(path);
Uri uri = file.getUri(); Uri uri = file.getUri();
switch (uri.getScheme()){
switch (uri.getScheme()) {
case "file": { case "file": {
new File(uri.getPath()).setLastModified(System.currentTimeMillis()); new File(uri.getPath()).setLastModified(System.currentTimeMillis());
}break; break;
case "content":{ }
getContext().getContentResolver().update(uri, null,null, null);
}break; case "content": {
default:{ getContext().getContentResolver().update(uri, null, null, null);
Log.w(Constants.LOG_TAG, "Cannot update file from scheme: "+uri.getScheme()); break;
}break; }
default: {
Log.w(Constants.LOG_TAG, "Cannot update file from scheme: " + uri.getScheme());
break;
}
} }
} }
@ -209,10 +216,12 @@ public class FileUtils {
public static String[] listFiles(String path){ public static String[] listFiles(String path){
DocumentFile folder = parseFile(path); DocumentFile folder = parseFile(path);
DocumentFile[] files = folder.listFiles(); DocumentFile[] files = folder.listFiles();
String[] result = new String[files.length]; String[] result = new String[files.length];
for (int i = 0; i < result.length; i++){ for (int i = 0; i < result.length; i++){
result[i] = files[i].getName(); result[i] = files[i].getName();
} }
return result; return result;
} }
} }

View file

@ -37,8 +37,8 @@ public class BaseEditor extends BasicTextEditor {
private final char[] textBuffer = new char[1]; private final char[] textBuffer = new char[1];
protected final int[] colors = new int[256]; protected final int[] colors = new int[256];
//512KB OF BUFFER // Allocate 512KB for the buffer
protected final byte[] syntaxBuffer = new byte[1024 * 512]; protected final byte[] syntaxBuffer = new byte[512 * 1024];
private boolean requireUpdate = true; private boolean requireUpdate = true;
public BaseEditor(@NonNull Context context) { public BaseEditor(@NonNull Context context) {
@ -89,6 +89,7 @@ public class BaseEditor extends BasicTextEditor {
} else { } else {
drawSelection(canvas); drawSelection(canvas);
} }
drawText(canvas); drawText(canvas);
drawLineCount(canvas); drawLineCount(canvas);
} catch (Throwable e) { } catch (Throwable e) {
@ -102,6 +103,7 @@ public class BaseEditor extends BasicTextEditor {
paint.setColor(Color.WHITE); paint.setColor(Color.WHITE);
canvas.drawText("Editor draw error:", getPaddingLeft(), getLineHeight(), paint); canvas.drawText("Editor draw error:", getPaddingLeft(), getLineHeight(), paint);
canvas.drawText(String.valueOf(e), getPaddingLeft(), getLineHeight() * 2, paint); canvas.drawText(String.valueOf(e), getPaddingLeft(), getLineHeight() * 2, paint);
int index = 2; int index = 2;
for (StackTraceElement trace : e.getStackTrace()) { for (StackTraceElement trace : e.getStackTrace()) {
index++; index++;
@ -122,7 +124,6 @@ public class BaseEditor extends BasicTextEditor {
{ {
int ascent = (int) Math.abs(fontMetrics.ascent); int ascent = (int) Math.abs(fontMetrics.ascent);
paint.getTextBounds(HELLO_WORLD, 0, HELLO_WORLD.length(), rect); paint.getTextBounds(HELLO_WORLD, 0, HELLO_WORLD.length(), rect);
;
textOffset = Math.max(((lineHeight - rect.height()) / 2), 0) + ascent; textOffset = Math.max(((lineHeight - rect.height()) / 2), 0) + ascent;
} }
@ -173,6 +174,7 @@ public class BaseEditor extends BasicTextEditor {
} else { } else {
paint.setColor(colorDisable); paint.setColor(colorDisable);
} }
float width = paint.measureText(text); float width = paint.measureText(text);
canvas.drawText(text, getPaddingLeft() - width - (spaceWidth * 2.5f), (i * lineHeight) + textOffset, paint); canvas.drawText(text, getPaddingLeft() - width - (spaceWidth * 2.5f), (i * lineHeight) + textOffset, paint);
} }
@ -202,13 +204,15 @@ public class BaseEditor extends BasicTextEditor {
textBuffer[0] = edit.charAt(i); textBuffer[0] = edit.charAt(i);
switch (textBuffer[0]) { switch (textBuffer[0]) {
case '\n': case '\n':
x = 0;
line++; line++;
x = 0;
y = (line * lineHeight) + textOffset; y = (line * lineHeight) + textOffset;
break; break;
case ' ': case ' ':
x += spaceWidth; x += spaceWidth;
break; break;
default: default:
paint.setColor(colors[syntaxBuffer[i - beginIndex]]); paint.setColor(colors[syntaxBuffer[i - beginIndex]]);
canvas.drawText(textBuffer, 0, 1, x, y, paint); canvas.drawText(textBuffer, 0, 1, x, y, paint);
@ -228,7 +232,10 @@ public class BaseEditor extends BasicTextEditor {
float y = (currentLine * lineHeight); float y = (currentLine * lineHeight);
Editable text = getText(); Editable text = getText();
for (int i = start; i < end; i++) { for (int i = start; i < end; i++) {
if (i == position) break; if (i == position) {
break;
}
textBuffer[0] = text.charAt(i); textBuffer[0] = text.charAt(i);
x += paint.measureText(textBuffer, 0, 1); x += paint.measureText(textBuffer, 0, 1);
} }
@ -309,7 +316,7 @@ public class BaseEditor extends BasicTextEditor {
@Override @Override
protected void onTextChanged() { protected void onTextChanged() {
super.onTextChanged();
requireUpdate = true; requireUpdate = true;
super.onTextChanged();
} }
} }

View file

@ -52,7 +52,6 @@ public class BasicTextEditor extends AppCompatEditText {
setLineSpacing(0, 1.3f); setLineSpacing(0, 1.3f);
setScroller(new Scroller(getContext())); setScroller(new Scroller(getContext()));
setInputType(InputType.TYPE_CLASS_TEXT | setInputType(InputType.TYPE_CLASS_TEXT |
InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS |
InputType.TYPE_TEXT_FLAG_IME_MULTI_LINE | InputType.TYPE_TEXT_FLAG_IME_MULTI_LINE |
@ -70,14 +69,12 @@ public class BasicTextEditor extends AppCompatEditText {
addTextChangedListener((SimpleTextWatcher) value -> BasicTextEditor.this.onTextChanged()); addTextChangedListener((SimpleTextWatcher) value -> BasicTextEditor.this.onTextChanged());
} }
// DISABLE ANDROID DEFAULT SCROLL // Disable default Android scroll
@Override @Override
public void scrollBy(int x, int y) { public void scrollBy(int x, int y) {}
}
@Override @Override
public void scrollTo(int x, int y) { public void scrollTo(int x, int y) {}
}
public void setScroll(int x, int y) { public void setScroll(int x, int y) {
x = Math.max(0, x); x = Math.max(0, x);
@ -100,8 +97,7 @@ public class BasicTextEditor extends AppCompatEditText {
setScroll(getScrollX(), getScrollY()); setScroll(getScrollX(), getScrollY());
} }
protected void onTextChanged() { protected void onTextChanged() {}
}
private boolean onSuperTouchListener(MotionEvent event) { private boolean onSuperTouchListener(MotionEvent event) {
return super.onTouchEvent(event); return super.onTouchEvent(event);

View file

@ -41,6 +41,7 @@ public class CodeEditor extends BaseEditor {
@Override @Override
protected void onRefreshColorScheme(byte[] buffer, int index, int length) { protected void onRefreshColorScheme(byte[] buffer, int index, int length) {
super.onRefreshColorScheme(buffer, index, length); super.onRefreshColorScheme(buffer, index, length);
if (syntax != null) { if (syntax != null) {
final CharSequence text = getText().subSequence(index, index + length); final CharSequence text = getText().subSequence(index, index + length);
syntax.apply(syntaxBuffer, text); syntax.apply(syntaxBuffer, text);

View file

@ -3,11 +3,14 @@ package com.panda3ds.pandroid.view.code.syntax;
public abstract class CodeSyntax { public abstract class CodeSyntax {
public abstract void apply(byte[] syntaxBuffer, final CharSequence text); public abstract void apply(byte[] syntaxBuffer, final CharSequence text);
public static CodeSyntax obtainByFileName(String name) { // Get syntax highlighting data for a file based on its filename, by looking at the extension
public static CodeSyntax getFromFilename(String name) {
name = name.trim().toLowerCase(); name = name.trim().toLowerCase();
String[] parts = name.split("\\."); String[] parts = name.split("\\.");
if (parts.length == 0) if (parts.length == 0)
return null; return null;
// Get syntax based on file extension
switch (parts[parts.length - 1]) { switch (parts[parts.length - 1]) {
case "lua": case "lua":
return new LuaSyntax(); return new LuaSyntax();

View file

@ -29,7 +29,6 @@ class LuaSyntax extends CodeSyntax {
public static final Pattern symbols = Pattern.compile("([.!&?:;*+/{}()\\]\\[,=-])"); public static final Pattern symbols = Pattern.compile("([.!&?:;*+/{}()\\]\\[,=-])");
public static final Pattern numbers = Pattern.compile("\\b((\\d*[.]?\\d+([Ee][+-]?[\\d]+)?[LlfFdD]?)|(0[xX][0-9a-zA-Z]+)|(0[bB][0-1]+)|(0[0-7]+))\\b"); public static final Pattern numbers = Pattern.compile("\\b((\\d*[.]?\\d+([Ee][+-]?[\\d]+)?[LlfFdD]?)|(0[xX][0-9a-zA-Z]+)|(0[bB][0-1]+)|(0[0-7]+))\\b");
@Override @Override
public void apply(byte[] syntaxBuffer, CharSequence text) { public void apply(byte[] syntaxBuffer, CharSequence text) {
for (Matcher matcher = keywords.matcher(text); matcher.find(); ) { for (Matcher matcher = keywords.matcher(text); matcher.find(); ) {

View file

@ -14,6 +14,7 @@ public final class AutoFitGridLayout extends GridLayoutManager {
public AutoFitGridLayout(Context context, int iconSize) { public AutoFitGridLayout(Context context, int iconSize) {
super(context, 1); super(context, 1);
this.iconSize = iconSize; this.iconSize = iconSize;
this.context = context; this.context = context;
} }
@ -24,7 +25,9 @@ public final class AutoFitGridLayout extends GridLayoutManager {
int width = View.MeasureSpec.getSize(widthSpec); int width = View.MeasureSpec.getSize(widthSpec);
int iconSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this.iconSize, context.getResources().getDisplayMetrics()); int iconSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this.iconSize, context.getResources().getDisplayMetrics());
int iconCount = Math.max(1, width / iconSize); int iconCount = Math.max(1, width / iconSize);
if (getSpanCount() != iconCount)
if (getSpanCount() != iconCount) {
setSpanCount(iconCount); setSpanCount(iconCount);
}
} }
} }

View file

@ -14,7 +14,6 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
public class SimpleListAdapter<T> extends RecyclerView.Adapter<SimpleListAdapter.Holder> { public class SimpleListAdapter<T> extends RecyclerView.Adapter<SimpleListAdapter.Holder> {
private final ArrayList<T> list = new ArrayList<>(); private final ArrayList<T> list = new ArrayList<>();
private final Binder<T> binder; private final Binder<T> binder;
private final int layoutId; private final int layoutId;