update dynamic layout inflater to latest version; add some ui samples
This commit is contained in:
@@ -100,6 +100,23 @@ module.exports = function(__runtime__, scope){
|
||||
});
|
||||
}
|
||||
|
||||
function getColorDetector(color, algorithm, threshold){
|
||||
switch(algorithm){
|
||||
case "rgb":
|
||||
return new com.stardust.autojs.core.image.ColorDetector.RGBDistanceDetector(color, threshold);
|
||||
case "equal":
|
||||
return new com.stardust.autojs.core.image.ColorDetector.EqualityDetector(color);
|
||||
case "diff":
|
||||
return new com.stardust.autojs.core.image.ColorDetector.DifferenceDetector(color, threshold);
|
||||
case "rgb+":
|
||||
return new com.stardust.autojs.core.image.ColorDetector.WeightedRGBDistanceDetector(color, threshold);
|
||||
case "hs":
|
||||
return new com.stardust.autojs.core.image.ColorDetector.HSDistanceDetector(color, threshold);
|
||||
}
|
||||
throw new Error("Unknown algorithm: " + algorithm);
|
||||
}
|
||||
|
||||
|
||||
function toPointArray(points){
|
||||
var arr = [];
|
||||
for(var i = 0; i < points.length; i++){
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
package com.stardust.autojs.core.image;
|
||||
|
||||
import android.graphics.Color;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/20.
|
||||
*/
|
||||
|
||||
public interface ColorDetector {
|
||||
|
||||
boolean detectsColor(int red, int green, int blue);
|
||||
|
||||
abstract class AbstractColorDetector implements ColorDetector {
|
||||
|
||||
protected final int mColor;
|
||||
protected final int mR, mG, mB;
|
||||
|
||||
public AbstractColorDetector(int color) {
|
||||
mColor = color;
|
||||
mR = Color.red(color);
|
||||
mG = Color.green(color);
|
||||
mB = Color.blue(color);
|
||||
}
|
||||
}
|
||||
|
||||
class EqualityDetector extends AbstractColorDetector {
|
||||
|
||||
|
||||
public EqualityDetector(int color) {
|
||||
super(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean detectsColor(int red, int green, int blue) {
|
||||
return mR == red && mG == green && mB == blue;
|
||||
}
|
||||
}
|
||||
|
||||
class DifferenceDetector extends AbstractColorDetector {
|
||||
|
||||
private final int mThreshold;
|
||||
|
||||
public DifferenceDetector(int color, int threshold) {
|
||||
super(color);
|
||||
mThreshold = threshold * 3;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean detectsColor(int R, int G, int B) {
|
||||
return Math.abs(R - mR) + Math.abs(G - mG) + Math.abs(B - mB) <= mThreshold;
|
||||
}
|
||||
}
|
||||
|
||||
class RDistanceDetector extends AbstractColorDetector {
|
||||
|
||||
private final int mThreshold;
|
||||
|
||||
public RDistanceDetector(int color, int threshold) {
|
||||
super(color);
|
||||
mThreshold = threshold;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean detectsColor(int R, int G, int B) {
|
||||
return Math.abs(mR - R) <= mThreshold;
|
||||
}
|
||||
}
|
||||
|
||||
class RGBDistanceDetector extends AbstractColorDetector {
|
||||
|
||||
private final int mThreshold;
|
||||
|
||||
public RGBDistanceDetector(int color, int threshold) {
|
||||
super(color);
|
||||
mThreshold = threshold * threshold * 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean detectsColor(int R, int G, int B) {
|
||||
int dR = R - mR;
|
||||
int dG = G - mG;
|
||||
int dB = B - mB;
|
||||
int d = dR * dR + dG * dG + dB * dB;
|
||||
return d <= mThreshold;
|
||||
}
|
||||
}
|
||||
|
||||
class WeightedRGBDistanceDetector extends AbstractColorDetector {
|
||||
|
||||
private final int mThreshold;
|
||||
private final int mR, mG, mB;
|
||||
|
||||
public WeightedRGBDistanceDetector(int color, int threshold) {
|
||||
super(color);
|
||||
mR = (color & 0xff0000) >> 16;
|
||||
mG = (color & 0x00ff00) >> 8;
|
||||
mB = color & 0xff;
|
||||
mThreshold = threshold * threshold * 8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean detectsColor(int R, int G, int B) {
|
||||
int dR = R - mR;
|
||||
int dG = G - mG;
|
||||
int dB = B - mB;
|
||||
double meanR = (mR + R) / 2;
|
||||
double weightR = 2 + meanR / 256;
|
||||
double weightG = 4.0;
|
||||
double weightB = 2 + (255 - meanR) / 256;
|
||||
return weightR * dR * dR + weightG * dG * dG + weightB * dB * dB <= mThreshold;
|
||||
}
|
||||
}
|
||||
|
||||
class HDistanceDetector extends AbstractColorDetector {
|
||||
|
||||
private final int mH;
|
||||
private final int mThreshold;
|
||||
|
||||
public HDistanceDetector(int color, int threshold) {
|
||||
super(color);
|
||||
mH = getH(mR, mG, mB);
|
||||
mThreshold = threshold;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean detectsColor(int R, int G, int B) {
|
||||
return Math.abs(mH - getH(R, G, B)) <= mThreshold;
|
||||
}
|
||||
|
||||
private static int getH(int R, int G, int B) {
|
||||
int max, min, H;
|
||||
if (R > G) {
|
||||
min = Math.min(G, B);
|
||||
max = Math.max(R, B);
|
||||
} else {
|
||||
min = Math.min(R, B);
|
||||
max = Math.max(G, B);
|
||||
}
|
||||
if (R == max) {
|
||||
H = (G - B) / (max - min) * 60;
|
||||
} else if (G == max) {
|
||||
H = 120 + (B - R) / (max - min) * 60;
|
||||
} else {
|
||||
H = 240 + (R - G) / (max - min) * 60;
|
||||
}
|
||||
if (H < 0) H = H + 360;
|
||||
return H;
|
||||
}
|
||||
}
|
||||
|
||||
class HSDistanceDetector extends AbstractColorDetector {
|
||||
|
||||
private final int mH, mS;
|
||||
private final int mThreshold;
|
||||
|
||||
public HSDistanceDetector(int color, int threshold) {
|
||||
super(color);
|
||||
long HS = getHS(mR, mG, mB);
|
||||
mH = (int) (HS & 0xffffffffL);
|
||||
mS = (int) ((HS >> 32) & 0xffffffffL);
|
||||
mThreshold = threshold * 3729600 / 255;
|
||||
}
|
||||
|
||||
public HSDistanceDetector(int color, float similarity) {
|
||||
this(color, (int) (1.0f - similarity) * 255);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean detectsColor(int R, int G, int B) {
|
||||
long hs = getHS(R, G, B);
|
||||
int dH = (int) (hs & 0xffffffffL) - mH;
|
||||
int dS = (int) ((hs >> 32) & 0xffffffffL) - mS;
|
||||
return dH * dH + dS * dS <= mThreshold;
|
||||
}
|
||||
|
||||
private static long getHS(int R, int G, int B) {
|
||||
int max, min, H;
|
||||
if (R > G) {
|
||||
min = Math.min(G, B);
|
||||
max = Math.max(R, B);
|
||||
} else {
|
||||
min = Math.min(R, B);
|
||||
max = Math.max(G, B);
|
||||
}
|
||||
if (R == max) {
|
||||
H = (G - B) / (max - min) * 60;
|
||||
} else if (G == max) {
|
||||
H = 120 + (B - R) / (max - min) * 60;
|
||||
} else {
|
||||
H = 240 + (R - G) / (max - min) * 60;
|
||||
}
|
||||
if (H < 0) H = H + 360;
|
||||
int S = (max - min) * 100 / max;
|
||||
return H & ((long) S << 32);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,12 +6,12 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.nickandjerry.dynamiclayoutinflator.lib.DynamicLayoutInflater;
|
||||
import com.nickandjerry.dynamiclayoutinflator.lib.util.Drawables;
|
||||
import com.stardust.autojs.core.ui.widget.JsFrameLayout;
|
||||
import com.stardust.autojs.core.ui.xml.XmlConverter;
|
||||
import com.stardust.util.MapEntries;
|
||||
|
||||
import org.autojs.dynamiclayoutinflater.DynamicLayoutInflater;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
@@ -7,7 +7,7 @@ import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.nickandjerry.dynamiclayoutinflator.lib.util.Ids;
|
||||
import org.autojs.dynamiclayoutinflater.util.Ids;
|
||||
|
||||
|
||||
/**
|
||||
@@ -18,7 +18,7 @@ public class JsViewHelper {
|
||||
|
||||
@Nullable
|
||||
public static View findViewByStringId(View view, String id) {
|
||||
View result = view.findViewById(Ids.getIdFromName(id));
|
||||
View result = view.findViewById(Ids.parse(id));
|
||||
if (result != null)
|
||||
return result;
|
||||
if (!(view instanceof ViewGroup)) {
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
package com.stardust.autojs.core.ui.widget;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.Button;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/15.
|
||||
*/
|
||||
|
||||
public class JsButton extends android.support.v7.widget.AppCompatButton {
|
||||
@SuppressLint("AppCompatCustomView")
|
||||
public class JsButton extends Button {
|
||||
public JsButton(Context context) {
|
||||
super(context);
|
||||
}
|
||||
@@ -20,6 +23,10 @@ public class JsButton extends android.support.v7.widget.AppCompatButton {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public JsButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
public String text() {
|
||||
return getText().toString();
|
||||
}
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
package com.stardust.autojs.core.ui.widget;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.EditText;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/15.
|
||||
*/
|
||||
|
||||
public class JsEditText extends android.support.v7.widget.AppCompatEditText {
|
||||
@SuppressLint("AppCompatCustomView")
|
||||
public class JsEditText extends EditText {
|
||||
public JsEditText(Context context) {
|
||||
super(context);
|
||||
}
|
||||
@@ -18,6 +23,12 @@ public class JsEditText extends android.support.v7.widget.AppCompatEditText {
|
||||
|
||||
public JsEditText(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public JsEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
public String text() {
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
package com.stardust.autojs.core.ui.widget;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/5/15.
|
||||
*/
|
||||
|
||||
public class JsTextView extends android.support.v7.widget.AppCompatTextView {
|
||||
@SuppressLint("AppCompatCustomView")
|
||||
public class JsTextView extends TextView {
|
||||
public JsTextView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
@@ -21,6 +26,11 @@ public class JsTextView extends android.support.v7.widget.AppCompatTextView {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public JsTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
public String text() {
|
||||
return getText().toString();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.stardust.autojs.core.ui.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.util.AttributeSet;
|
||||
import android.webkit.WebChromeClient;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/11/29.
|
||||
*/
|
||||
|
||||
public class JsWebView extends WebView {
|
||||
|
||||
public JsWebView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public JsWebView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public JsWebView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public JsWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
WebSettings settings = getSettings();
|
||||
settings.setUseWideViewPort(true);
|
||||
settings.setBuiltInZoomControls(true);
|
||||
settings.setLoadWithOverviewMode(true);
|
||||
settings.setJavaScriptEnabled(true);
|
||||
settings.setJavaScriptCanOpenWindowsAutomatically(true);
|
||||
settings.setDomStorageEnabled(true);
|
||||
settings.setDisplayZoomControls(false);
|
||||
setWebViewClient(new WebViewClient());
|
||||
setWebChromeClient(new WebChromeClient());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +1,22 @@
|
||||
package com.stardust.autojs.core.ui.xml;
|
||||
|
||||
import android.webkit.WebView;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.DatePicker;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TimePicker;
|
||||
|
||||
import com.stardust.autojs.core.ui.widget.JsButton;
|
||||
import com.stardust.autojs.core.ui.widget.JsEditText;
|
||||
import com.stardust.autojs.core.ui.widget.JsFrameLayout;
|
||||
import com.stardust.autojs.core.ui.widget.JsLinearLayout;
|
||||
import com.stardust.autojs.core.ui.widget.JsRelativeLayout;
|
||||
import com.stardust.autojs.core.ui.widget.JsTextView;
|
||||
import com.stardust.autojs.core.ui.widget.JsWebView;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
@@ -16,6 +27,7 @@ import org.xml.sax.SAXException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
@@ -32,11 +44,21 @@ public class XmlConverter {
|
||||
.defaultHandler(new NodeHandler.MapNameHandler()
|
||||
.map("frame", JsFrameLayout.class.getName())
|
||||
.map("linear", JsLinearLayout.class.getName())
|
||||
.map("horizontal", JsLinearLayout.class.getName())
|
||||
.map("relative", JsRelativeLayout.class.getName())
|
||||
.map("button", JsButton.class.getName())
|
||||
.map("text", JsTextView.class.getName())
|
||||
.map("input", JsEditText.class.getName())
|
||||
.map("img", "ImageView")
|
||||
.map("datepicker", DatePicker.class.getName())
|
||||
.map("timepicker", TimePicker.class.getName())
|
||||
.map("webview", JsWebView.class.getName())
|
||||
.map("progressbar", ProgressBar.class.getName())
|
||||
.map("seekbar", SeekBar.class.getName())
|
||||
.map("spinner", Spinner.class.getName())
|
||||
.map("radio", RadioButton.class.getName())
|
||||
.map("radiogroup", RadioGroup.class.getName())
|
||||
.map("checkbox", CheckBox.class.getName())
|
||||
);
|
||||
|
||||
private static final AttributeHandler ATTRIBUTE_HANDLER = new AttributeHandler.AttrNameRouter()
|
||||
|
||||
@@ -14,8 +14,6 @@ import android.view.Display;
|
||||
import android.view.Surface;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.nickandjerry.dynamiclayoutinflator.lib.ImageLoader;
|
||||
import com.nickandjerry.dynamiclayoutinflator.lib.util.Drawables;
|
||||
import com.stardust.autojs.annotation.ScriptVariable;
|
||||
import com.stardust.autojs.core.image.ColorFinder;
|
||||
import com.stardust.autojs.core.image.ImageWrapper;
|
||||
|
||||
Reference in New Issue
Block a user