6.7.0 - Alpha23 - Fine tuning
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$data": {
|
"$data": {
|
||||||
"v6.7.0": {
|
"v6.7.0": {
|
||||||
"released_date": "2026/02/23",
|
"released_date": "2026/03/07",
|
||||||
"feature": [
|
"feature": [
|
||||||
"插件中心功能, 支持插件的安装/卸载/更新等操作 (入口: 主页抽屉按钮/主页标签页)",
|
"插件中心功能, 支持插件的安装/卸载/更新等操作 (入口: 主页抽屉按钮/主页标签页)",
|
||||||
"版本历史功能, 支持查看/恢复可编辑文件的历史版本 (入口: 主页抽屉按钮/文件管理器菜单/代码编辑器菜单)",
|
"版本历史功能, 支持查看/恢复可编辑文件的历史版本 (入口: 主页抽屉按钮/文件管理器菜单/代码编辑器菜单)",
|
||||||
@@ -150,6 +150,8 @@
|
|||||||
"代码编辑器 \"查找/替换\" 支持状态持久化及实时显示搜索计数信息",
|
"代码编辑器 \"查找/替换\" 支持状态持久化及实时显示搜索计数信息",
|
||||||
"代码编辑器提示保存时确保保存成功后再退出编辑器以降低保存失败率",
|
"代码编辑器提示保存时确保保存成功后再退出编辑器以降低保存失败率",
|
||||||
"代码编辑器保存按钮的状态更符合用户主观逻辑",
|
"代码编辑器保存按钮的状态更符合用户主观逻辑",
|
||||||
|
"打包应用打包过程对话框增加 \"中止\" 按钮",
|
||||||
|
"打包应用打包过程对话框的显示方式并增加耗时统计",
|
||||||
"打包应用页面默认勾选必要权限 (WAKE_LOCK/INTERNET/WRITE_EXTERNAL_STORAGE) _[`issue #397`](http://issues.autojs6.com/397)_",
|
"打包应用页面默认勾选必要权限 (WAKE_LOCK/INTERNET/WRITE_EXTERNAL_STORAGE) _[`issue #397`](http://issues.autojs6.com/397)_",
|
||||||
"打包应用设置页面增加前台服务开关 _[`issue #406`](http://issues.autojs6.com/406)_",
|
"打包应用设置页面增加前台服务开关 _[`issue #406`](http://issues.autojs6.com/406)_",
|
||||||
"脚本项目配置文件保存时增加键名冲突检测机制防止键名歧义",
|
"脚本项目配置文件保存时增加键名冲突检测机制防止键名歧义",
|
||||||
|
|||||||
@@ -167,13 +167,14 @@
|
|||||||
|
|
||||||
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
|
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
|
||||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
||||||
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
|
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
|
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
|
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
|
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
|
||||||
|
|||||||
@@ -3,34 +3,21 @@ package androidx.recyclerview.widget;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.widget.EdgeEffect;
|
import android.widget.EdgeEffect;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.widget.EdgeEffectCompat;
|
|
||||||
import org.autojs.autojs.theme.ThemeColor;
|
import org.autojs.autojs.theme.ThemeColor;
|
||||||
import org.autojs.autojs.theme.ThemeColorManager;
|
import org.autojs.autojs.theme.ThemeColorManager;
|
||||||
import org.autojs.autojs.theme.ThemeColorMutable;
|
import org.autojs.autojs.theme.ThemeColorMutable;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on Aug 14, 2016.
|
* Created by Stardust on Aug 14, 2016.
|
||||||
* Modified by SuperMonster003 as of Dec 1, 2021.
|
* Modified by JetBrains AI Assistant (GPT-5.3-Codex (xhigh)) as of Mar 6, 2026.
|
||||||
|
* Modified by SuperMonster003 as of Mar 6, 2026.
|
||||||
*/
|
*/
|
||||||
public class ThemeColorRecyclerView extends RecyclerView implements ThemeColorMutable {
|
public class ThemeColorRecyclerView extends RecyclerView implements ThemeColorMutable {
|
||||||
|
|
||||||
private int mColorPrimary;
|
private int mColorPrimary;
|
||||||
|
|
||||||
private Field mLeftGlowField;
|
|
||||||
private Field mTopGlowField;
|
|
||||||
private Field mRightGlowField;
|
|
||||||
private Field mBottomGlowField;
|
|
||||||
|
|
||||||
private Field mEdgeEffectField;
|
|
||||||
|
|
||||||
private boolean hasAppliedThemeColorLeft;
|
|
||||||
private boolean hasAppliedThemeColorTop;
|
|
||||||
private boolean hasAppliedThemeColorRight;
|
|
||||||
private boolean hasAppliedThemeColorBottom;
|
|
||||||
|
|
||||||
public ThemeColorRecyclerView(Context context) {
|
public ThemeColorRecyclerView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
init();
|
init();
|
||||||
@@ -46,65 +33,17 @@ public class ThemeColorRecyclerView extends RecyclerView implements ThemeColorMu
|
|||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean applyThemeColor(Field edgeEffectCompatField) {
|
|
||||||
try {
|
|
||||||
EdgeEffectCompat edgeEffectCompat = (EdgeEffectCompat) edgeEffectCompatField.get(this);
|
|
||||||
if (edgeEffectCompat != null) {
|
|
||||||
return setEdgeEffectColor(edgeEffectCompat, mColorPrimary);
|
|
||||||
}
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
/* Ignored. */
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
try {
|
setEdgeEffectFactory(new EdgeEffectFactory() {
|
||||||
mEdgeEffectField = EdgeEffectCompat.class.getDeclaredField("mEdgeEffect");
|
@NonNull
|
||||||
mEdgeEffectField.setAccessible(true);
|
@Override
|
||||||
mLeftGlowField = RecyclerView.class.getDeclaredField("mLeftGlow");
|
protected EdgeEffect createEdgeEffect(@NonNull RecyclerView view, int direction) {
|
||||||
mLeftGlowField.setAccessible(true);
|
EdgeEffect edgeEffect = new EdgeEffect(view.getContext());
|
||||||
mRightGlowField = RecyclerView.class.getDeclaredField("mRightGlow");
|
edgeEffect.setColor(mColorPrimary);
|
||||||
mRightGlowField.setAccessible(true);
|
return edgeEffect;
|
||||||
mTopGlowField = RecyclerView.class.getDeclaredField("mTopGlow");
|
|
||||||
mTopGlowField.setAccessible(true);
|
|
||||||
mBottomGlowField = RecyclerView.class.getDeclaredField("mBottomGlow");
|
|
||||||
mBottomGlowField.setAccessible(true);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
// android:fadeScrollbars="true"
|
|
||||||
// setScrollbarFadingEnabled(true);
|
|
||||||
|
|
||||||
// android:scrollbarDefaultDelayBeforeFade="600"
|
|
||||||
// setScrollBarDefaultDelayBeforeFade(600);
|
|
||||||
|
|
||||||
// android:scrollbarFadeDuration="500"
|
|
||||||
// setScrollBarFadeDuration(500);
|
|
||||||
|
|
||||||
// android:scrollbars="vertical"
|
|
||||||
// setVerticalScrollBarEnabled(true);
|
|
||||||
|
|
||||||
// To ensure scrollbar fading works properly.
|
|
||||||
// setFadingEdgeLength(0);
|
|
||||||
|
|
||||||
ThemeColorManager.add(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean setEdgeEffectColor(EdgeEffectCompat compat, int color) {
|
|
||||||
if (compat == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
EdgeEffect edgeEffect = (EdgeEffect) mEdgeEffectField.get(compat);
|
|
||||||
if (edgeEffect != null) {
|
|
||||||
edgeEffect.setColor(color);
|
|
||||||
}
|
}
|
||||||
} catch (Exception ignored) {
|
});
|
||||||
/* Ignored. */
|
ThemeColorManager.add(this);
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -113,36 +52,7 @@ public class ThemeColorRecyclerView extends RecyclerView implements ThemeColorMu
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mColorPrimary = color.colorPrimary;
|
mColorPrimary = color.colorPrimary;
|
||||||
invalidateGlows();
|
|
||||||
}
|
|
||||||
|
|
||||||
void invalidateGlows() {
|
|
||||||
super.invalidateGlows();
|
super.invalidateGlows();
|
||||||
hasAppliedThemeColorLeft = false;
|
|
||||||
hasAppliedThemeColorTop = false;
|
|
||||||
hasAppliedThemeColorRight = false;
|
|
||||||
hasAppliedThemeColorBottom = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ensureLeftGlow() {
|
|
||||||
super.ensureLeftGlow();
|
|
||||||
hasAppliedThemeColorLeft = hasAppliedThemeColorLeft || applyThemeColor(mLeftGlowField);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ensureTopGlow() {
|
|
||||||
super.ensureTopGlow();
|
|
||||||
hasAppliedThemeColorTop = hasAppliedThemeColorTop || applyThemeColor(mTopGlowField);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ensureRightGlow() {
|
|
||||||
super.ensureLeftGlow();
|
|
||||||
hasAppliedThemeColorRight = hasAppliedThemeColorRight || applyThemeColor(mRightGlowField);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ensureBottomGlow() {
|
|
||||||
super.ensureBottomGlow();
|
|
||||||
hasAppliedThemeColorBottom = hasAppliedThemeColorBottom || applyThemeColor(mBottomGlowField);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,6 @@ class ScriptPromiseAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val UNSET = Object()
|
private val UNSET = Any()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,7 +156,7 @@ open class RhinoJavaScriptEngine(private val mAndroidContext: android.content.Co
|
|||||||
|
|
||||||
override fun wrap(cx: Context, scope: Scriptable, obj: Any?, staticType: Class<*>?): Any? {
|
override fun wrap(cx: Context, scope: Scriptable, obj: Any?, staticType: Class<*>?): Any? {
|
||||||
return when {
|
return when {
|
||||||
obj is String -> runtime.bridges.toString(obj.toString())
|
obj is String -> runtime.bridges.toString(obj)
|
||||||
staticType == UiObjectCollection::class.java -> runtime.bridges.asArray(obj)
|
staticType == UiObjectCollection::class.java -> runtime.bridges.asArray(obj)
|
||||||
else -> super.wrap(cx, scope, obj, staticType)
|
else -> super.wrap(cx, scope, obj, staticType)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class SearchUpTargetAction(action: Int, filter: FilterAction.Filter) : SearchTar
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private val TAG = SearchUpTargetAction::class.java!!.getSimpleName()
|
private val TAG = SearchUpTargetAction::class.java.getSimpleName()
|
||||||
private val LOOP_MAX = 20
|
private val LOOP_MAX = 20
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -863,13 +863,17 @@ open class UiSelector : UiObjectActions, StringReadable {
|
|||||||
|
|
||||||
internal fun pick(scriptRuntime: ScriptRuntime) = Detector(compass, object : Result(resultType) {
|
internal fun pick(scriptRuntime: ScriptRuntime) = Detector(compass, object : Result(resultType) {
|
||||||
|
|
||||||
override fun byOne() = selector?.let { sel ->
|
override fun byOne(): UiObject? {
|
||||||
root?.let { return sel.findOneOf(it) } ?: sel.findOnce()
|
return selector?.let { sel ->
|
||||||
|
root?.let { return sel.findOneOf(it) } ?: sel.findOnce()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun byAll() = selector?.let { sel ->
|
override fun byAll(): UiObjectCollection {
|
||||||
root?.let { return sel.findOf(it) } ?: sel.find()
|
return selector?.let { sel ->
|
||||||
} ?: EMPTY
|
root?.let { return sel.findOf(it) } ?: sel.find()
|
||||||
|
} ?: EMPTY
|
||||||
|
}
|
||||||
|
|
||||||
}, callback, selector).detect(scriptRuntime)
|
}, callback, selector).detect(scriptRuntime)
|
||||||
|
|
||||||
|
|||||||
@@ -41,15 +41,17 @@ class StartForResultActivity : Activity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (extras == null) {
|
if (extras == null) {
|
||||||
finish().also { return }
|
finish()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
val callback = extras!!.map["callback"]
|
val callback = extras.map["callback"]
|
||||||
if (callback is Callback) {
|
if (callback is Callback) {
|
||||||
mCallback = callback
|
mCallback = callback
|
||||||
}
|
}
|
||||||
if (callback == null) {
|
if (callback == null) {
|
||||||
mCallback = null
|
mCallback = null
|
||||||
finish().also { return }
|
finish()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
mCallback!!.onActivityCreate(this)
|
mCallback!!.onActivityCreate(this)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ enum class Language(@JvmField val languageTag: String, @KeyRes private val keyRe
|
|||||||
;
|
;
|
||||||
|
|
||||||
val locale: Locale = when (languageTag.isBlank()) {
|
val locale: Locale = when (languageTag.isBlank()) {
|
||||||
true -> LocaleUtils.getSystemLocale()
|
true -> LocaleUtils.getPrimarySystemLocale()
|
||||||
else -> Locale.forLanguageTag(languageTag)
|
else -> Locale.forLanguageTag(languageTag)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ enum class Language(@JvmField val languageTag: String, @KeyRes private val keyRe
|
|||||||
return languageTag
|
return languageTag
|
||||||
}
|
}
|
||||||
|
|
||||||
val systemTag = LocaleUtils.getSystemLocale().toLanguageTag()
|
val systemTag = LocaleUtils.getPrimarySystemLocale().toLanguageTag()
|
||||||
val availableTags = values().map { it.languageTag }
|
val availableTags = values().map { it.languageTag }
|
||||||
|
|
||||||
if (systemTag in availableTags) {
|
if (systemTag in availableTags) {
|
||||||
|
|||||||
@@ -7,10 +7,6 @@ import android.util.Log
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import org.autojs.autojs.core.ui.ViewExtras
|
import org.autojs.autojs.core.ui.ViewExtras
|
||||||
import org.autojs.autojs.engine.module.AssetAndUrlModuleSourceProvider
|
import org.autojs.autojs.engine.module.AssetAndUrlModuleSourceProvider
|
||||||
import org.autojs.autojs.rhino.extension.AnyExtensions.isJsNullish
|
|
||||||
import org.autojs.autojs.rhino.extension.AnyExtensions.jsBrief
|
|
||||||
import org.autojs.autojs.rhino.extension.ScriptableExtensions.defineProp
|
|
||||||
import org.autojs.autojs.rhino.extension.ScriptableExtensions.prop
|
|
||||||
import org.autojs.autojs.pio.PFiles
|
import org.autojs.autojs.pio.PFiles
|
||||||
import org.autojs.autojs.pio.UncheckedIOException
|
import org.autojs.autojs.pio.UncheckedIOException
|
||||||
import org.autojs.autojs.project.ScriptConfig
|
import org.autojs.autojs.project.ScriptConfig
|
||||||
@@ -18,6 +14,10 @@ import org.autojs.autojs.rhino.AndroidContextFactory
|
|||||||
import org.autojs.autojs.rhino.AutoJsContext
|
import org.autojs.autojs.rhino.AutoJsContext
|
||||||
import org.autojs.autojs.rhino.RhinoAndroidHelper
|
import org.autojs.autojs.rhino.RhinoAndroidHelper
|
||||||
import org.autojs.autojs.rhino.TopLevelScope
|
import org.autojs.autojs.rhino.TopLevelScope
|
||||||
|
import org.autojs.autojs.rhino.extension.AnyExtensions.isJsNullish
|
||||||
|
import org.autojs.autojs.rhino.extension.AnyExtensions.jsBrief
|
||||||
|
import org.autojs.autojs.rhino.extension.ScriptableExtensions.defineProp
|
||||||
|
import org.autojs.autojs.rhino.extension.ScriptableExtensions.prop
|
||||||
import org.autojs.autojs.runtime.ScriptRuntime
|
import org.autojs.autojs.runtime.ScriptRuntime
|
||||||
import org.autojs.autojs.runtime.api.augment.proxy.PaintProxyObject
|
import org.autojs.autojs.runtime.api.augment.proxy.PaintProxyObject
|
||||||
import org.autojs.autojs.script.JavaScriptSource
|
import org.autojs.autojs.script.JavaScriptSource
|
||||||
@@ -42,7 +42,7 @@ import java.io.IOException
|
|||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
import java.io.Reader
|
import java.io.Reader
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.util.*
|
import java.util.Locale
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on Apr 2, 2017.
|
* Created by Stardust on Apr 2, 2017.
|
||||||
@@ -215,9 +215,9 @@ open class RhinoJavaScriptEngine(private val androidContext: android.content.Con
|
|||||||
private inner class WrapFactory : AndroidContextFactory.WrapFactory() {
|
private inner class WrapFactory : AndroidContextFactory.WrapFactory() {
|
||||||
|
|
||||||
override fun wrapAsJavaObject(cx: Context?, scope: Scriptable, javaObject: Any?, staticType: TypeInfo): Scriptable? {
|
override fun wrapAsJavaObject(cx: Context?, scope: Scriptable, javaObject: Any?, staticType: TypeInfo): Scriptable? {
|
||||||
return when (javaObject) {
|
return when {
|
||||||
is View -> ViewExtras.getNativeView(scope, /* view = */ javaObject, staticType.asClass(), runtime)
|
javaObject is View -> ViewExtras.getNativeView(scope, /* view = */ javaObject, staticType.asClass(), runtime)
|
||||||
is Paint if Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> {
|
javaObject is Paint && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> {
|
||||||
// Use composition-based proxy to preserve Paint identity and intercept setColor only.
|
// Use composition-based proxy to preserve Paint identity and intercept setColor only.
|
||||||
// zh-CN: 使用组合式代理以保持 Paint 身份一致性, 且仅拦截 setColor.
|
// zh-CN: 使用组合式代理以保持 Paint 身份一致性, 且仅拦截 setColor.
|
||||||
val base = super.wrapAsJavaObject(cx, scope, javaObject, staticType) ?: return null
|
val base = super.wrapAsJavaObject(cx, scope, javaObject, staticType) ?: return null
|
||||||
@@ -226,11 +226,12 @@ open class RhinoJavaScriptEngine(private val androidContext: android.content.Con
|
|||||||
else -> super.wrapAsJavaObject(cx, scope, javaObject, staticType)
|
else -> super.wrapAsJavaObject(cx, scope, javaObject, staticType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
private const val TAG = "RhinoJavaScriptEngine"
|
||||||
|
|
||||||
const val SOURCE_FILE_INIT = "init.js"
|
const val SOURCE_FILE_INIT = "init.js"
|
||||||
const val SOURCE_NAME_INIT = "<init>"
|
const val SOURCE_NAME_INIT = "<init>"
|
||||||
const val MODULES_ROOT_PATH = "modules"
|
const val MODULES_ROOT_PATH = "modules"
|
||||||
@@ -238,9 +239,5 @@ open class RhinoJavaScriptEngine(private val androidContext: android.content.Con
|
|||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val JS_BEAUTIFY_FILE = PFiles.join(JS_BEAUTIFY_PATH, "beautify.js")
|
val JS_BEAUTIFY_FILE = PFiles.join(JS_BEAUTIFY_PATH, "beautify.js")
|
||||||
|
|
||||||
private val TAG = RhinoJavaScriptEngine::class.java.simpleName
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ object ScriptIntents {
|
|||||||
JavaScriptFileSource(path).let { fss: JavaScriptFileSource ->
|
JavaScriptFileSource(path).let { fss: JavaScriptFileSource ->
|
||||||
source = script?.let { SequenceScriptSource(fss.name, StringScriptSource(it), fss) } ?: fss
|
source = script?.let { SequenceScriptSource(fss.name, StringScriptSource(it), fss) } ?: fss
|
||||||
}
|
}
|
||||||
File(path!!).parent?.let { config.workingDirectory = it }
|
File(path).parent?.let { config.workingDirectory = it }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
source?.let { AutoJs.instance.scriptEngineService.execute(it, config) }
|
source?.let { AutoJs.instance.scriptEngineService.execute(it, config) }
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ package org.autojs.autojs.inrt
|
|||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.EdgeEffect
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import org.autojs.autojs.runtime.api.Permissions
|
import org.autojs.autojs.runtime.api.Permissions
|
||||||
import org.autojs.autojs.theme.preference.Syncable
|
import org.autojs.autojs.theme.preference.Syncable
|
||||||
import org.autojs.autojs.util.ViewUtils.excludePaddingClippableViewFromBottomNavigationBar
|
import org.autojs.autojs.util.ViewUtils.excludePaddingClippableViewFromBottomNavigationBar
|
||||||
@@ -67,11 +69,17 @@ class SettingsActivity : AppCompatActivity() {
|
|||||||
setDivider(null)
|
setDivider(null)
|
||||||
setDividerHeight(0)
|
setDividerHeight(0)
|
||||||
|
|
||||||
|
listView.edgeEffectFactory = object : RecyclerView.EdgeEffectFactory() {
|
||||||
|
override fun createEdgeEffect(recyclerView: RecyclerView, direction: Int): EdgeEffect {
|
||||||
|
return EdgeEffect(recyclerView.context).apply {
|
||||||
|
color = recyclerView.context.getColor(R.color.md_blue_gray_500)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
listView.isHorizontalScrollBarEnabled = false
|
listView.isHorizontalScrollBarEnabled = false
|
||||||
listView.isVerticalScrollBarEnabled = false
|
listView.isVerticalScrollBarEnabled = false
|
||||||
listView.excludePaddingClippableViewFromBottomNavigationBar()
|
listView.excludePaddingClippableViewFromBottomNavigationBar()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,12 +61,13 @@ class AppUtils(context: Context, @get:ScriptInterface val fileProviderAuthority:
|
|||||||
* @param o < alias | packageName >
|
* @param o < alias | packageName >
|
||||||
*/
|
*/
|
||||||
@ScriptInterface
|
@ScriptInterface
|
||||||
fun launchPackage(o: String?) = runCatching {
|
fun launchPackage(o: String?): Boolean =
|
||||||
o ?: return false
|
runCatching {
|
||||||
val nicePackageName = getAppByAlias(alias = o)?.packageName ?: (/* packageName = */ o)
|
o ?: return false
|
||||||
val intent = mPackageManager.getLaunchIntentForPackage(nicePackageName) ?: return false
|
val nicePackageName = getAppByAlias(alias = o)?.packageName ?: (/* packageName = */ o)
|
||||||
intent.start(mContext)
|
val intent = mPackageManager.getLaunchIntentForPackage(nicePackageName) ?: return false
|
||||||
}.isSuccess
|
intent.start(mContext)
|
||||||
|
}.isSuccess
|
||||||
|
|
||||||
@ScriptInterface
|
@ScriptInterface
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
|
|||||||
@@ -122,14 +122,14 @@ class Device(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
@RhinoFunctionBody
|
@RhinoFunctionBody
|
||||||
fun vibrateRhinoWithRuntime(scriptRuntime: ScriptRuntime, o: Any?, p: Any?) {
|
fun vibrateRhinoWithRuntime(scriptRuntime: ScriptRuntime, o: Any?, p: Any?) {
|
||||||
when (o) {
|
when {
|
||||||
is String -> {
|
o is String -> {
|
||||||
MorseCode.vibrateRhino(o, p)
|
MorseCode.vibrateRhino(o, p)
|
||||||
}
|
}
|
||||||
is Number if p is Number -> {
|
o is Number && p is Number -> {
|
||||||
scriptRuntime.device.vibrate(/* off = */ o.toLong(), /* millis = */ p.toLong())
|
scriptRuntime.device.vibrate(/* off = */ o.toLong(), /* millis = */ p.toLong())
|
||||||
}
|
}
|
||||||
is NativeArray if p is Number -> {
|
o is NativeArray && p is Number -> {
|
||||||
val listOff = listOf(p.toLong())
|
val listOff = listOf(p.toLong())
|
||||||
val listOthers = o.map { toVibrateTimingElement(it) }
|
val listOthers = o.map { toVibrateTimingElement(it) }
|
||||||
val timings = (listOff + listOthers).toLongArray()
|
val timings = (listOff + listOthers).toLongArray()
|
||||||
|
|||||||
@@ -494,15 +494,16 @@ class Dialogs(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun applyDialogProperty(builder: JsDialogBuilder, name: String, value: Any?) {
|
private fun applyDialogProperty(builder: JsDialogBuilder, name: String, value: Any?) {
|
||||||
when (val propertySetter = propertySetterMap[name]) {
|
val propertySetter = propertySetterMap[name]
|
||||||
PropertyConverter.COLOR_INT -> {
|
when {
|
||||||
|
propertySetter == PropertyConverter.COLOR_INT -> {
|
||||||
val colorInt = Colors.toIntRhino(value)
|
val colorInt = Colors.toIntRhino(value)
|
||||||
invokeJavaMethod(builder, name, arrayOf(colorInt))
|
invokeJavaMethod(builder, name, arrayOf(colorInt))
|
||||||
}
|
}
|
||||||
PropertyConverter.BOOLEAN if coerceBoolean(value, false) -> {
|
propertySetter == PropertyConverter.BOOLEAN && coerceBoolean(value, false) -> {
|
||||||
invokeJavaMethod(builder, name, emptyArray())
|
invokeJavaMethod(builder, name, emptyArray())
|
||||||
}
|
}
|
||||||
is String -> when (propertySetter) {
|
propertySetter is String -> when (propertySetter) {
|
||||||
in propertySetterMap -> {
|
in propertySetterMap -> {
|
||||||
applyDialogProperty(builder, propertySetter, value)
|
applyDialogProperty(builder, propertySetter, value)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1494,7 +1494,7 @@ class Images(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitt
|
|||||||
val similarityMethod = runCatching {
|
val similarityMethod = runCatching {
|
||||||
ImageSimilarity::class.java.getDeclaredMethod(metric, OpencvMat::class.java, OpencvMat::class.java)
|
ImageSimilarity::class.java.getDeclaredMethod(metric, OpencvMat::class.java, OpencvMat::class.java)
|
||||||
}.getOrElse { throw WrappedIllegalArgumentException("Unknown similarity metric: $metric") }
|
}.getOrElse { throw WrappedIllegalArgumentException("Unknown similarity metric: $metric") }
|
||||||
if (similarityMethod.returnType != Double::class.java && similarityMethod.returnType != java.lang.Double::class.java) {
|
if (similarityMethod.returnType != Double::class.java) {
|
||||||
throw WrappedIllegalArgumentException("Similarity metric ($metric) method must return Double type. Found: ${similarityMethod.returnType}")
|
throw WrappedIllegalArgumentException("Similarity metric ($metric) method must return Double type. Found: ${similarityMethod.returnType}")
|
||||||
}
|
}
|
||||||
similarityMethod.invoke(ImageSimilarity, matA, matB) as Double
|
similarityMethod.invoke(ImageSimilarity, matA, matB) as Double
|
||||||
|
|||||||
@@ -587,9 +587,7 @@ object Inspect : Augmentable(), Invokable {
|
|||||||
|
|
||||||
private fun formatProperty(ctx: Ctx, value: ScriptableObject, recurseTimes: Int?, visibleKeys: NativeObject, key: String, array: Boolean): String {
|
private fun formatProperty(ctx: Ctx, value: ScriptableObject, recurseTimes: Int?, visibleKeys: NativeObject, key: String, array: Boolean): String {
|
||||||
var name: String? = null
|
var name: String? = null
|
||||||
val desc = js_object_getOwnPropertyDescriptor(value, key) ?: newNativeObject().apply {
|
val desc = js_object_getOwnPropertyDescriptor(value, key)
|
||||||
put("value", this, value.prop(key))
|
|
||||||
}
|
|
||||||
val getter = desc.prop(PROXY_GETTER_KEY)
|
val getter = desc.prop(PROXY_GETTER_KEY)
|
||||||
val setter = desc.prop(PROXY_SETTER_KEY)
|
val setter = desc.prop(PROXY_SETTER_KEY)
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package org.autojs.autojs.theme.widget;
|
package org.autojs.autojs.theme.widget;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.widget.EdgeEffect;
|
import android.widget.EdgeEffect;
|
||||||
import android.widget.HorizontalScrollView;
|
import android.widget.HorizontalScrollView;
|
||||||
|
|
||||||
import org.autojs.autojs.theme.ThemeColor;
|
import org.autojs.autojs.theme.ThemeColor;
|
||||||
import org.autojs.autojs.theme.ThemeColorManager;
|
import org.autojs.autojs.theme.ThemeColorManager;
|
||||||
import org.autojs.autojs.theme.ThemeColorMutable;
|
import org.autojs.autojs.theme.ThemeColorMutable;
|
||||||
@@ -60,17 +61,23 @@ public class ThemeColorHorizontalScrollView extends HorizontalScrollView impleme
|
|||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("DiscouragedPrivateApi")
|
||||||
private void syncEdgeEffect() {
|
private void syncEdgeEffect() {
|
||||||
try {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
Field f1 = HorizontalScrollView.class.getDeclaredField("mEdgeGlowLeft");
|
setLeftEdgeEffectColor(mFadingEdgeColor);
|
||||||
f1.setAccessible(true);
|
setRightEdgeEffectColor(mFadingEdgeColor);
|
||||||
f1.set(this, mEdgeGlowLeft);
|
} else {
|
||||||
|
try {
|
||||||
|
Field f1 = HorizontalScrollView.class.getDeclaredField("mEdgeGlowLeft");
|
||||||
|
f1.setAccessible(true);
|
||||||
|
f1.set(this, mEdgeGlowLeft);
|
||||||
|
|
||||||
Field f2 = HorizontalScrollView.class.getDeclaredField("mEdgeGlowRight");
|
Field f2 = HorizontalScrollView.class.getDeclaredField("mEdgeGlowRight");
|
||||||
f2.setAccessible(true);
|
f2.setAccessible(true);
|
||||||
f2.set(this, mEdgeGlowRight);
|
f2.set(this, mEdgeGlowRight);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1080,7 +1080,7 @@ public class ScriptOperations {
|
|||||||
// zh-CN: 删除操作使用不确定进度条即可, 行为更稳定.
|
// zh-CN: 删除操作使用不确定进度条即可, 行为更稳定.
|
||||||
MaterialDialog.Builder builder = new MaterialDialog.Builder(mContext)
|
MaterialDialog.Builder builder = new MaterialDialog.Builder(mContext)
|
||||||
.title(titleRes)
|
.title(titleRes)
|
||||||
.content(R.string.text_deleting)
|
.content(mContext.getString(R.string.text_deleting) + mContext.getString(R.string.text_half_ellipsis))
|
||||||
.negativeText(R.string.dialog_button_abort)
|
.negativeText(R.string.dialog_button_abort)
|
||||||
.negativeColorRes(R.color.dialog_button_caution)
|
.negativeColorRes(R.color.dialog_button_caution)
|
||||||
.onNegative((dialog, which) -> {
|
.onNegative((dialog, which) -> {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import android.content.ContextWrapper
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
|
import android.graphics.Color
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
@@ -1328,8 +1329,8 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
mNormalToolbar.apply {
|
mNormalToolbar.apply {
|
||||||
setOnMenuItemClickListener(this@EditorView)
|
setOnMenuItemClickListener(this@EditorView)
|
||||||
setOnMenuItemLongClickListener { id ->
|
setOnMenuItemLongClickListener { id ->
|
||||||
when (id) {
|
when {
|
||||||
R.id.run if !mReadOnly -> true.also { debug() }
|
id == R.id.run && !mReadOnly -> true.also { debug() }
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1338,8 +1339,8 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
(existing as? ToolbarFragment<*>)?.apply {
|
(existing as? ToolbarFragment<*>)?.apply {
|
||||||
setOnMenuItemClickListener(this@EditorView)
|
setOnMenuItemClickListener(this@EditorView)
|
||||||
setOnMenuItemLongClickListener { id ->
|
setOnMenuItemLongClickListener { id ->
|
||||||
when (id) {
|
when {
|
||||||
R.id.run if !mReadOnly -> true.also { debug() }
|
id == R.id.run && !mReadOnly -> true.also { debug() }
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1513,7 +1514,12 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
mCodeCompletionBar.setTextColor(textColor)
|
mCodeCompletionBar.setTextColor(textColor)
|
||||||
mSymbolBar.setTextColor(textColor)
|
mSymbolBar.setTextColor(textColor)
|
||||||
mShowFunctionsButton.setColorFilter(textColor)
|
mShowFunctionsButton.setColorFilter(textColor)
|
||||||
ViewUtils.setNavigationBarBackgroundColor(activity, imeBarBackgroundColor)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
ViewUtils.setNavigationBarBackgroundColor(activity, imeBarBackgroundColor)
|
||||||
|
} else {
|
||||||
|
val adjustedImageContrastColor = ColorUtils.adjustColorForContrast(Color.WHITE, ColorUtils.applyAlpha(imeBarBackgroundColor, 1.0), 2.3)
|
||||||
|
ViewUtils.setNavigationBarBackgroundColor(activity, adjustedImageContrastColor)
|
||||||
|
}
|
||||||
invalidate()
|
invalidate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2683,7 +2689,7 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag
|
|||||||
private const val MIN_CONFIDENCE_TO_WRITE_FILE = 90
|
private const val MIN_CONFIDENCE_TO_WRITE_FILE = 90
|
||||||
private val DEFAULT_CHARSET_TO_WRITE_FILE = StandardCharsets.UTF_8
|
private val DEFAULT_CHARSET_TO_WRITE_FILE = StandardCharsets.UTF_8
|
||||||
|
|
||||||
private const val LARGE_FILE_MODE_THRESHOLD = JavaScriptHighlighter.MAX_HIGHLIGHT_CHARS
|
private const val LARGE_FILE_MODE_THRESHOLD = JavaScriptHighlighter.MAX_HIGHLIGHT_CHARS
|
||||||
|
|
||||||
// Internal storage root (no external SD).
|
// Internal storage root (no external SD).
|
||||||
// zh-CN: 内部存储根目录 (不访问外置 SD).
|
// zh-CN: 内部存储根目录 (不访问外置 SD).
|
||||||
|
|||||||
@@ -597,11 +597,14 @@ class CodeEditText : AppCompatEditText {
|
|||||||
runCatching { event.text.clear() }
|
runCatching { event.text.clear() }
|
||||||
runCatching { event.contentDescription = null }
|
runCatching { event.contentDescription = null }
|
||||||
|
|
||||||
// Also drop selection-changed events entirely in large-text mode.
|
// Also drop selection-changed events entirely in large-text mode to avoid TransactionTooLargeException.
|
||||||
// zh-CN: 大文本模式下直接丢弃 selection-changed 事件.
|
// zh-CN: 大文本模式下直接丢弃 selection-changed 事件以避免 TransactionTooLargeException.
|
||||||
if (event.eventType == AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED) return
|
when (event.eventType) {
|
||||||
if (event.eventType == AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED) return
|
AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED -> return
|
||||||
if (event.eventType == AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY) return
|
AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED -> return
|
||||||
|
AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY -> return
|
||||||
|
else -> Unit
|
||||||
|
}
|
||||||
}
|
}
|
||||||
super.sendAccessibilityEventUnchecked(event)
|
super.sendAccessibilityEventUnchecked(event)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ class CodeEditor : HVScrollView {
|
|||||||
if (mProcessDialog?.isShowing == true) return@Runnable
|
if (mProcessDialog?.isShowing == true) return@Runnable
|
||||||
|
|
||||||
mProcessDialog = MaterialDialog.Builder(context)
|
mProcessDialog = MaterialDialog.Builder(context)
|
||||||
.content(R.string.text_processing)
|
.content(R.string.text_in_progress)
|
||||||
// Text only, no progress spinner.
|
// Text only, no progress spinner.
|
||||||
// zh-CN: 仅显示文字, 不使用进度圆圈动画.
|
// zh-CN: 仅显示文字, 不使用进度圆圈动画.
|
||||||
.cancelable(false)
|
.cancelable(false)
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ object SymbolsConfigStore {
|
|||||||
fun getAllDefaultNameAliases(context: Context): Set<String> {
|
fun getAllDefaultNameAliases(context: Context): Set<String> {
|
||||||
val appLang = Language.getPrefLanguageOrNull()
|
val appLang = Language.getPrefLanguageOrNull()
|
||||||
val appKey = appLang?.languageTag ?: "null"
|
val appKey = appLang?.languageTag ?: "null"
|
||||||
val sysKey = LocaleUtils.getSystemLocale().toLanguageTag()
|
val sysKey = LocaleUtils.getPrimarySystemLocale().toLanguageTag()
|
||||||
val cacheKey = "app=$appKey|sys=$sysKey"
|
val cacheKey = "app=$appKey|sys=$sysKey"
|
||||||
|
|
||||||
sDefaultAliasesCache[cacheKey]?.let { return it }
|
sDefaultAliasesCache[cacheKey]?.let { return it }
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ class NodeInfoView : RecyclerView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return when (NodeInfo::class.java.getDeclaredField(attr).type) {
|
return when (NodeInfo::class.java.getDeclaredField(attr).type) {
|
||||||
java.lang.String::class.java -> "$attr('$value')"
|
String::class.java -> "$attr('$value')"
|
||||||
else -> "$attr($value)"
|
else -> "$attr($value)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ package org.autojs.autojs.ui.settings
|
|||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.EdgeEffect
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import org.autojs.autojs.theme.ThemeColorManager
|
||||||
import org.autojs.autojs.util.ViewUtils.excludePaddingClippableViewFromBottomNavigationBar
|
import org.autojs.autojs.util.ViewUtils.excludePaddingClippableViewFromBottomNavigationBar
|
||||||
import org.autojs.autojs6.R
|
import org.autojs.autojs6.R
|
||||||
|
|
||||||
@@ -14,9 +17,15 @@ class PreferencesFragment : PreferenceFragmentCompat() {
|
|||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
listView.edgeEffectFactory = object : RecyclerView.EdgeEffectFactory() {
|
||||||
|
override fun createEdgeEffect(recyclerView: RecyclerView, direction: Int): EdgeEffect {
|
||||||
|
return EdgeEffect(recyclerView.context).apply {
|
||||||
|
color = ThemeColorManager.colorPrimary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
listView.isHorizontalScrollBarEnabled = false
|
listView.isHorizontalScrollBarEnabled = false
|
||||||
listView.isVerticalScrollBarEnabled = false
|
listView.isVerticalScrollBarEnabled = false
|
||||||
listView.excludePaddingClippableViewFromBottomNavigationBar()
|
listView.excludePaddingClippableViewFromBottomNavigationBar()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -384,10 +384,8 @@ object ColorUtils {
|
|||||||
)
|
)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun applyAlpha(@ColorInt color: Int, alpha: Double): Int = when (alpha) {
|
fun applyAlpha(@ColorInt color: Int, alpha: Double): Int =
|
||||||
1.0 -> color
|
ColorUtils.setAlphaComponent(color, (alpha * 255).roundToInt())
|
||||||
else -> ColorUtils.setAlphaComponent(color, (alpha * 255).roundToInt())
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the contrast ratio between two colors using the W3C WCAG formula.
|
* Calculate the contrast ratio between two colors using the W3C WCAG formula.
|
||||||
|
|||||||
@@ -3091,16 +3091,17 @@ object FileUtils {
|
|||||||
}.getOrElse { false }
|
}.getOrElse { false }
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun File.isBinDiscImageLike() = runCatching {
|
fun File.isBinDiscImageLike(): Boolean =
|
||||||
this@isBinDiscImageLike.inputStream().use { inputStream ->
|
runCatching {
|
||||||
val header = ByteArray(2048) // Read first sector
|
this@isBinDiscImageLike.inputStream().use { inputStream ->
|
||||||
if (inputStream.read(header) != header.size) return false
|
val header = ByteArray(2048) // Read first sector
|
||||||
|
if (inputStream.read(header) != header.size) return false
|
||||||
|
|
||||||
// Check for very basic ISO 9660 primary volume descriptor
|
// Check for very basic ISO 9660 primary volume descriptor
|
||||||
val pvdDescriptor = "CD001".toByteArray()
|
val pvdDescriptor = "CD001".toByteArray()
|
||||||
header.sliceArray(0x800 until 0x800 + pvdDescriptor.size).contentEquals(pvdDescriptor)
|
header.sliceArray(0x800 until 0x800 + pvdDescriptor.size).contentEquals(pvdDescriptor)
|
||||||
}
|
}
|
||||||
}.getOrElse { false }
|
}.getOrElse { false }
|
||||||
|
|
||||||
// Determines if a CUE file describes audio tracks
|
// Determines if a CUE file describes audio tracks
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@@ -3168,17 +3169,26 @@ object FileUtils {
|
|||||||
}.getOrElse { false }
|
}.getOrElse { false }
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun File.isSegaMDLike() = runCatching {
|
fun File.isSegaMDLike(): Boolean =
|
||||||
this@isSegaMDLike.inputStream().use { inputStream ->
|
runCatching {
|
||||||
val header = ByteArray(512) // 假设 SEGA 游戏文件有特定的头部
|
this@isSegaMDLike.inputStream().use { inputStream ->
|
||||||
if (inputStream.read(header) != header.size) return false
|
// Assume SEGA game files have a specific header.
|
||||||
|
// zh-CN: 假设 SEGA 游戏文件有特定的头部.
|
||||||
|
val header = ByteArray(512)
|
||||||
|
if (inputStream.read(header) != header.size) return false
|
||||||
|
|
||||||
// 这里你需要根据 SEGA 文件的具体特征来调整条件
|
// Here is the modification needed to adjust the conditions based on specific SEGA file characteristics.
|
||||||
// 例如: 找到特定的标识符或者模式
|
// This requires identifying specific identifiers or patterns within the header.
|
||||||
val segaIdentifier = byteArrayOf(0x53, 0x45, 0x47, 0x41) // 可能的 "SEGA" 标记
|
// zh-CN:
|
||||||
header.sliceArray(segaIdentifier.indices).contentEquals(segaIdentifier)
|
// 这里需要根据 SEGA 文件的具体特征来调整条件.
|
||||||
}
|
// 例如: 找到特定的标识符或者模式.
|
||||||
}.getOrElse { false }
|
|
||||||
|
// Possible "SEGA" marker.
|
||||||
|
// zh-CN: 可能的 "SEGA" 标记.
|
||||||
|
val segaIdentifier = byteArrayOf(0x53, 0x45, 0x47, 0x41)
|
||||||
|
header.sliceArray(segaIdentifier.indices).contentEquals(segaIdentifier)
|
||||||
|
}
|
||||||
|
}.getOrElse { false }
|
||||||
|
|
||||||
// Function to check if a file is likely a macro based on scripting patterns found in samples
|
// Function to check if a file is likely a macro based on scripting patterns found in samples
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
|||||||
@@ -38,18 +38,41 @@ object LocaleUtils {
|
|||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
context.getSystemService(LocaleManager::class.java).applicationLocales = LocaleList.getEmptyLocaleList()
|
context.getSystemService(LocaleManager::class.java).applicationLocales = LocaleList.getEmptyLocaleList()
|
||||||
} else {
|
} else {
|
||||||
setLocale(context, getSystemLocale())
|
setLocale(context, getPrimarySystemLocale())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@Deprecated("Use getSystemLocaleList instead", ReplaceWith("getPrimarySystemLocale()"))
|
||||||
fun getSystemLocale(): Locale = Resources.getSystem().configuration.locales[0] ?: Locale.getDefault()
|
fun getSystemLocale(): Locale = Resources.getSystem().configuration.locales[0] ?: Locale.getDefault()
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun getSystemLocaleList(context: Context? = null): List<Locale> {
|
||||||
|
return when {
|
||||||
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> {
|
||||||
|
val localeManager = (context ?: GlobalAppContext.get()).getSystemService(LocaleManager::class.java)
|
||||||
|
val localeList: LocaleList = localeManager.systemLocales
|
||||||
|
List(localeList.size()) { index -> localeList[index] }
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
val localeList = Resources.getSystem().configuration.locales
|
||||||
|
List(localeList.size()) { index -> localeList[index] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun getPrimarySystemLocale(context: Context? = null): Locale {
|
||||||
|
return getSystemLocaleList(context).firstOrNull() ?: Locale.getDefault()
|
||||||
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getResources(desiredLocale: Locale?): Resources {
|
fun getResources(desiredLocale: Locale?): Resources {
|
||||||
return GlobalAppContext.get().let { context ->
|
return GlobalAppContext.get().let { context ->
|
||||||
context.resources.configuration.let { Configuration(it) }.run {
|
context.resources.configuration.let { Configuration(it) }.run {
|
||||||
setLocale(desiredLocale ?: getSystemLocale())
|
setLocale(desiredLocale ?: getPrimarySystemLocale())
|
||||||
context.createConfigurationContext(this).resources
|
context.createConfigurationContext(this).resources
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,25 @@
|
|||||||
package org.autojs.autojs.util;
|
package org.autojs.autojs.util
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Stardust on Nov 26, 2017.
|
* Created by Stardust on Nov 26, 2017.
|
||||||
|
* Transformed by SuperMonster003 on Mar 5, 2026.
|
||||||
|
* Modified by SuperMonster003 as of Mar 5, 2026.
|
||||||
*/
|
*/
|
||||||
public class MathUtils {
|
object MathUtils {
|
||||||
|
|
||||||
public static int min(int... ints) {
|
@JvmStatic
|
||||||
int min = ints[0];
|
fun min(vararg ints: Int): Int =
|
||||||
for (int i = 1; i < ints.length; i++) {
|
ints.minOrNull() ?: throw NoSuchElementException("Array is empty")
|
||||||
min = Math.min(ints[i], min);
|
|
||||||
}
|
@JvmStatic
|
||||||
return min;
|
fun Int.floorMod(mod: Int): Int =
|
||||||
}
|
Math.floorMod(this, mod)
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun Long.floorMod(mod: Long): Long =
|
||||||
|
Math.floorMod(this, mod)
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun Long.floorMod(mod: Int): Int =
|
||||||
|
Math.floorMod(this, mod)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.ThemeColorRecyclerView
|
||||||
android:id="@+id/apps"
|
android:id="@+id/apps"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.ThemeColorRecyclerView
|
||||||
android:id="@+id/recycler"
|
android:id="@+id/recycler"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
android:layout_marginTop="6dp"
|
android:layout_marginTop="6dp"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.ThemeColorRecyclerView
|
||||||
android:id="@+id/recycler_view"
|
android:id="@+id/recycler_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|||||||
@@ -105,7 +105,7 @@
|
|||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1">
|
android:layout_weight="1">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.ThemeColorRecyclerView
|
||||||
android:id="@+id/recycler"
|
android:id="@+id/recycler"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
tools:visibility="gone"
|
tools:visibility="gone"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.ThemeColorRecyclerView
|
||||||
android:id="@+id/recycler_view"
|
android:id="@+id/recycler_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
tools:visibility="gone"
|
tools:visibility="gone"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.ThemeColorRecyclerView
|
||||||
android:id="@+id/recycler_view"
|
android:id="@+id/recycler_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
android:background="@drawable/little_triangle" />
|
android:background="@drawable/little_triangle" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.ThemeColorRecyclerView
|
||||||
android:id="@+id/list"
|
android:id="@+id/list"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
android:animateLayoutChanges="true"
|
android:animateLayoutChanges="true"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.ThemeColorRecyclerView
|
||||||
android:id="@+id/log_list"
|
android:id="@+id/log_list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
android:animateLayoutChanges="true"
|
android:animateLayoutChanges="true"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.ThemeColorRecyclerView
|
||||||
android:id="@+id/log_list"
|
android:id="@+id/log_list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
app:tint="@android:color/white" />
|
app:tint="@android:color/white" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.ThemeColorRecyclerView
|
||||||
android:id="@+id/variables"
|
android:id="@+id/variables"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.ThemeColorRecyclerView
|
||||||
android:id="@+id/result_list"
|
android:id="@+id/result_list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="400dp" />
|
android:layout_height="400dp" />
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.ThemeColorRecyclerView
|
||||||
android:id="@+id/list"
|
android:id="@+id/list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"/>
|
android:layout_height="match_parent"/>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
app:cardElevation="0.97dp"
|
app:cardElevation="0.97dp"
|
||||||
app:cardUseCompatPadding="true" />
|
app:cardUseCompatPadding="true" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.ThemeColorRecyclerView
|
||||||
android:id="@+id/explorer_item_list"
|
android:id="@+id/explorer_item_list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
android:importantForAccessibility="no"
|
android:importantForAccessibility="no"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.ThemeColorRecyclerView
|
||||||
android:id="@+id/drawer_menu"
|
android:id="@+id/drawer_menu"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
android:background="@color/divider_functions_keyboard" />
|
android:background="@color/divider_functions_keyboard" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.ThemeColorRecyclerView
|
||||||
android:id="@+id/properties"
|
android:id="@+id/properties"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
android:background="@color/divider_functions_keyboard" />
|
android:background="@color/divider_functions_keyboard" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.ThemeColorRecyclerView
|
||||||
android:id="@+id/module_list"
|
android:id="@+id/module_list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="50dp" />
|
android:layout_height="50dp" />
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ public class MDTintHelper {
|
|||||||
fCursorDrawable.set(editor, drawables);
|
fCursorDrawable.set(editor, drawables);
|
||||||
} catch (NoSuchFieldException e1) {
|
} catch (NoSuchFieldException e1) {
|
||||||
Log.d("MDTintHelper", "Device issue with cursor tinting: " + e1.getMessage());
|
Log.d("MDTintHelper", "Device issue with cursor tinting: " + e1.getMessage());
|
||||||
e1.printStackTrace();
|
// e1.printStackTrace();
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
e2.printStackTrace();
|
e2.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user