Fixed some bugs

Implement some base classes for XMLLayoutInflater
This commit is contained in:
Akash Yadav
2021-11-02 15:59:20 +05:30
parent 9df38ac9c4
commit 4c2855800f
19 changed files with 373 additions and 27 deletions
@@ -184,7 +184,7 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F
loadFragment(mFileTreeFragment);
symbolInput = new SymbolInputView(this);
mBinding.inputContainer.addView(symbolInput, 1, new ViewGroup.LayoutParams(-1, -2));
mBinding.inputContainer.addView(symbolInput, 0, new ViewGroup.LayoutParams(-1, -2));
mBinding.editorViewPager.setOffscreenPageLimit(9);
mBinding.editorViewPager.setAdapter(mPagerAdapter);
@@ -233,6 +233,26 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F
}
}
@Override
protected void onPause() {
new Thread(() -> {
boolean saved = false;
try {
saveAll();
saved = true;
} catch (Throwable th) {
LOG.error(":onPause(): Failed to save files", th);
saved = false;
}
if(!saved) {
getApp().toast(R.string.msg_failed_save, Toaster.Type.ERROR);
}
}, "AndroidIDE FileSaver").start();
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
@@ -96,7 +96,9 @@ public class EditorPagerAdapter extends FragmentStatePagerAdapter implements Edi
public void save(int index, SaveResult result) {
if (index >= 0 && index < mFragments.size()) {
EditorFragment frag = getFrag(index);
if (frag == null || frag.getFile() == null) {
return;
}
/**
* Must be called before frag.save()
* Otherwise, it'll always return false
@@ -140,6 +140,8 @@ public class EditorFragment extends BaseFragment implements EditorEventListener
mBinding.editor.setLineColorsEnabled(true);
mBinding.editor.setDividerWidth(SizeUtils.dp2px(1));
mBinding.diagnosticTextContainer.setVisibility(View.GONE);
configureEditorIfNeeded();
final Range range = fromArgs(getArguments());
@@ -1,6 +1,7 @@
package com.itsaky.androidide.handlers;
import android.view.View;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.itsaky.androidide.R;
import com.itsaky.androidide.managers.PreferenceManager;
import com.itsaky.androidide.models.AndroidProject;
@@ -12,12 +13,11 @@ import com.itsaky.androidide.tasks.gradle.build.ApkGeneratingTask;
import com.itsaky.androidide.utils.Environment;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.Collection;
public class BuildServiceHandler extends IDEHandler implements IDEService.BuildListener {
@@ -182,6 +182,7 @@ public abstract class IDELanguageClientImpl implements IDELanguageClient {
final FragmentEditorBinding binding = frag.getBinding();
binding.diagnosticTextContainer.setVisibility(View.VISIBLE);
binding.diagnosticText.setVisibility(View.VISIBLE);
binding.diagnosticText.setClickable(false);
binding.diagnosticText.setText(diagnostic.getMessage());
@@ -221,12 +222,6 @@ public abstract class IDELanguageClientImpl implements IDELanguageClient {
return;
}
TransitionSet set = new TransitionSet();
set.addTransition(new ChangeBounds());
set.addTransition(new Fade());
set.setDuration(DIAGNOSTIC_TRANSITION_DURATION);
TransitionManager.beginDelayedTransition(activity().getBinding().getRoot(), set);
activity().getDiagnosticBinding().getRoot().setVisibility(View.GONE);
}
@@ -241,6 +236,7 @@ public abstract class IDELanguageClientImpl implements IDELanguageClient {
}
frag.getBinding().diagnosticTextContainer.setVisibility(View.GONE);
frag.getBinding().diagnosticText.setVisibility(View.GONE);
frag.getBinding().diagnosticText.setClickable(false);
}
@@ -113,7 +113,8 @@ public class ShellServer extends Thread {
try {
this.process.getOutputStream().write(str.concat("\n").getBytes());
this.process.getOutputStream().flush();
} catch (IOException e) {
} catch (Throwable e) {
// Ignored
}
}
@@ -0,0 +1,22 @@
package com.itsaky.androidide.ui.inflater;
import java.io.File;
import java.util.Set;
/**
* A layout inflater which inflates layout from a raw XML file
*
* @author Akash Yadav
*/
public abstract class ILayoutInflater {
/**
* Creates an instance of {@code ILayoutInflater}
*
* @param config The configuration of the LayoutInflater
* @return A new layout inflater instance
*/
public static ILayoutInflater newInstance (LayoutInflaterConfiguration config) {
return new XMLLayoutInflater (config);
}
}
@@ -0,0 +1,15 @@
package com.itsaky.androidide.ui.inflater;
import java.io.File;
import java.util.Set;
public class LayoutInflaterConfiguration {
private final Set<File> resDirs;
public LayoutInflaterConfiguration(Set<File> resDirs) {
this.resDirs = resDirs;
}
}
@@ -0,0 +1,10 @@
package com.itsaky.androidide.ui.inflater;
class XMLLayoutInflater extends ILayoutInflater {
final LayoutInflaterConfiguration config;
XMLLayoutInflater(LayoutInflaterConfiguration config) {
this.config = config;
}
}
@@ -0,0 +1,122 @@
package com.itsaky.androidide.ui.view;
/**
* Value type of {@link IAttribute}
*
* @author Akash Yadav
*/
public enum AttrType {
/**
* Refers to another resource
*/
REFERENCE ("reference"),
/**
* Color value
*/
COLOR ("color"),
/**
* Either {@code true} or {@code false}
*/
BOOLEAN ("boolean"),
/**
* A dimension like 10dp, 14sp etc.
*/
DIMENSION ("dimension"),
/**
* A floating point number. E.g.: 1.9, 123.45
*/
FLOAT ("float"),
/**
* An integer value
*/
INTEGER ("integer"),
/**
* A string value
*/
STRING ("string"),
/**
* A fraction
*/
FRACTION ("fraction"),
/**
* A enum value. Unlike {@link #FLAG}, an attribute can have only one of this.
*/
ENUM ("enum"),
/**
* A flag value. May contain on or more values
*/
FLAG ("flag"),
/**
* An unknown value. The layout inflater does not consider this
*/
UNKNOWN ("");
private final String format;
public static final String FORMAT_REF = REFERENCE.getFormat();
public static final String FORMAT_COLOR = COLOR.getFormat();
public static final String FORMAT_BOOL = BOOLEAN.getFormat();
public static final String FORMAT_DIMEN = DIMENSION.getFormat();
public static final String FORMAT_FLOAT = FLOAT.getFormat();
public static final String FORMAT_INT = INTEGER.getFormat();
public static final String FORMAT_STRING = STRING.getFormat();
public static final String FORMAT_FRACTION = FRACTION.getFormat();
public static final String FORMAT_ENUM = ENUM.getFormat();
public static final String FORMAT_FLAG = FLAG.getFormat();
private AttrType(String format) {
this.format = format;
}
public String getFormat () {
return this.format;
}
public boolean hasFixedValues () {
return this == AttrType.ENUM
|| this == AttrType.FLAG;
}
/**
* Get the attribute type from format
*
* @param format Format, as declared in styleables.
* @return The Attribute type
*/
public static AttrType fromFormat (String format) {
if (FORMAT_REF.equals(format)) {
return AttrType.REFERENCE;
} else if (FORMAT_COLOR.equals(format)) {
return AttrType.COLOR;
} else if (FORMAT_BOOL.equals(format)) {
return AttrType.BOOLEAN;
} else if (FORMAT_DIMEN.equals(format)) {
return AttrType.DIMENSION;
} else if (FORMAT_FLOAT.equals(format)) {
return AttrType.FLOAT;
} else if (FORMAT_INT.equals(format)) {
return AttrType.INTEGER;
} else if (FORMAT_STRING.equals(format)) {
return AttrType.STRING;
} else if (FORMAT_FRACTION.equals(format)) {
return AttrType.FRACTION;
} else if (FORMAT_ENUM.equals(format)) {
return AttrType.ENUM;
} else if (FORMAT_FLAG.equals(format)) {
return AttrType.FLAG;
}
return AttrType.UNKNOWN;
}
}
@@ -0,0 +1,64 @@
package com.itsaky.androidide.ui.view;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.Set;
/**
* Attribute that can be applied to a {@link IView}
*
* @author Akash Yadav
*/
public interface IAttribute {
/**
* Set namespace of this attribute
*/
void setNamespace (String namespace);
/**
* @see setNamespace(String)
*/
@NonNull
String getNamespace ();
/**
* Set name of this attribute
*/
void setAtrributeName (String name);
/**
* @see setAtrributeName(String)
*/
@NonNull
String getAttributeName ();
/**
* Set current value of this attribute
*/
void setValue (String name);
/**
* @see setValue(String)
*/
@Nullable
String getValue ();
/**
* Set applicable values of this attribute
* Empty by default
*/
void setApplicableValues(Set<String> name);
/**
* @see setAtrributeName(String)
*/
@NonNull
String getApplicableValues ();
/**
* Get the value type of this attribute
*/
@NonNull
AttrType getType ();
}
@@ -0,0 +1,39 @@
package com.itsaky.androidide.ui.view;
import android.view.View;
/**
* Represents a view in the UI Designer
*
* @author Akash Yadav
*/
public interface IView {
/**
* Get this view as android {@link View}. This will be used to display this view in the designer
*
* @return {@link View} of this object. Maybe {@code null}
*/
View asView();
/**
* Add this attribute to this view
*
* @param attr The Attribute to add
*/
void addAttribute (IAttribute attr);
/**
* Remove this attribute
*
* @param attr The Attribute to remove
*/
void removeAttribute (IAttribute attr);
/**
* Remove attribute at index
*
* @param index Index of the attribute to remove
*/
void removeAttributeAt (int index);
}
@@ -0,0 +1,39 @@
package com.itsaky.androidide.ui.view;
/**
* Represents a {@link android.view.ViewGroup}
*
* @author Akash Yadav
*/
public interface IViewGroup extends IView {
/**
* Add this view to this group
*
* @param view The view to add
*/
void addView (IView view);
/**
* Add this view to this group
*
* @param view The view to add
* @param index Add this view to this index
*/
void addView (IView view, int index);
/**
* Get the number of child views this layout contains
*
* @return The child count
*/
int getChildCount();
/**
* Get child at the provided index
*
* @param index The index of child
* @throws IndexOutOfBoundsException If there is no child at the given index
*/
IView getChildAt (int index);
}
@@ -70,6 +70,8 @@ public class Toaster {
}
public void show() {
// Always run on UI Thread
ThreadUtils.runOnUiThread(() -> {
showInternal();
});
@@ -15,11 +15,10 @@
*/
package io.github.rosemoe.editor.text;
import java.util.ArrayList;
import java.util.List;
import io.github.rosemoe.editor.struct.Span;
import io.github.rosemoe.editor.widget.EditorColorScheme;
import java.util.ArrayList;
import java.util.List;
/**
* Update spans on text change event
@@ -29,6 +28,11 @@ import io.github.rosemoe.editor.widget.EditorColorScheme;
public class SpanMapUpdater {
public static void shiftSpansOnMultiLineDelete(List<List<Span>> map, int startLine, int startColumn, int endLine, int endColumn) {
if (map == null || map.isEmpty()) {
return;
}
int lineCount = endLine - startLine - 1;
// Remove unrelated lines
while (lineCount > 0) {
@@ -36,7 +40,7 @@ public class SpanMapUpdater {
lineCount--;
}
// Clean up start line
List<Span> startLineSpans = map.get(startLine);
List<Span> startLineSpans = emptyIfNull(map.get(startLine));
int index = startLineSpans.size() - 1;
while (index > 0) {
if (startLineSpans.get(index).column >= startColumn) {
@@ -47,7 +51,7 @@ public class SpanMapUpdater {
}
}
// Shift end line
List<Span> endLineSpans = map.get(startLine + 1);
List<Span> endLineSpans = emptyIfNull(map.get(startLine + 1));
while (endLineSpans.size() > 1) {
Span first = endLineSpans.get(0);
if (first.column >= endColumn) {
@@ -76,7 +80,7 @@ public class SpanMapUpdater {
if (map == null || map.isEmpty()) {
return;
}
List<Span> spanList = map.get(line);
List<Span> spanList = emptyIfNull(map.get(line));
int startIndex = findSpanIndexFor(spanList, 0, startCol);
if (startIndex == -1) {
//No span is to be updated
@@ -114,7 +118,7 @@ public class SpanMapUpdater {
if (map == null || map.isEmpty()) {
return;
}
List<Span> spanList = map.get(line);
List<Span> spanList = emptyIfNull( map.get(line));
int index = findSpanIndexFor(spanList, 0, startCol);
if (index == -1) {
return;
@@ -138,7 +142,7 @@ public class SpanMapUpdater {
public static void shiftSpansOnMultiLineInsert(List<List<Span>> map, int startLine, int startColumn, int endLine, int endColumn) {
// Find extended span
List<Span> startLineSpans = map.get(startLine);
List<Span> startLineSpans = emptyIfNull( map.get(startLine));
int extendedSpanIndex = findSpanIndexFor(startLineSpans, 0, startColumn);
if (extendedSpanIndex == -1) {
extendedSpanIndex = startLineSpans.size() - 1;
@@ -159,7 +163,7 @@ public class SpanMapUpdater {
map.add(startLine + 1, list);
}
// Add original spans to new line
List<Span> endLineSpans = map.get(endLine);
List<Span> endLineSpans = emptyIfNull(map.get(endLine));
if (endColumn == 0 && extendedSpanIndex + 1 < startLineSpans.size()) {
endLineSpans.clear();
}
@@ -174,6 +178,7 @@ public class SpanMapUpdater {
}
private static int findSpanIndexFor(List<Span> spans, int initialPosition, int targetCol) {
spans = emptyIfNull(spans);
for (int i = initialPosition; i < spans.size(); i++) {
if (spans.get(i).column >= targetCol) {
return i;
@@ -181,5 +186,13 @@ public class SpanMapUpdater {
}
return -1;
}
private static <T> List<T> emptyIfNull (List<T> original) {
if (original == null) {
original = new ArrayList<T>();
}
return original;
}
}
+1 -1
View File
@@ -258,7 +258,7 @@
<string name="label_splash_image">Splash image</string>
<string name="msg_checking_storage_permissions">Checking storage permissions</string>
<string name="msg_failed_list_files">Failed to list project files!</string>
<string name="msg_failed_save">Failed to save some files!</string>
<string name="msg_failed_save">Failed to save files!</string>
<string name="msg_service_started">Service Started</string>
<string name="msg_starting_completion">Starting services</string>
<string name="msg_starting_completion_failed">Failed to start Completion Services</string>
+1 -1
View File
@@ -11,7 +11,7 @@ buildscript {
javaSourceVersion = JavaVersion.VERSION_1_8
javaTargetVersion = JavaVersion.VERSION_1_8
stringfogEnabled = false
stringfogEnabled = true
}
repositories {
@@ -47,7 +47,7 @@ public class TreeNode {
}
public TreeNode(File value) {
children = new ArrayList<>();
children = Collections.synchronizedList(new ArrayList<TreeNode>());
mValue = value;
}
@@ -93,7 +93,7 @@ public class TreeNode {
}
public List<TreeNode> getChildren() {
return children == null ? new ArrayList<TreeNode>() : children;
return children == null ? Collections.synchronizedList(new ArrayList<TreeNode>()) : children;
}
public int size() {
@@ -223,10 +223,9 @@ public class AndroidTreeView {
node.setExpanded(true);
final TreeNode.BaseNodeViewHolder parentViewHolder = getViewHolderForNode(node);
parentViewHolder.getNodeItemsView().removeAllViews();
parentViewHolder.toggle(true);
final Iterator<TreeNode> nodes = node.getChildren().iterator();
while (nodes.hasNext()) {
final TreeNode n = nodes.next();