6.6.2 - Alpha5 - 主题色设置页面新布局支持显示颜色详情
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
package org.autojs.autojs.extension
|
||||
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import org.autojs.autojs.util.ClipboardUtils
|
||||
import org.autojs.autojs.util.IntentUtils
|
||||
import org.autojs.autojs.util.ViewUtils
|
||||
import org.autojs.autojs6.R
|
||||
|
||||
object MaterialDialogExtensions {
|
||||
|
||||
fun MaterialDialog.makeSettingsLaunchable(viewGetter: (dialog: MaterialDialog) -> View?, packageName: String?) {
|
||||
viewGetter(this)?.setOnClickListener {
|
||||
packageName?.let { pkg ->
|
||||
IntentUtils.goToAppDetailSettings(this.context, pkg)
|
||||
} ?: ViewUtils.showSnack(this.view, R.string.error_app_not_installed)
|
||||
}
|
||||
}
|
||||
|
||||
fun MaterialDialog.makeTextCopyable(textViewGetter: (dialog: MaterialDialog) -> TextView?) {
|
||||
makeTextCopyable(textViewGetter(this))
|
||||
}
|
||||
|
||||
fun MaterialDialog.makeTextCopyable(textView: TextView?, textValue: String? = textView?.text?.toString()) {
|
||||
if (textValue != null) {
|
||||
val context = this.context
|
||||
textView?.setOnClickListener {
|
||||
ClipboardUtils.setClip(context, textValue)
|
||||
ViewUtils.showSnack(this.view, "${context.getString(R.string.text_already_copied_to_clip)}: $textValue")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun TextView.setCopyableTextIfAbsent(dialog: MaterialDialog, f: () -> String?) {
|
||||
val textView = this
|
||||
val textValue = f.invoke()
|
||||
if (textView.text == context.getString(R.string.ellipsis_six)) {
|
||||
textView.text = textValue.takeUnless { it.isNullOrBlank() } ?: context.getString(R.string.text_unknown)
|
||||
}
|
||||
dialog.makeTextCopyable(textView, textValue)
|
||||
}
|
||||
|
||||
fun TextView.setCopyableText(dialog: MaterialDialog, f: () -> String?) {
|
||||
val textView = this
|
||||
val textValue = f.invoke()
|
||||
textView.text = textValue.takeUnless { it.isNullOrBlank() } ?: context.getString(R.string.text_unknown)
|
||||
dialog.makeTextCopyable(textView, textValue)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,14 +26,4 @@ object NumberExtensions {
|
||||
.toPlainString()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun Double.roundToAlphaString(scale: Int = 2, keepTrailingZeroForFullAlpha: Boolean = true): String {
|
||||
return toBigDecimal()
|
||||
.setScale(scale, RoundingMode.HALF_UP)
|
||||
.stripTrailingZeros()
|
||||
.toPlainString()
|
||||
.let { if (keepTrailingZeroForFullAlpha && it == "1") "1.0" else it }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -59,5 +59,4 @@ object StringExtensions {
|
||||
else -> false
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -19,8 +19,6 @@ import org.autojs.autojs.extension.ArrayExtensions.toNativeArray
|
||||
import org.autojs.autojs.extension.ArrayExtensions.toNativeObject
|
||||
import org.autojs.autojs.extension.FlexibleArray.Companion.component1
|
||||
import org.autojs.autojs.extension.FlexibleArray.Companion.component2
|
||||
import org.autojs.autojs.extension.NumberExtensions.jsString
|
||||
import org.autojs.autojs.extension.NumberExtensions.roundToAlphaString
|
||||
import org.autojs.autojs.extension.ScriptableExtensions.prop
|
||||
import org.autojs.autojs.extension.ScriptableObjectExtensions.inquire
|
||||
import org.autojs.autojs.runtime.api.augment.Augmentable
|
||||
@@ -30,6 +28,10 @@ import org.autojs.autojs.runtime.exception.ShouldNeverHappenException
|
||||
import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
|
||||
import org.autojs.autojs.theme.ThemeColor
|
||||
import org.autojs.autojs.util.ColorUtils
|
||||
import org.autojs.autojs.util.ColorUtils.roundToAlphaString
|
||||
import org.autojs.autojs.util.ColorUtils.roundToHueString
|
||||
import org.autojs.autojs.util.ColorUtils.roundToSaturationString
|
||||
import org.autojs.autojs.util.ColorUtils.roundToValueString
|
||||
import org.autojs.autojs.util.RhinoUtils.coerceBoolean
|
||||
import org.autojs.autojs.util.RhinoUtils.ensureNativeArrayLength
|
||||
import org.autojs.autojs.util.RhinoUtils.newNativeObject
|
||||
@@ -129,11 +131,11 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
::toHsla.name,
|
||||
::toRgbString.name,
|
||||
::toRgbaString.name,
|
||||
// ::toArgbString.name,
|
||||
// ::toHsvString.name,
|
||||
// ::toHsvaString.name,
|
||||
// ::toHslString.name,
|
||||
// ::toHslaString.name,
|
||||
::toArgbString.name,
|
||||
::toHsvString.name,
|
||||
::toHsvaString.name,
|
||||
::toHslString.name,
|
||||
::toHslaString.name,
|
||||
::isSimilar.name,
|
||||
::isEqual.name,
|
||||
::toColorStateList.name,
|
||||
@@ -626,10 +628,10 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - red: ColorComponent <br>
|
||||
* - green: ColorComponent <br>
|
||||
* - blue: ColorComponent <br>
|
||||
* Parameters
|
||||
* * red: `ColorComponent`
|
||||
* * green: `ColorComponent`
|
||||
* * blue: `ColorComponent`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -639,9 +641,9 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - o <1> rgbComponents: [ColorComponent, ColorComponent, ColorComponent] <br>
|
||||
* - o <2> color: OmniColor <br>
|
||||
* Parameters
|
||||
* * o <1> rgbComponents: `[ColorComponent, ColorComponent, ColorComponent]`
|
||||
* * o <2> color: `OmniColor`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -664,11 +666,11 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - alpha: ColorComponent <br>
|
||||
* - red: ColorComponent <br>
|
||||
* - green: ColorComponent <br>
|
||||
* - blue: ColorComponent <br>
|
||||
* Parameters
|
||||
* * alpha: `ColorComponent`
|
||||
* * red: `ColorComponent`
|
||||
* * green: `ColorComponent`
|
||||
* * blue: `ColorComponent`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -678,9 +680,9 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - o <1> argbComponents: [ColorComponent, ColorComponent, ColorComponent, ColorComponent] <br>
|
||||
* - o <2> colorHex: String (#AARRGGBB) <br>
|
||||
* Parameters
|
||||
* * o <1> argbComponents: `[ColorComponent, ColorComponent, ColorComponent, ColorComponent]`
|
||||
* * o <2> colorHex: `String` (#AARRGGBB)
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -704,11 +706,11 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - red: ColorComponent <br>
|
||||
* - green: ColorComponent <br>
|
||||
* - blue: ColorComponent <br>
|
||||
* - alpha: ColorComponent <br>
|
||||
* Parameters
|
||||
* * red: `ColorComponent`
|
||||
* * green: `ColorComponent`
|
||||
* * blue: `ColorComponent`
|
||||
* * alpha: `ColorComponent`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -718,9 +720,9 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - rgbComponents: [ColorComponent, ColorComponent, ColorComponent] <br>
|
||||
* - alpha: ColorComponent <br>
|
||||
* Parameters
|
||||
* * rgbComponents: `[ColorComponent, ColorComponent, ColorComponent]`
|
||||
* * alpha: `ColorComponent`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -731,9 +733,9 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - o <1> rgbaComponents: [ColorComponent, ColorComponent, ColorComponent, ColorComponent] <br>
|
||||
* - o <2> colorHex: String (#RRGGBBAA) <br>
|
||||
* Parameters
|
||||
* * o <1> rgbaComponents: `[ColorComponent, ColorComponent, ColorComponent, ColorComponent]`
|
||||
* * o <2> colorHex: `String` (#RRGGBBAA)
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -761,10 +763,10 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - h: ColorComponent <br>
|
||||
* - s: ColorComponent <br>
|
||||
* - v: ColorComponent <br>
|
||||
* Parameters
|
||||
* * h: `ColorComponent`
|
||||
* * s: `ColorComponent`
|
||||
* * v: `ColorComponent`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -774,8 +776,8 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - hsvComponents: [ColorComponent, ColorComponent, ColorComponent] <br>
|
||||
* Parameters
|
||||
* * hsvComponents: `[ColorComponent, ColorComponent, ColorComponent]`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -797,11 +799,11 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - h: ColorComponent <br>
|
||||
* - s: ColorComponent <br>
|
||||
* - v: ColorComponent <br>
|
||||
* - a: ColorComponent <br>
|
||||
* Parameters
|
||||
* * h: `ColorComponent`
|
||||
* * s: `ColorComponent`
|
||||
* * v: `ColorComponent`
|
||||
* * a: `ColorComponent`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -811,9 +813,9 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - hsvComponents: [ColorComponent, ColorComponent, ColorComponent] <br>
|
||||
* - alpha: ColorComponent <br>
|
||||
* Parameters
|
||||
* * hsvComponents: `[ColorComponent, ColorComponent, ColorComponent]`
|
||||
* * alpha: `ColorComponent`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -824,8 +826,8 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - hsvaComponents: [ColorComponent, ColorComponent, ColorComponent, ColorComponent] <br>
|
||||
* Parameters
|
||||
* * hsvaComponents: `[ColorComponent, ColorComponent, ColorComponent, ColorComponent]`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -846,10 +848,10 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - h: ColorComponent <br>
|
||||
* - s: ColorComponent <br>
|
||||
* - l: ColorComponent <br>
|
||||
* Parameters
|
||||
* * h: `ColorComponent`
|
||||
* * s: `ColorComponent`
|
||||
* * l: `ColorComponent`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -859,8 +861,8 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - hslComponents: [ColorComponent, ColorComponent, ColorComponent] <br>
|
||||
* Parameters
|
||||
* * hslComponents: `[ColorComponent, ColorComponent, ColorComponent]`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -882,11 +884,11 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - h: ColorComponent <br>
|
||||
* - s: ColorComponent <br>
|
||||
* - l: ColorComponent <br>
|
||||
* - a: ColorComponent <br>
|
||||
* Parameters
|
||||
* * h: `ColorComponent`
|
||||
* * s: `ColorComponent`
|
||||
* * l: `ColorComponent`
|
||||
* * a: `ColorComponent`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -896,9 +898,9 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - hslComponents: [ColorComponent, ColorComponent, ColorComponent] <br>
|
||||
* - alpha: ColorComponent <br>
|
||||
* Parameters
|
||||
* * hslComponents: `[ColorComponent, ColorComponent, ColorComponent]`
|
||||
* * alpha: `ColorComponent`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -909,8 +911,8 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - hslaComponents: [ColorComponent, ColorComponent, ColorComponent, ColorComponent] <br>
|
||||
* Parameters
|
||||
* * hslaComponents: `[ColorComponent, ColorComponent, ColorComponent, ColorComponent]`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -987,8 +989,8 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - color: OmniColor <br>
|
||||
* Parameters
|
||||
* * color: `OmniColor`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -997,9 +999,9 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - color: OmniColor <br>
|
||||
* - hsvResultContainer: java.lang.Float[] <br>
|
||||
* Parameters
|
||||
* * color: `OmniColor`
|
||||
* * hsvResultContainer: `java.lang.Float[]`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -1015,10 +1017,10 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - r: ColorComponent <br>
|
||||
* - g: ColorComponent <br>
|
||||
* - b: ColorComponent <br>
|
||||
* Parameters
|
||||
* * r: `ColorComponent`
|
||||
* * g: `ColorComponent`
|
||||
* * b: `ColorComponent`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -1027,11 +1029,11 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - r: ColorComponent <br>
|
||||
* - g: ColorComponent <br>
|
||||
* - b: ColorComponent <br>
|
||||
* - hsvResultContainer: java.lang.Float[] <br>
|
||||
* Parameters
|
||||
* * r: `ColorComponent`
|
||||
* * g: `ColorComponent`
|
||||
* * b: `ColorComponent`
|
||||
* * hsvResultContainer: `java.lang.Float[]`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -1053,24 +1055,24 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - color: OmniColor <br>
|
||||
* Parameters
|
||||
* * color: `OmniColor`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
fun toHsvaRhino(color: Any?): List<Double> {
|
||||
return toHsvaRhino(color, FloatArray(3))
|
||||
return toHsvaRhino(color, FloatArray(4))
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - color: OmniColor <br>
|
||||
* - hsvaResultContainer: java.lang.Float[] <br>
|
||||
* Parameters
|
||||
* * color: `OmniColor`
|
||||
* * hsvaResultContainer: `java.lang.Float[]`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
fun toHsvaRhino(color: Any?, hsvaResultContainer: Any?): List<Double> {
|
||||
require(hsvaResultContainer is FloatArray) { "Container argument \"hsvaResultContainer\" must be a Java Float Array for colors.toHsva(r, g, b, a, hsvResultContainer)" }
|
||||
require(hsvaResultContainer is FloatArray) { "Container argument \"hsvaResultContainer\" must be a Java Float Array for colors.toHsva(color, hsvResultContainer)" }
|
||||
val r = redRhino(color)
|
||||
val g = greenRhino(color)
|
||||
val b = blueRhino(color)
|
||||
@@ -1083,11 +1085,11 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - r: ColorComponent <br>
|
||||
* - g: ColorComponent <br>
|
||||
* - b: ColorComponent <br>
|
||||
* - a: ColorComponent <br>
|
||||
* Parameters
|
||||
* * r: `ColorComponent`
|
||||
* * g: `ColorComponent`
|
||||
* * b: `ColorComponent`
|
||||
* * a: `ColorComponent`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -1096,12 +1098,12 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - r: ColorComponent <br>
|
||||
* - g: ColorComponent <br>
|
||||
* - b: ColorComponent <br>
|
||||
* - a: ColorComponent <br>
|
||||
* - hsvaResultContainer: java.lang.Float[] <br>
|
||||
* Parameters
|
||||
* * r: `ColorComponent`
|
||||
* * g: `ColorComponent`
|
||||
* * b: `ColorComponent`
|
||||
* * a: `ColorComponent`
|
||||
* * hsvaResultContainer: `java.lang.Float[]`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -1123,8 +1125,8 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - color: OmniColor <br>
|
||||
* Parameters
|
||||
* * color: `OmniColor`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -1133,9 +1135,9 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - color: OmniColor <br>
|
||||
* - hslResultContainer: java.lang.Float[] <br>
|
||||
* Parameters
|
||||
* * color: `OmniColor`
|
||||
* * hslResultContainer: `java.lang.Float[]`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -1151,10 +1153,10 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - r: ColorComponent <br>
|
||||
* - g: ColorComponent <br>
|
||||
* - b: ColorComponent <br>
|
||||
* Parameters
|
||||
* * r: `ColorComponent`
|
||||
* * g: `ColorComponent`
|
||||
* * b: `ColorComponent`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -1163,11 +1165,11 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - r: ColorComponent <br>
|
||||
* - g: ColorComponent <br>
|
||||
* - b: ColorComponent <br>
|
||||
* - hslResultContainer: java.lang.Float[] <br>
|
||||
* Parameters
|
||||
* * r: `ColorComponent`
|
||||
* * g: `ColorComponent`
|
||||
* * b: `ColorComponent`
|
||||
* * hslResultContainer: `java.lang.Float[]`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -1187,8 +1189,8 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - color: OmniColor <br>
|
||||
* Parameters
|
||||
* * color: `OmniColor`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -1197,11 +1199,11 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters <br>
|
||||
* - r: ColorComponent <br>
|
||||
* - g: ColorComponent <br>
|
||||
* - b: ColorComponent <br>
|
||||
* - a: ColorComponent <br>
|
||||
* Parameters
|
||||
* * r: `ColorComponent`
|
||||
* * g: `ColorComponent`
|
||||
* * b: `ColorComponent`
|
||||
* * a: `ColorComponent`
|
||||
*/
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
@@ -1353,12 +1355,9 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
fun summaryRhino(color: Any?): String {
|
||||
var (r, g, b, a) = toRgbaRhino(color)
|
||||
return when (val doubleA = toDoubleComponent(a)) {
|
||||
1.0 -> "Color { ${toHexRhino(color)} | rgb(${r.jsString}, ${g.jsString}, ${b.jsString}) | int(${toIntRhino(color)}) }"
|
||||
else -> "Color { ${toHexRhino(color)} | rgba(${r.jsString}, ${g.jsString}, ${b.jsString}, ${doubleA.roundToAlphaString()}) | int(${toIntRhino(color)}) }"
|
||||
}
|
||||
fun summaryRhino(color: Any?): String = when (alphaDoubleRhino(color)) {
|
||||
1.0 -> "Color { ${toHexRhino(color)} | ${toRgbStringRhino(color)} | ${toHslStringRhino(color)} | ${toHsvStringRhino(color)} | int(${toIntRhino(color)}) }"
|
||||
else -> "Color { ${toHexRhino(color)} | ${toRgbaString(arrayOf(color))} | ${toHslaString(arrayOf(color))} | ${toHsvaString(arrayOf(color))} | int(${toIntRhino(color)}) }"
|
||||
}
|
||||
|
||||
internal fun parseRelativePercentage(percentage: Any?): Double {
|
||||
@@ -1474,75 +1473,135 @@ object Colors : Augmentable(), SimpleGetterProxy {
|
||||
fun toRgbaString(args: Array<out Any?>): String = ensureArgumentsAtMost(args, 2) { argList ->
|
||||
val (color, options) = argList
|
||||
|
||||
var keepTrailingZeroForFullAlpha = true
|
||||
|
||||
when (options) {
|
||||
is NativeObject -> {
|
||||
options.inquire<Boolean>("keepTrailingZeroForFullAlpha", ::coerceBoolean)?.let {
|
||||
keepTrailingZeroForFullAlpha = it
|
||||
}
|
||||
}
|
||||
is Boolean -> {
|
||||
keepTrailingZeroForFullAlpha = options
|
||||
}
|
||||
val keepTrailingZeroForFullAlpha = when (options) {
|
||||
is NativeObject -> options.inquire<Boolean>("keepTrailingZeroForFullAlpha", ::coerceBoolean) != false
|
||||
is Boolean -> options
|
||||
else -> true
|
||||
}
|
||||
|
||||
val list = listOf(redRhino(color), greenRhino(color), blueRhino(color)).map {
|
||||
it.roundToInt().coerceIn(0..255).toString()
|
||||
} + alphaDoubleRhino(color).roundToAlphaString(2, keepTrailingZeroForFullAlpha)
|
||||
} + alphaDoubleRhino(color).roundToAlphaString(keepTrailingZeroForFullAlpha = keepTrailingZeroForFullAlpha)
|
||||
|
||||
list.joinToString(", ", prefix = "rgba(", postfix = ")")
|
||||
}
|
||||
|
||||
// // 格式化 argb 格式为 "argb(a, r, g, b)"
|
||||
// fun toArgbString(color: Int): String {
|
||||
// val arr = rawToArgb(color)
|
||||
// return "argb(${arr[0]}, ${arr[1]}, ${arr[2]}, ${arr[3]})"
|
||||
// }
|
||||
//
|
||||
// // 格式化 hsv 格式为 "hsv(h, s%, v%)",其中 h 取整,s 和 v 转换为百分比(整数)
|
||||
// fun toHsvString(color: Int): String {
|
||||
// val arr = rawToHsv(color)
|
||||
// val h = arr[0].roundToInt()
|
||||
// val s = (arr[1] * 100).roundToInt()
|
||||
// val v = (arr[2] * 100).roundToInt()
|
||||
// return "hsv($h, ${s}%, ${v}%)"
|
||||
// }
|
||||
//
|
||||
// // 格式化 hsva 格式为 "hsva(h, s%, v%, a)",其中 a 保留两位小数(或整数)
|
||||
// fun toHsvaString(color: Int): String {
|
||||
// val arr = rawToHsva(color)
|
||||
// val h = arr[0].roundToInt()
|
||||
// val s = (arr[1] * 100).roundToInt()
|
||||
// val v = (arr[2] * 100).roundToInt()
|
||||
// val a = arr[3]
|
||||
// val aStr = if (a % 1.0 == 0.0)
|
||||
// a.roundToInt().toString()
|
||||
// else
|
||||
// String.format("%.2f", a)
|
||||
// return "hsva($h, ${s}%, ${v}%, $aStr)"
|
||||
// }
|
||||
//
|
||||
// // 格式化 hsl 格式为 "hsl(h, s%, l%)"
|
||||
// fun toHslString(color: Int): String {
|
||||
// val arr = rawToHsl(color)
|
||||
// val h = arr[0].roundToInt()
|
||||
// val s = (arr[1] * 100).roundToInt()
|
||||
// val l = (arr[2] * 100).roundToInt()
|
||||
// return "hsl($h, ${s}%, ${l}%)"
|
||||
// }
|
||||
//
|
||||
// // 格式化 hsla 格式为 "hsla(h, s%, l%, a)"
|
||||
// fun toHslaString(color: Int): String {
|
||||
// val arr = rawToHsla(color)
|
||||
// val h = arr[0].roundToInt()
|
||||
// val s = (arr[1] * 100).roundToInt()
|
||||
// val l = (arr[2] * 100).roundToInt()
|
||||
// val a = arr[3]
|
||||
// val aStr = if (a % 1.0 == 0.0)
|
||||
// a.roundToInt().toString()
|
||||
// else
|
||||
// String.format("%.2f", a)
|
||||
// return "hsla($h, ${s}%, ${l}%, $aStr)"
|
||||
// }
|
||||
@JvmStatic
|
||||
@RhinoSingletonFunctionInterface
|
||||
fun toArgbString(args: Array<out Any?>): String = ensureArgumentsAtMost(args, 2) { argList ->
|
||||
val (color, options) = argList
|
||||
|
||||
val keepTrailingZeroForFullAlpha = when (options) {
|
||||
is NativeObject -> options.inquire<Boolean>("keepTrailingZeroForFullAlpha", ::coerceBoolean) != false
|
||||
is Boolean -> options
|
||||
else -> true
|
||||
}
|
||||
|
||||
val list = listOf(
|
||||
alphaDoubleRhino(color).roundToAlphaString(keepTrailingZeroForFullAlpha = keepTrailingZeroForFullAlpha)
|
||||
) + listOf(redRhino(color), greenRhino(color), blueRhino(color)).map {
|
||||
it.roundToInt().coerceIn(0..255).toString()
|
||||
}
|
||||
|
||||
list.joinToString(", ", prefix = "argb(", postfix = ")")
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@RhinoSingletonFunctionInterface
|
||||
fun toHsvString(args: Array<out Any?>): String = ensureArgumentsLengthInRange(args, 1..3) {
|
||||
when (it.size) {
|
||||
1 -> toHsvStringRhino(it[0])
|
||||
3 -> toHsvStringRhino(it[0], it[1], it[2])
|
||||
else -> throw WrappedIllegalArgumentException("Invalid arguments ${it.jsArrayBrief()} for colors.toHsvString")
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
fun toHsvStringRhino(color: Any?): String {
|
||||
val (r, g, b) = toRgbRhino(color)
|
||||
return toHsvStringRhino(r, g, b)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
fun toHsvStringRhino(r: Any?, g: Any?, b: Any?): String {
|
||||
val (hue, saturation, value) = toHsvRhino(r, g, b)
|
||||
return listOf(
|
||||
hue.roundToHueString(),
|
||||
saturation.roundToSaturationString(),
|
||||
value.roundToValueString(),
|
||||
).joinToString(", ", prefix = "hsv(", postfix = ")")
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@RhinoSingletonFunctionInterface
|
||||
fun toHsvaString(args: Array<out Any?>): String = ensureArgumentsAtMost(args, 2) { argList ->
|
||||
val (color, options) = argList
|
||||
val (hue, saturation, value) = toHsvRhino(color)
|
||||
|
||||
val keepTrailingZeroForFullAlpha = when (options) {
|
||||
is NativeObject -> options.inquire<Boolean>("keepTrailingZeroForFullAlpha", ::coerceBoolean) != false
|
||||
is Boolean -> options
|
||||
else -> true
|
||||
}
|
||||
|
||||
val list = listOf(
|
||||
hue.roundToHueString(),
|
||||
saturation.roundToSaturationString(),
|
||||
value.roundToValueString(),
|
||||
) + alphaDoubleRhino(color).roundToAlphaString(keepTrailingZeroForFullAlpha = keepTrailingZeroForFullAlpha)
|
||||
|
||||
list.joinToString(", ", prefix = "hsva(", postfix = ")")
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@RhinoSingletonFunctionInterface
|
||||
fun toHslString(args: Array<out Any?>): String = ensureArgumentsLengthInRange(args, 1..3) {
|
||||
when (it.size) {
|
||||
1 -> toHslStringRhino(it[0])
|
||||
3 -> toHslStringRhino(it[0], it[1], it[2])
|
||||
else -> throw WrappedIllegalArgumentException("Invalid arguments ${it.jsArrayBrief()} for colors.toHslString")
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
fun toHslStringRhino(color: Any?): String {
|
||||
val (r, g, b) = toRgbRhino(color)
|
||||
return toHslStringRhino(r, g, b)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@RhinoFunctionBody
|
||||
fun toHslStringRhino(r: Any?, g: Any?, b: Any?): String {
|
||||
val (hue, saturation, lightness) = toHslRhino(r, g, b)
|
||||
return listOf(
|
||||
hue.roundToHueString(),
|
||||
saturation.roundToSaturationString(),
|
||||
lightness.roundToValueString(),
|
||||
).joinToString(", ", prefix = "hsl(", postfix = ")")
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@RhinoSingletonFunctionInterface
|
||||
fun toHslaString(args: Array<out Any?>): String = ensureArgumentsAtMost(args, 2) { argList ->
|
||||
val (color, options) = argList
|
||||
val (hue, saturation, lightness) = toHslRhino(color)
|
||||
|
||||
val keepTrailingZeroForFullAlpha = when (options) {
|
||||
is NativeObject -> options.inquire<Boolean>("keepTrailingZeroForFullAlpha", ::coerceBoolean) != false
|
||||
is Boolean -> options
|
||||
else -> true
|
||||
}
|
||||
|
||||
val list = listOf(
|
||||
hue.roundToHueString(),
|
||||
saturation.roundToSaturationString(),
|
||||
lightness.roundToValueString(),
|
||||
) + alphaDoubleRhino(color).roundToAlphaString(keepTrailingZeroForFullAlpha = keepTrailingZeroForFullAlpha)
|
||||
|
||||
list.joinToString(", ", prefix = "hsla(", postfix = ")")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package org.autojs.autojs.theme.app
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View.MeasureSpec.UNSPECIFIED
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.isVisible
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.autojs.autojs.extension.MaterialDialogExtensions.setCopyableText
|
||||
import org.autojs.autojs.runtime.api.augment.colors.Colors
|
||||
import org.autojs.autojs.util.ColorUtils
|
||||
import org.autojs.autojs6.R
|
||||
import org.autojs.autojs6.databinding.ColorInfoDialogListItemBinding
|
||||
|
||||
object ColorInfoDialogManager {
|
||||
|
||||
@JvmStatic
|
||||
fun showColorInfoDialog(context: Context, @ColorInt color: Int, titleRes: Int = R.string.dialog_title_color_details) {
|
||||
val binding = ColorInfoDialogListItemBinding.inflate(LayoutInflater.from(context))
|
||||
|
||||
val colorWithoutAlpha = color or -0x1000000
|
||||
|
||||
val dialog = MaterialDialog.Builder(context)
|
||||
.title(titleRes)
|
||||
.customView(binding.root, false)
|
||||
.positiveText(R.string.dialog_button_dismiss)
|
||||
.positiveColorRes(R.color.dialog_button_default)
|
||||
.show()
|
||||
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
launch(Dispatchers.IO) {
|
||||
ColorUtils.toHex(colorWithoutAlpha).let { binding.colorHexValue.bindWith(dialog, it) }
|
||||
Colors.toRgbStringRhino(colorWithoutAlpha).let { binding.colorRgbValue.bindWith(dialog, it) }
|
||||
Colors.toHslStringRhino(colorWithoutAlpha).let { binding.colorHslValue.bindWith(dialog, it) }
|
||||
Colors.toHsvStringRhino(colorWithoutAlpha).let { binding.colorHsvValue.bindWith(dialog, it) }
|
||||
ColorUtils.toInt(colorWithoutAlpha).let { binding.colorIntValue.bindWith(dialog, it.toString()) }
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
restoreEssentialViews(binding)
|
||||
updateGuidelines(binding)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun restoreEssentialViews(binding: ColorInfoDialogListItemBinding) {
|
||||
listOf(
|
||||
binding.colorHexColon to binding.colorHexValue,
|
||||
binding.colorRgbColon to binding.colorRgbValue,
|
||||
binding.colorHslColon to binding.colorHslValue,
|
||||
binding.colorHsvColon to binding.colorHsvValue,
|
||||
binding.colorIntColon to binding.colorIntValue,
|
||||
).forEach { pair ->
|
||||
val (colonView, valueView) = pair
|
||||
colonView.isVisible = true
|
||||
valueView.isVisible = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateGuidelines(binding: ColorInfoDialogListItemBinding) {
|
||||
val filteredBindings = listOf(
|
||||
binding.colorHexLabel to binding.colorHexGuideline,
|
||||
binding.colorRgbLabel to binding.colorRgbGuideline,
|
||||
binding.colorHslLabel to binding.colorHslGuideline,
|
||||
binding.colorHsvLabel to binding.colorHsvGuideline,
|
||||
binding.colorIntLabel to binding.colorIntGuideline,
|
||||
).filter { (it.first.parent as? ConstraintLayout)?.isVisible == true }
|
||||
|
||||
val maxWidth = filteredBindings.maxOfOrNull { it.first.apply { measure(UNSPECIFIED, UNSPECIFIED) }.measuredWidth } ?: return
|
||||
|
||||
filteredBindings.forEach { (_, guideline) ->
|
||||
guideline.layoutParams = (guideline.layoutParams as ConstraintLayout.LayoutParams).also {
|
||||
it.guideBegin = maxWidth
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun TextView.bindWith(dialog: MaterialDialog, text: String) {
|
||||
withContext(Dispatchers.Main) {
|
||||
this@bindWith.setCopyableText(dialog) { text }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -50,8 +50,11 @@ class ColorLibrariesActivity : ColorSelectBaseActivity() {
|
||||
MtActivityColorLibrariesBinding.inflate(layoutInflater).let {
|
||||
binding = it
|
||||
setContentView(it.root)
|
||||
setUpToolbar(it.toolbar)
|
||||
setUpAppBar(it.appBar, it.appBarContainer)
|
||||
it.toolbar.let { toolbar ->
|
||||
setUpToolbar(toolbar)
|
||||
toolbar.setOnLongClickListener { true.also { showThemeColorDetails() } }
|
||||
}
|
||||
}
|
||||
|
||||
binding.colorLibrariesRecyclerView.let {
|
||||
@@ -120,15 +123,15 @@ class ColorLibrariesActivity : ColorSelectBaseActivity() {
|
||||
true
|
||||
}
|
||||
R.id.action_new_color_library -> {
|
||||
ViewUtils.showToast(this, R.string.text_under_development_title)
|
||||
ViewUtils.showToast(this, R.string.text_under_development)
|
||||
true
|
||||
}
|
||||
R.id.action_import_color_library -> {
|
||||
ViewUtils.showToast(this, R.string.text_under_development_title)
|
||||
ViewUtils.showToast(this, R.string.text_under_development)
|
||||
true
|
||||
}
|
||||
R.id.action_clone_color_library -> {
|
||||
ViewUtils.showToast(this, R.string.text_under_development_title)
|
||||
ViewUtils.showToast(this, R.string.text_under_development)
|
||||
true
|
||||
}
|
||||
R.id.action_locate_current_theme_color -> {
|
||||
|
||||
@@ -4,15 +4,17 @@ import android.annotation.SuppressLint
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import org.autojs.autojs.theme.app.ColorLibrariesActivity.Companion.PresetColorLibrary
|
||||
import org.autojs.autojs6.R
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
class ColorLibraryAdapter(
|
||||
private var libraries: List<ColorLibrariesActivity.Companion.PresetColorLibrary>,
|
||||
private val onItemClick: (ColorLibrariesActivity.Companion.PresetColorLibrary) -> Unit,
|
||||
private var libraries: List<PresetColorLibrary>,
|
||||
private val onItemClick: (PresetColorLibrary) -> Unit,
|
||||
) : RecyclerView.Adapter<ColorLibraryViewHolder>() {
|
||||
|
||||
fun updateData(newLibraries: List<ColorLibrariesActivity.Companion.PresetColorLibrary>) {
|
||||
fun updateData(newLibraries: List<PresetColorLibrary>) {
|
||||
libraries = newLibraries
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
@@ -26,7 +28,17 @@ class ColorLibraryAdapter(
|
||||
override fun onBindViewHolder(holder: ColorLibraryViewHolder, position: Int) {
|
||||
val library = libraries[position]
|
||||
holder.bind(library)
|
||||
holder.itemView.setOnClickListener { onItemClick(library) }
|
||||
holder.itemView.setOnClickListener {
|
||||
when {
|
||||
library.isIntelligent -> MaterialDialog.Builder(holder.itemView.context)
|
||||
.title(R.string.text_under_development_title)
|
||||
.content(R.string.text_under_development_content)
|
||||
.positiveText(R.string.dialog_button_dismiss)
|
||||
.positiveColorRes(R.color.dialog_button_default)
|
||||
.show()
|
||||
else -> onItemClick(library)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount() = libraries.size
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package org.autojs.autojs.theme.app
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.res.ColorStateList
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.autojs.autojs.theme.ThemeColorManager
|
||||
import org.autojs.autojs.theme.app.ColorLibrariesActivity.Companion.PresetColorLibrary
|
||||
import org.autojs.autojs.util.ColorUtils
|
||||
import org.autojs.autojs6.R
|
||||
|
||||
@@ -18,11 +20,19 @@ class ColorLibraryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
|
||||
private val libraryName: TextView = itemView.findViewById(R.id.name)
|
||||
private val description: TextView = itemView.findViewById(R.id.description)
|
||||
|
||||
fun bind(library: ColorLibrariesActivity.Companion.PresetColorLibrary) {
|
||||
fun bind(library: PresetColorLibrary) {
|
||||
libraryName.text = context.getString(library.nameRes)
|
||||
|
||||
val size = library.colors.size
|
||||
description.text = resources.getQuantityString(R.plurals.text_items_total_sum, size, size)
|
||||
description.text = when {
|
||||
library.isIntelligent -> {
|
||||
@SuppressLint("SetTextI18n")
|
||||
"[ ${context.getString(R.string.text_under_development)} ]"
|
||||
}
|
||||
else -> {
|
||||
val size = library.colors.size
|
||||
resources.getQuantityString(R.plurals.text_items_total_sum, size, size)
|
||||
}
|
||||
}
|
||||
|
||||
val adjustedContrastColor = ColorUtils.adjustColorForContrast(context.getColor(R.color.window_background), ThemeColorManager.colorPrimary, 2.3)
|
||||
when {
|
||||
|
||||
@@ -249,6 +249,14 @@ abstract class ColorSelectBaseActivity : BaseActivity() {
|
||||
.show(supportFragmentManager, "ColorPickerTagForColorLibraries")
|
||||
}
|
||||
|
||||
protected fun showColorDetails(color: Int, titleRes: Int = R.string.dialog_title_color_details) {
|
||||
ColorInfoDialogManager.showColorInfoDialog(this, color, titleRes)
|
||||
}
|
||||
|
||||
protected fun showThemeColorDetails() {
|
||||
showColorDetails(ThemeColorManager.colorPrimary, R.string.dialog_title_theme_color_details)
|
||||
}
|
||||
|
||||
private fun savePrefsForLibraries() {
|
||||
Pref.putInt(KEY_SELECTED_COLOR_LIBRARY_ID, COLOR_LIBRARY_ID_PALETTE)
|
||||
Pref.putInt(KEY_SELECTED_COLOR_LIBRARY_ITEM_ID, 0)
|
||||
|
||||
@@ -249,7 +249,7 @@ public class EditorMenu {
|
||||
builder.itemsDisabledIndices(i);
|
||||
MaterialDialog built = builder.build();
|
||||
assert built.getItems() != null;
|
||||
built.getItems().set(i, built.getItems().get(i) + " (" + builder.getContext().getString(R.string.text_under_development_title).toLowerCase(Language.getPrefLanguage().getLocale()) + ")");
|
||||
built.getItems().set(i, built.getItems().get(i) + " (" + builder.getContext().getString(R.string.text_under_development).toLowerCase(Language.getPrefLanguage().getLocale()) + ")");
|
||||
built.show();
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ class LogActivity : BaseActivity() {
|
||||
}
|
||||
R.id.action_settings -> {
|
||||
// TODO by SuperMonster003 on Jul 3, 2023.
|
||||
showToast(this, R.string.text_under_development_title)
|
||||
showToast(this, R.string.text_under_development)
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
||||
@@ -5,10 +5,7 @@ import android.content.Context
|
||||
import android.content.pm.PackageManager.GET_META_DATA
|
||||
import android.os.Build
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.View.MeasureSpec.UNSPECIFIED
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.isVisible
|
||||
import com.afollestad.materialdialogs.DialogAction
|
||||
@@ -19,11 +16,12 @@ import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.autojs.autojs.extension.MaterialDialogExtensions.makeSettingsLaunchable
|
||||
import org.autojs.autojs.extension.MaterialDialogExtensions.makeTextCopyable
|
||||
import org.autojs.autojs.extension.MaterialDialogExtensions.setCopyableTextIfAbsent
|
||||
import org.autojs.autojs.pio.PFiles
|
||||
import org.autojs.autojs.runtime.api.AppUtils
|
||||
import org.autojs.autojs.util.ClipboardUtils
|
||||
import org.autojs.autojs.util.IntentUtils
|
||||
import org.autojs.autojs.util.ViewUtils
|
||||
import org.autojs.autojs6.R
|
||||
import org.autojs.autojs6.databinding.ApkFileInfoDialogListItemBinding
|
||||
import java.io.File
|
||||
@@ -36,13 +34,13 @@ object ApkInfoDialogManager {
|
||||
@SuppressLint("SetTextI18n")
|
||||
fun showApkInfoDialog(context: Context, apkFile: File) {
|
||||
val binding = ApkFileInfoDialogListItemBinding.inflate(LayoutInflater.from(context))
|
||||
val root = binding.root as ViewGroup
|
||||
|
||||
val apkFilePath = apkFile.absolutePath
|
||||
val packageManager = context.packageManager
|
||||
|
||||
val dialog = MaterialDialog.Builder(context)
|
||||
.title(apkFile.name)
|
||||
.customView(root, false)
|
||||
.customView(binding.root, false)
|
||||
.autoDismiss(false)
|
||||
.iconRes(R.drawable.ic_three_dots_outline_small)
|
||||
.limitIconToDefaultSize()
|
||||
@@ -58,8 +56,6 @@ object ApkInfoDialogManager {
|
||||
.onNegative { materialDialog, _ -> materialDialog.dismiss() }
|
||||
.show()
|
||||
|
||||
val packageManager = context.packageManager
|
||||
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
val packageInfo = withContext(Dispatchers.IO) {
|
||||
runCatching { packageManager.getPackageArchiveInfo(apkFilePath, GET_META_DATA) }.getOrNull()
|
||||
@@ -91,7 +87,7 @@ object ApkInfoDialogManager {
|
||||
val installedPackageName: String? = packageName?.let { pkg ->
|
||||
AppUtils.getInstalledVersionInfo(pkg)?.let { versionInfo ->
|
||||
binding.installedVersionParent.isVisible = true
|
||||
binding.installedVersionValue.setTextIfAbsent(dialog) { context.getString(R.string.text_full_version_info, versionInfo.versionName, versionInfo.versionCode) }
|
||||
binding.installedVersionValue.setCopyableTextIfAbsent(dialog) { context.getString(R.string.text_full_version_info, versionInfo.versionName, versionInfo.versionCode) }
|
||||
pkg /* returns as installedPackageName */
|
||||
}
|
||||
}
|
||||
@@ -102,19 +98,19 @@ object ApkInfoDialogManager {
|
||||
when {
|
||||
versionName != null -> {
|
||||
binding.versionPlaceholderLabel.text = context.getString(R.string.text_version)
|
||||
binding.versionPlaceholderValue.setTextIfAbsent(dialog) { context.getString(R.string.text_full_version_info, versionName, versionCode) }
|
||||
binding.versionPlaceholderValue.setCopyableTextIfAbsent(dialog) { context.getString(R.string.text_full_version_info, versionName, versionCode) }
|
||||
}
|
||||
versionCode != null -> {
|
||||
binding.versionPlaceholderLabel.text = context.getString(R.string.text_version_code)
|
||||
binding.versionPlaceholderValue.setTextIfAbsent(dialog) { "$versionCode" }
|
||||
binding.versionPlaceholderValue.setCopyableTextIfAbsent(dialog) { "$versionCode" }
|
||||
}
|
||||
else -> binding.versionPlaceholderValue.setTextIfAbsent(dialog) { null }
|
||||
else -> binding.versionPlaceholderValue.setCopyableTextIfAbsent(dialog) { null }
|
||||
}
|
||||
|
||||
binding.packageNameValue.setTextIfAbsent(dialog) { packageName }
|
||||
binding.deviceSdkValue.setTextIfAbsent(dialog) { "${Build.VERSION.SDK_INT}" }
|
||||
binding.fileSizeValue.setTextIfAbsent(dialog) { fileSize }
|
||||
binding.signatureSchemeValue.setTextIfAbsent(dialog) { signatureScheme }
|
||||
binding.packageNameValue.setCopyableTextIfAbsent(dialog) { packageName }
|
||||
binding.deviceSdkValue.setCopyableTextIfAbsent(dialog) { "${Build.VERSION.SDK_INT}" }
|
||||
binding.fileSizeValue.setCopyableTextIfAbsent(dialog) { fileSize }
|
||||
binding.signatureSchemeValue.setCopyableTextIfAbsent(dialog) { signatureScheme }
|
||||
|
||||
dialog.setIcon(applicationInfo?.apply {
|
||||
sourceDir = apkFilePath
|
||||
@@ -126,10 +122,10 @@ object ApkInfoDialogManager {
|
||||
|
||||
val apkInfo = getApkInfo(apkFile)
|
||||
|
||||
binding.labelNameValue.setTextIfAbsent(dialog) { apkInfo?.label }
|
||||
binding.packageNameValue.setTextIfAbsent(dialog) { apkInfo?.packageName }
|
||||
binding.minSdkValue.setTextIfAbsent(dialog) { apkInfo?.minSdkVersion?.toString() }
|
||||
binding.targetSdkValue.setTextIfAbsent(dialog) { apkInfo?.targetSdkVersion?.toString() }
|
||||
binding.labelNameValue.setCopyableTextIfAbsent(dialog) { apkInfo?.label }
|
||||
binding.packageNameValue.setCopyableTextIfAbsent(dialog) { apkInfo?.packageName }
|
||||
binding.minSdkValue.setCopyableTextIfAbsent(dialog) { apkInfo?.minSdkVersion?.toString() }
|
||||
binding.targetSdkValue.setCopyableTextIfAbsent(dialog) { apkInfo?.targetSdkVersion?.toString() }
|
||||
|
||||
if (apkInfo != null) dialog.getActionButton(DialogAction.NEUTRAL).let { neutralButton ->
|
||||
neutralButton.isVisible = true
|
||||
@@ -155,37 +151,6 @@ object ApkInfoDialogManager {
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
private fun MaterialDialog.makeSettingsLaunchable(viewGetter: (dialog: MaterialDialog) -> View?, packageName: String?) {
|
||||
viewGetter(this)?.setOnClickListener {
|
||||
packageName?.let { pkg ->
|
||||
IntentUtils.goToAppDetailSettings(this.context, pkg)
|
||||
} ?: ViewUtils.showSnack(this.view, R.string.error_app_not_installed)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MaterialDialog.makeTextCopyable(textViewGetter: (dialog: MaterialDialog) -> TextView?) {
|
||||
makeTextCopyable(textViewGetter(this))
|
||||
}
|
||||
|
||||
private fun MaterialDialog.makeTextCopyable(textView: TextView?, textValue: String? = textView?.text?.toString()) {
|
||||
if (textValue != null) {
|
||||
val context = this.context
|
||||
textView?.setOnClickListener {
|
||||
ClipboardUtils.setClip(context, textValue)
|
||||
ViewUtils.showSnack(this.view, "${context.getString(R.string.text_already_copied_to_clip)}: $textValue")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun TextView.setTextIfAbsent(dialog: MaterialDialog, f: () -> String?) {
|
||||
val textView = this
|
||||
val textValue = f.invoke()
|
||||
if (textView.text == context.getString(R.string.ellipsis_six)) {
|
||||
textView.text = textValue ?: context.getString(R.string.text_unknown)
|
||||
}
|
||||
dialog.makeTextCopyable(textView, textValue)
|
||||
}
|
||||
|
||||
private fun restoreEssentialViews(binding: ApkFileInfoDialogListItemBinding, context: Context) {
|
||||
listOf(
|
||||
Triple(binding.labelNameLabel, binding.labelNameColon, binding.labelNameValue) to R.string.text_label_name,
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View.MeasureSpec.UNSPECIFIED
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.isVisible
|
||||
@@ -16,6 +15,8 @@ import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.autojs.autojs.extension.MaterialDialogExtensions.makeTextCopyable
|
||||
import org.autojs.autojs.extension.MaterialDialogExtensions.setCopyableText
|
||||
import org.autojs.autojs.model.explorer.ExplorerItem
|
||||
import org.autojs.autojs.util.ViewUtils
|
||||
import org.autojs.autojs6.R
|
||||
@@ -33,11 +34,10 @@ object MediaInfoDialogManager {
|
||||
@SuppressLint("SetTextI18n")
|
||||
fun showMediaInfoDialog(context: Context, explorerItem: ExplorerItem) {
|
||||
val binding = MediaFileInfoDialogListItemBinding.inflate(LayoutInflater.from(context))
|
||||
val root = binding.root as ViewGroup
|
||||
|
||||
val dialog = MaterialDialog.Builder(context)
|
||||
.title(explorerItem.name)
|
||||
.customView(root, false)
|
||||
.customView(binding.root, false)
|
||||
.autoDismiss(false)
|
||||
.iconRes(R.drawable.transparent)
|
||||
.limitIconToDefaultSize()
|
||||
@@ -60,38 +60,38 @@ object MediaInfoDialogManager {
|
||||
|
||||
launch(Dispatchers.IO) {
|
||||
mediaInfo(filePath, GENERAL, "FileSize/String").let {
|
||||
binding.fileSizeValue.bindWith(it)
|
||||
binding.fileSizeValue.bindWith(dialog, it)
|
||||
}
|
||||
}
|
||||
launch(Dispatchers.IO) {
|
||||
mediaInfo(filePath, GENERAL, "Duration/String").let { binding.durationValue.bindWith(it) }
|
||||
mediaInfo(filePath, GENERAL, "Duration/String").let { binding.durationValue.bindWith(dialog, it) }
|
||||
}
|
||||
launch(Dispatchers.IO) {
|
||||
mediaInfo(filePath, GENERAL, "Album").let { binding.albumValue.bindWith(it) }
|
||||
mediaInfo(filePath, GENERAL, "Album").let { binding.albumValue.bindWith(dialog, it) }
|
||||
}
|
||||
launch(Dispatchers.IO) {
|
||||
mediaInfo(filePath, GENERAL, "Track").let { binding.trackNameValue.bindWith(it) }
|
||||
mediaInfo(filePath, GENERAL, "Track").let { binding.trackNameValue.bindWith(dialog, it) }
|
||||
}
|
||||
launch(Dispatchers.IO) {
|
||||
mediaInfo(filePath, GENERAL, "Performer").let { binding.performerValue.bindWith(it) }
|
||||
mediaInfo(filePath, GENERAL, "Performer").let { binding.performerValue.bindWith(dialog, it) }
|
||||
}
|
||||
launch(Dispatchers.IO) {
|
||||
mediaInfo(filePath, AUDIO, "BitRate/String").let { binding.bitRateForAudioValue.bindWith(it) }
|
||||
mediaInfo(filePath, AUDIO, "BitRate/String").let { binding.bitRateForAudioValue.bindWith(dialog, it) }
|
||||
}
|
||||
launch(Dispatchers.IO) {
|
||||
mediaInfo(filePath, VIDEO, "BitRate/String").let { binding.bitRateForVideoValue.bindWith(it) }
|
||||
mediaInfo(filePath, VIDEO, "BitRate/String").let { binding.bitRateForVideoValue.bindWith(dialog, it) }
|
||||
}
|
||||
launch(Dispatchers.IO) {
|
||||
mediaInfo(filePath, VIDEO, "DisplayAspectRatio/String").let { binding.aspectRatioValue.bindWith(it) }
|
||||
mediaInfo(filePath, VIDEO, "DisplayAspectRatio/String").let { binding.aspectRatioValue.bindWith(dialog, it) }
|
||||
}
|
||||
launch(Dispatchers.IO) {
|
||||
mediaInfo(filePath, VIDEO, "FrameRate").let { binding.frameRateValue.bindWith(it) }
|
||||
mediaInfo(filePath, VIDEO, "FrameRate").let { binding.frameRateValue.bindWith(dialog, it) }
|
||||
}
|
||||
launch(Dispatchers.IO) {
|
||||
val deferredVideoWidth = async(Dispatchers.IO) { mediaInfo(filePath, VIDEO, "Width") }
|
||||
val deferredVideoHeight = async(Dispatchers.IO) { mediaInfo(filePath, VIDEO, "Height") }
|
||||
val (width, height) = awaitAll(deferredVideoWidth, deferredVideoHeight)
|
||||
binding.resolutionValue.bindWith(if (width.isNotEmpty() && height.isNotEmpty()) "$width × $height" else "")
|
||||
binding.resolutionValue.bindWith(dialog, if (width.isNotEmpty() && height.isNotEmpty()) "$width × $height" else "")
|
||||
}
|
||||
|
||||
when {
|
||||
@@ -123,6 +123,7 @@ object MediaInfoDialogManager {
|
||||
restoreEssentialViews(binding, context)
|
||||
updateGuidelines(binding)
|
||||
updateSplitLineVisibility(binding)
|
||||
dialog.makeTextCopyable { it.titleView }
|
||||
}
|
||||
|
||||
when (val containerFormat = deferredContainerFormat.await()) {
|
||||
@@ -134,9 +135,9 @@ object MediaInfoDialogManager {
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
containerFormat.let { binding.containerFormatValue.bindWith(it) }
|
||||
deferredAudioFormat.await().let { binding.audioFormatValue.bindWith(it) }
|
||||
deferredVideoFormat.await().let { binding.videoFormatValue.bindWith(it) }
|
||||
containerFormat.let { binding.containerFormatValue.bindWith(dialog, it) }
|
||||
deferredAudioFormat.await().let { binding.audioFormatValue.bindWith(dialog, it) }
|
||||
deferredVideoFormat.await().let { binding.videoFormatValue.bindWith(dialog, it) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,12 +183,12 @@ object MediaInfoDialogManager {
|
||||
binding.performerParent.isVisible = true
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
@Suppress("UNUSED_PARAMETER", "unused")
|
||||
private fun setViewsAsMediaMenuPlaceholder(binding: MediaFileInfoDialogListItemBinding) {
|
||||
/* Nothing to do yet. */
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
@Suppress("UNUSED_PARAMETER", "unused")
|
||||
private fun setViewsAsLeastPlaceholder(binding: MediaFileInfoDialogListItemBinding) {
|
||||
/* Nothing to do yet. */
|
||||
}
|
||||
@@ -252,8 +253,10 @@ object MediaInfoDialogManager {
|
||||
).any { it.isVisible }
|
||||
}
|
||||
|
||||
private suspend fun TextView.bindWith(text: String) {
|
||||
withContext(Dispatchers.Main) { this@bindWith.text = text.takeUnless { text.isEmpty() } ?: context.getString(R.string.text_unknown) }
|
||||
private suspend fun TextView.bindWith(dialog: MaterialDialog, text: String) {
|
||||
withContext(Dispatchers.Main) {
|
||||
this@bindWith.setCopyableText(dialog) { text }
|
||||
}
|
||||
}
|
||||
|
||||
private operator fun MediaInfo.invoke(filePath: String, streamKind: MediaInfo.StreamKind, parameter: String): String {
|
||||
|
||||
@@ -14,6 +14,7 @@ import androidx.core.graphics.ColorUtils
|
||||
import org.autojs.autojs.app.GlobalAppContext
|
||||
import org.autojs.autojs.core.image.ColorTable
|
||||
import org.autojs.autojs.theme.ThemeColor
|
||||
import java.math.RoundingMode
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.text.RegexOption.IGNORE_CASE
|
||||
|
||||
@@ -419,4 +420,41 @@ object ColorUtils {
|
||||
return null
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun Double.roundToAlphaString(scale: Int = 1, keepTrailingZeroForFullAlpha: Boolean = true): String {
|
||||
return toBigDecimal()
|
||||
.setScale(scale, RoundingMode.HALF_UP)
|
||||
.stripTrailingZeros()
|
||||
.toPlainString()
|
||||
.let { if (keepTrailingZeroForFullAlpha && it == "1") "1.0" else it }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun Double.roundToHueString(scale: Int = 0): String {
|
||||
return toBigDecimal()
|
||||
.setScale(scale, RoundingMode.HALF_UP)
|
||||
.stripTrailingZeros()
|
||||
.toPlainString()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun Double.roundToSaturationString(scale: Int = 1): String {
|
||||
return (this * 100.0).toBigDecimal()
|
||||
.setScale(scale, RoundingMode.HALF_UP)
|
||||
.stripTrailingZeros()
|
||||
.toPlainString() + "%"
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun Double.roundToValueString(scale: Int = 1): String {
|
||||
return (this * 100.0).toBigDecimal()
|
||||
.setScale(scale, RoundingMode.HALF_UP)
|
||||
.stripTrailingZeros()
|
||||
.toPlainString() + "%"
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user