Merge pull request #2876 from Philoul/wear/new_custom_watchface

Wear CWF Include Cockpit Watchface into assets and simplify code
This commit is contained in:
Milos Kozak 2023-10-06 22:25:24 +02:00 committed by GitHub
commit d064291a1b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 88 additions and 69 deletions

View file

@ -251,7 +251,10 @@ enum class JsonKeys(val key: String) {
INVALIDVALUE("invalidValue"), INVALIDVALUE("invalidValue"),
IMAGE("image"), IMAGE("image"),
INVALIDIMAGE("invalidImage"), INVALIDIMAGE("invalidImage"),
INVALIDCOLOR("invalidColor") INVALIDCOLOR("invalidColor"),
TWINVIEW("twinView"),
TOPOFFSETTWINHIDDEN("topOffsetTwinHidden"),
LEFTOFFSETTWINHIDDEN("leftOffsetTwinHidden")
} }
enum class JsonKeyValues(val key: String) { enum class JsonKeyValues(val key: String) {

Binary file not shown.

View file

@ -65,6 +65,7 @@ class CustomWatchface : BaseWatchFace() {
private val TEMPLATE_RESOLUTION = 400 private val TEMPLATE_RESOLUTION = 400
private var lowBatColor = Color.RED private var lowBatColor = Color.RED
private var resDataMap: CwfResDataMap = mutableMapOf() private var resDataMap: CwfResDataMap = mutableMapOf()
private var json = JSONObject()
private var jsonString = "" private var jsonString = ""
private val bgColor: Int private val bgColor: Int
get() = when (singleBg.sgvLevel) { get() = when (singleBg.sgvLevel) {
@ -151,7 +152,7 @@ class CustomWatchface : BaseWatchFace() {
customWatchface?.let { customWatchface?.let {
updatePref(it.customWatchfaceData.metadata) updatePref(it.customWatchfaceData.metadata)
try { try {
val json = JSONObject(it.customWatchfaceData.json) json = JSONObject(it.customWatchfaceData.json)
if (!resDataMap.isEquals(it.customWatchfaceData.resDatas) || jsonString != it.customWatchfaceData.json) { if (!resDataMap.isEquals(it.customWatchfaceData.resDatas) || jsonString != it.customWatchfaceData.json) {
resDataMap = it.customWatchfaceData.resDatas resDataMap = it.customWatchfaceData.resDatas
jsonString = it.customWatchfaceData.json jsonString = it.customWatchfaceData.json
@ -177,18 +178,11 @@ class CustomWatchface : BaseWatchFace() {
binding.mainLayout.forEach { view -> binding.mainLayout.forEach { view ->
ViewMap.fromId(view.id)?.let { viewMap -> ViewMap.fromId(view.id)?.let { viewMap ->
json.optJSONObject(viewMap.key)?.also { viewJson ->
when (view) { when (view) {
is TextView -> viewMap.customizeTextView(view, viewJson) is TextView -> viewMap.customizeTextView(view)
is ImageView -> viewMap.customizeImageView(view, viewJson) is ImageView -> viewMap.customizeImageView(view)
is lecho.lib.hellocharts.view.LineChartView -> viewMap.customizeGraphView(view, viewJson) is lecho.lib.hellocharts.view.LineChartView -> viewMap.customizeGraphView(view)
else -> viewMap.customizeViewCommon(view, viewJson) else -> viewMap.customizeViewCommon(view)
}
} ?: apply {
view.visibility = View.GONE
if (view is TextView) {
view.text = ""
}
} }
} }
} }
@ -445,8 +439,11 @@ class CustomWatchface : BaseWatchFace() {
it.highCustom = null it.highCustom = null
it.lowCustom = null it.lowCustom = null
it.textDrawable = null it.textDrawable = null
it.viewJson = null
it.twinView = null
} }
fun fromId(id: Int): ViewMap? = values().firstOrNull { it.id == id } fun fromId(id: Int): ViewMap? = values().firstOrNull { it.id == id }
fun fromKey(key: String?): ViewMap? = values().firstOrNull { it.key == key }
} }
lateinit var cwf: CustomWatchface lateinit var cwf: CustomWatchface
@ -454,6 +451,10 @@ class CustomWatchface : BaseWatchFace() {
var height = 0 var height = 0
var left = 0 var left = 0
var top = 0 var top = 0
var viewJson: JSONObject? = null
get() = field ?: cwf.json.optJSONObject(key)?.also { viewJson = it }
val visibility: Int
get() = viewJson?.let { cwf.setVisibility(it.optString(VISIBILITY.key, JsonKeyValues.GONE.key), visibility()) } ?: View.GONE
var dynData: DynProvider? = null var dynData: DynProvider? = null
var rangeCustom: Drawable? = null var rangeCustom: Drawable? = null
get() = field ?: customDrawable?.let { cd -> cwf.resDataMap[cd.fileName]?.toDrawable(cwf.resources).also { rangeCustom = it } } get() = field ?: customDrawable?.let { cd -> cwf.resDataMap[cd.fileName]?.toDrawable(cwf.resources).also { rangeCustom = it } }
@ -469,31 +470,38 @@ class CustomWatchface : BaseWatchFace() {
-1L -> lowCustom ?: rangeCustom -1L -> lowCustom ?: rangeCustom
else -> rangeCustom else -> rangeCustom
} }
var twinView: ViewMap? = null
get() = field ?: viewJson?.let { viewJson -> ViewMap.fromKey(viewJson.optString(TWINVIEW.key)).also { twinView = it } }
fun visibility(): Boolean = this.pref?.let { cwf.sp.getBoolean(it, true) } fun visibility(): Boolean = this.pref?.let { cwf.sp.getBoolean(it, true) }
?: true ?: true
fun textDrawable(viewJson: JSONObject): Drawable? = textDrawable fun textDrawable(): Drawable? = textDrawable
?: cwf.resDataMap[viewJson.optString(JsonKeys.BACKGROUND.key)]?.toDrawable(cwf.resources, width, height)?.also { textDrawable = it } ?: cwf.resDataMap[viewJson?.optString(JsonKeys.BACKGROUND.key)]?.toDrawable(cwf.resources, width, height)?.also { textDrawable = it }
fun customizeViewCommon(view: View, viewJson: JSONObject) { fun customizeViewCommon(view: View) {
view.visibility = visibility
viewJson?.let {viewJson ->
width = (viewJson.optInt(WIDTH.key) * cwf.zoomFactor).toInt() width = (viewJson.optInt(WIDTH.key) * cwf.zoomFactor).toInt()
height = (viewJson.optInt(HEIGHT.key) * cwf.zoomFactor).toInt() height = (viewJson.optInt(HEIGHT.key) * cwf.zoomFactor).toInt()
left = (viewJson.optInt(LEFTMARGIN.key) * cwf.zoomFactor).toInt() left = (viewJson.optInt(LEFTMARGIN.key) * cwf.zoomFactor).toInt()
top = (viewJson.optInt(TOPMARGIN.key) * cwf.zoomFactor).toInt() top = (viewJson.optInt(TOPMARGIN.key) * cwf.zoomFactor).toInt()
val params = FrameLayout.LayoutParams(width, height) val params = FrameLayout.LayoutParams(width, height)
dynData = DynProvider.getDyn(cwf, viewJson.optString(DYNDATA.key),width, height, key) dynData = DynProvider.getDyn(cwf, viewJson.optString(DYNDATA.key), width, height, key)
val topOffset = if (viewJson.optBoolean(TOPOFFSET.key, false)) dynData?.getTopOffset() ?:0 else 0 val topOffset = if (viewJson.optBoolean(TOPOFFSET.key, false)) dynData?.getTopOffset() ?: 0 else 0
params.topMargin = top + topOffset val topOffsetTwin = ((twinView?.let { if (it.visibility != View.VISIBLE) viewJson.optInt(TOPOFFSETTWINHIDDEN.key,0) else 0 } ?: 0 ) * cwf.zoomFactor).toInt()
val leftOffset = if (viewJson.optBoolean(LEFTOFFSET.key, false)) dynData?.getLeftOffset() ?:0 else 0 params.topMargin = top + topOffset + topOffsetTwin
params.leftMargin = left + leftOffset val leftOffset = if (viewJson.optBoolean(LEFTOFFSET.key, false)) dynData?.getLeftOffset() ?: 0 else 0
val leftOffsetTwin = ((twinView?.let { if (it.visibility != View.VISIBLE) viewJson.optInt(LEFTOFFSETTWINHIDDEN.key,0) else 0 } ?: 0) * cwf.zoomFactor).toInt()
params.leftMargin = left + leftOffset + leftOffsetTwin
view.layoutParams = params view.layoutParams = params
view.visibility = cwf.setVisibility(viewJson.optString(VISIBILITY.key, JsonKeyValues.GONE.key), visibility()) val rotationOffset = if (viewJson.optBoolean(ROTATIONOFFSET.key, false)) dynData?.getRotationOffset()?.toFloat() ?: 0F else 0F
val rotationOffset = if (viewJson.optBoolean(ROTATIONOFFSET.key, false)) dynData?.getRotationOffset()?.toFloat() ?:0F else 0F
view.rotation = viewJson.optInt(ROTATION.key).toFloat() + rotationOffset view.rotation = viewJson.optInt(ROTATION.key).toFloat() + rotationOffset
} }
}
fun customizeTextView(view: TextView, viewJson: JSONObject) { fun customizeTextView(view: TextView) {
customizeViewCommon(view, viewJson) customizeViewCommon(view)
viewJson?.let { viewJson ->
view.setTextSize(TypedValue.COMPLEX_UNIT_PX, (viewJson.optInt(TEXTSIZE.key, 22) * cwf.zoomFactor).toFloat()) view.setTextSize(TypedValue.COMPLEX_UNIT_PX, (viewJson.optInt(TEXTSIZE.key, 22) * cwf.zoomFactor).toFloat())
view.gravity = GravityMap.gravity(viewJson.optString(GRAVITY.key, GravityMap.CENTER.key)) view.gravity = GravityMap.gravity(viewJson.optString(GRAVITY.key, GravityMap.CENTER.key))
view.setTypeface( view.setTypeface(
@ -504,12 +512,14 @@ class CustomWatchface : BaseWatchFace() {
view.isAllCaps = viewJson.optBoolean(ALLCAPS.key) view.isAllCaps = viewJson.optBoolean(ALLCAPS.key)
if (viewJson.has(TEXTVALUE.key)) if (viewJson.has(TEXTVALUE.key))
view.text = viewJson.optString(TEXTVALUE.key) view.text = viewJson.optString(TEXTVALUE.key)
view.background = dynData?.getDrawable() ?: textDrawable(viewJson) view.background = dynData?.getDrawable() ?: textDrawable()
} ?: apply { view.text = "" }
} }
fun customizeImageView(view: ImageView, viewJson: JSONObject) { fun customizeImageView(view: ImageView) {
customizeViewCommon(view, viewJson) customizeViewCommon(view)
view.clearColorFilter() view.clearColorFilter()
viewJson?.let { viewJson ->
drawable?.let { drawable?.let {
if (viewJson.has(COLOR.key) || (dynData?.stepColor ?: 0) > 0) // Note only works on bitmap (png or jpg) or xml included into res, not for svg files if (viewJson.has(COLOR.key) || (dynData?.stepColor ?: 0) > 0) // Note only works on bitmap (png or jpg) or xml included into res, not for svg files
it.colorFilter = cwf.changeDrawableColor(dynData?.getColor() ?: cwf.getColor(viewJson.optString(COLOR.key))) it.colorFilter = cwf.changeDrawableColor(dynData?.getColor() ?: cwf.getColor(viewJson.optString(COLOR.key)))
@ -524,11 +534,14 @@ class CustomWatchface : BaseWatchFace() {
view.clearColorFilter() view.clearColorFilter()
} }
} }
}
fun customizeGraphView(view: lecho.lib.hellocharts.view.LineChartView, viewJson: JSONObject) { fun customizeGraphView(view: lecho.lib.hellocharts.view.LineChartView) {
customizeViewCommon(view, viewJson) customizeViewCommon(view)
view.setBackgroundColor(dynData?.getColor() ?: cwf.getColor(viewJson.optString(COLOR.key, "#0000000000"),Color.TRANSPARENT)) viewJson?.let { viewJson ->
view.background = dynData?.getDrawable() ?: textDrawable(viewJson) view.setBackgroundColor(dynData?.getColor() ?: cwf.getColor(viewJson.optString(COLOR.key, "#0000000000"), Color.TRANSPARENT))
view.background = dynData?.getDrawable() ?: textDrawable()
}
} }
} }
@ -549,6 +562,7 @@ class CustomWatchface : BaseWatchFace() {
fun init(cwf: CustomWatchface) = values().forEach { fun init(cwf: CustomWatchface) = values().forEach {
it.cwf = cwf it.cwf = cwf
it.arrowCustom = null it.arrowCustom = null
} }
fun drawable() = values().firstOrNull { it.symbol == it.cwf.singleBg.slopeArrow }?.arrowCustom ?: NONE.arrowCustom fun drawable() = values().firstOrNull { it.symbol == it.cwf.singleBg.slopeArrow }?.arrowCustom ?: NONE.arrowCustom
fun value() = values().firstOrNull { it.symbol == it.cwf.singleBg.slopeArrow }?.dynValue ?: NONE.dynValue fun value() = values().firstOrNull { it.symbol == it.cwf.singleBg.slopeArrow }?.dynValue ?: NONE.dynValue
@ -707,8 +721,10 @@ class CustomWatchface : BaseWatchFace() {
ValueMap.WEEKNUMBER -> DateTime().weekOfWeekyear.toDouble() ValueMap.WEEKNUMBER -> DateTime().weekOfWeekyear.toDouble()
} }
fun getTopOffset(): Int = dataRange?.let { dataRange -> topRange?.let { topRange -> dataValue?.let { valueMap.dynValue(it, dataRange, topRange) } ?: topRange.invalidData } } ?: 0 fun getTopOffset(): Int = dataRange?.let { dataRange -> topRange?.let { topRange -> dataValue?.let { (valueMap.dynValue(it, dataRange, topRange) * cwf.zoomFactor).toInt() }
fun getLeftOffset(): Int = dataRange?.let { dataRange -> leftRange?.let { leftRange -> dataValue?.let { valueMap.dynValue(it, dataRange, leftRange) } ?: leftRange.invalidData } } ?: 0 ?: (topRange.invalidData * cwf.zoomFactor).toInt() } } ?: 0
fun getLeftOffset(): Int = dataRange?.let { dataRange -> leftRange?.let { leftRange -> dataValue?.let { (valueMap.dynValue(it, dataRange, leftRange) * cwf.zoomFactor).toInt() }
?: (leftRange.invalidData * cwf.zoomFactor).toInt() } } ?: 0
fun getRotationOffset(): Int = dataRange?.let { dataRange -> rotationRange?.let { rotRange -> dataValue?.let { valueMap.dynValue(it, dataRange, rotRange) } ?: rotRange.invalidData } } ?: 0 fun getRotationOffset(): Int = dataRange?.let { dataRange -> rotationRange?.let { rotRange -> dataValue?.let { valueMap.dynValue(it, dataRange, rotRange) } ?: rotRange.invalidData } } ?: 0
fun getDrawable() = dataRange?.let { dataRange -> dataValue?.let { dynDrawable[valueMap.stepValue(it, dataRange, stepDraw)] } ?: dynDrawable[0] } fun getDrawable() = dataRange?.let { dataRange -> dataValue?.let { dynDrawable[valueMap.stepValue(it, dataRange, stepDraw)] } ?: dynDrawable[0] }
fun getColor() = if (stepColor > 0) dataRange?.let { dataRange -> dataValue?.let { dynColor[valueMap.stepValue(it, dataRange, stepColor)] } ?: dynColor[0] } else null fun getColor() = if (stepColor > 0) dataRange?.let { dataRange -> dataValue?.let { dynColor[valueMap.stepValue(it, dataRange, stepColor)] } ?: dynColor[0] } else null