mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
Fixed some bugs
Implement some base classes for XMLLayoutInflater
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user