Merge pull request #2688 from Philoul/wear/new_custom_watchface
CWF Wear: minor bug fix and code improvements (cwf v0.10)
This commit is contained in:
commit
1f0bce9f7f
14 changed files with 423 additions and 289 deletions
|
@ -1,5 +1,5 @@
|
|||
package info.nightscout.rx.events
|
||||
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceData
|
||||
import info.nightscout.rx.weardata.CwfData
|
||||
|
||||
class EventWearUpdateGui(val customWatchfaceData: CustomWatchfaceData? = null, val exportFile: Boolean = false) : Event()
|
||||
class EventWearUpdateGui(val customWatchfaceData: CwfData? = null, val exportFile: Boolean = false) : Event()
|
|
@ -17,34 +17,39 @@ import java.util.zip.ZipEntry
|
|||
import java.util.zip.ZipInputStream
|
||||
import java.util.zip.ZipOutputStream
|
||||
|
||||
val CUSTOM_VERSION = "0.9"
|
||||
enum class CustomWatchfaceDrawableDataKey(val key: String, @DrawableRes val icon: Int?, val fileName: String) {
|
||||
val CUSTOM_VERSION = "0.10"
|
||||
|
||||
enum class CwfDrawableFileMap(val key: String, @DrawableRes val icon: Int?, val fileName: String) {
|
||||
UNKNOWN("unknown", null, "Unknown"),
|
||||
CUSTOM_WATCHFACE("customWatchface", R.drawable.watchface_custom, "CustomWatchface"),
|
||||
BACKGROUND("background", R.drawable.background, "Background"),
|
||||
BACKGROUND_HIGH("background", R.drawable.background, "BackgroundHigh"),
|
||||
BACKGROUND_LOW("background", R.drawable.background, "BackgroundLow"),
|
||||
COVERCHART("cover_chart", null, "CoverChart"),
|
||||
COVERPLATE("cover_plate", R.drawable.simplified_dial, "CoverPlate"),
|
||||
HOURHAND("hour_hand", R.drawable.hour_hand, "HourHand"),
|
||||
MINUTEHAND("minute_hand", R.drawable.minute_hand, "MinuteHand"),
|
||||
SECONDHAND("second_hand", R.drawable.second_hand, "SecondHand");
|
||||
BACKGROUND(ViewKeys.BACKGROUND.key, R.drawable.background, "Background"),
|
||||
BACKGROUND_HIGH(ViewKeys.BACKGROUND.key, R.drawable.background, "BackgroundHigh"),
|
||||
BACKGROUND_LOW(ViewKeys.BACKGROUND.key, R.drawable.background, "BackgroundLow"),
|
||||
COVER_CHART(ViewKeys.COVER_CHART.key, null, "CoverChart"),
|
||||
COVER_PLATE(ViewKeys.COVER_PLATE.key, R.drawable.simplified_dial, "CoverPlate"),
|
||||
HOUR_HAND(ViewKeys.HOUR_HAND.key, R.drawable.hour_hand, "HourHand"),
|
||||
MINUTE_HAND(ViewKeys.MINUTE_HAND.key, R.drawable.minute_hand, "MinuteHand"),
|
||||
SECOND_HAND(ViewKeys.SECOND_HAND.key, R.drawable.second_hand, "SecondHand");
|
||||
|
||||
companion object {
|
||||
fun fromKey(key: String): CustomWatchfaceDrawableDataKey =
|
||||
|
||||
fun fromKey(key: String): CwfDrawableFileMap =
|
||||
values().firstOrNull { it.key == key } ?: UNKNOWN
|
||||
fun fromFileName(file: String): CustomWatchfaceDrawableDataKey = values().firstOrNull { it.fileName == file.substringBeforeLast(".") } ?: UNKNOWN
|
||||
|
||||
fun fromFileName(file: String): CwfDrawableFileMap = values().firstOrNull { it.fileName == file.substringBeforeLast(".") } ?: UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
enum class DrawableFormat(val extension: String) {
|
||||
UNKNOWN(""),
|
||||
|
||||
//XML("xml"),
|
||||
//SVG("svg"),
|
||||
JPG("jpg"),
|
||||
PNG("png");
|
||||
|
||||
companion object {
|
||||
|
||||
fun fromFileName(fileName: String): DrawableFormat =
|
||||
values().firstOrNull { it.extension == fileName.substringAfterLast(".") } ?: UNKNOWN
|
||||
|
||||
|
@ -82,51 +87,149 @@ data class DrawableData(val value: ByteArray, val format: DrawableFormat) {
|
|||
}
|
||||
}
|
||||
|
||||
typealias CustomWatchfaceDrawableDataMap = MutableMap<CustomWatchfaceDrawableDataKey, DrawableData>
|
||||
typealias CustomWatchfaceMetadataMap = MutableMap<CustomWatchfaceMetadataKey, String>
|
||||
typealias CwfDrawableDataMap = MutableMap<CwfDrawableFileMap, DrawableData>
|
||||
typealias CwfMetadataMap = MutableMap<CwfMetadataKey, String>
|
||||
|
||||
@Serializable
|
||||
data class CustomWatchfaceData(val json: String, var metadata: CustomWatchfaceMetadataMap, val drawableDatas: CustomWatchfaceDrawableDataMap)
|
||||
data class CwfData(val json: String, var metadata: CwfMetadataMap, val drawableDatas: CwfDrawableDataMap)
|
||||
|
||||
enum class CustomWatchfaceMetadataKey(val key: String, @StringRes val label: Int) {
|
||||
enum class CwfMetadataKey(val key: String, @StringRes val label: Int, val isPref: Boolean) {
|
||||
|
||||
CWF_NAME("name", R.string.metadata_label_watchface_name, false),
|
||||
CWF_FILENAME("filename", R.string.metadata_wear_import_filename, false),
|
||||
CWF_AUTHOR("author", R.string.metadata_label_watchface_author, false),
|
||||
CWF_CREATED_AT("created_at", R.string.metadata_label_watchface_created_at, false),
|
||||
CWF_VERSION("cwf_version", R.string.metadata_label_plugin_version, false),
|
||||
CWF_AUTHOR_VERSION("author_version", R.string.metadata_label_watchface_name_version, false),
|
||||
CWF_COMMENT("comment", R.string.metadata_label_watchface_comment, false), // label not planed to be used for CWF_COMMENT
|
||||
CWF_AUTHORIZATION("cwf_authorization", R.string.metadata_label_watchface_authorization, false),
|
||||
CWF_PREF_WATCH_SHOW_DETAILED_IOB("key_show_detailed_iob", R.string.metadata_label_watchface_pref, true),
|
||||
CWF_PREF_WATCH_SHOW_DETAILED_DELTA("key_show_detailed_delta", R.string.metadata_label_watchface_pref, true),
|
||||
CWF_PREF_WATCH_SHOW_BGI("key_show_bgi", R.string.metadata_label_watchface_pref, true),
|
||||
CWF_PREF_WATCH_SHOW_IOB("key_show_iob", R.string.metadata_label_watchface_pref, true),
|
||||
CWF_PREF_WATCH_SHOW_COB("key_show_cob", R.string.metadata_label_watchface_pref, true),
|
||||
CWF_PREF_WATCH_SHOW_DELTA("key_show_delta", R.string.metadata_label_watchface_pref, true),
|
||||
CWF_PREF_WATCH_SHOW_AVG_DELTA("key_show_avg_delta", R.string.metadata_label_watchface_pref, true),
|
||||
CWF_PREF_WATCH_SHOW_UPLOADER_BATTERY("key_show_uploader_battery", R.string.metadata_label_watchface_pref, true),
|
||||
CWF_PREF_WATCH_SHOW_RIG_BATTERY("key_show_rig_battery", R.string.metadata_label_watchface_pref, true),
|
||||
CWF_PREF_WATCH_SHOW_TEMP_BASAL("key_show_temp_basal", R.string.metadata_label_watchface_pref, true),
|
||||
CWF_PREF_WATCH_SHOW_DIRECTION("key_show_direction", R.string.metadata_label_watchface_pref, true),
|
||||
CWF_PREF_WATCH_SHOW_AGO("key_show_ago", R.string.metadata_label_watchface_pref, true),
|
||||
CWF_PREF_WATCH_SHOW_BG("key_show_bg", R.string.metadata_label_watchface_pref, true),
|
||||
CWF_PREF_WATCH_SHOW_LOOP_STATUS("key_show_loop_status", R.string.metadata_label_watchface_pref, true);
|
||||
|
||||
CWF_NAME("name", R.string.metadata_label_watchface_name),
|
||||
CWF_FILENAME("filename", R.string.metadata_wear_import_filename),
|
||||
CWF_AUTHOR("author", R.string.metadata_label_watchface_author),
|
||||
CWF_CREATED_AT("created_at", R.string.metadata_label_watchface_created_at),
|
||||
CWF_VERSION("cwf_version", R.string.metadata_label_plugin_version),
|
||||
CWF_AUTHOR_VERSION("author_version", R.string.metadata_label_watchface_name_version),
|
||||
CWF_COMMENT("comment", R.string.metadata_label_watchface_comment), // label not planed to be used for CWF_COMMENT
|
||||
CWF_AUTHORIZATION("cwf_authorization", R.string.metadata_label_watchface_authorization),
|
||||
CWF_PREF_WATCH_SHOW_DETAILED_IOB("key_show_detailed_iob", R.string.metadata_label_watchface_pref),
|
||||
CWF_PREF_WATCH_SHOW_DETAILED_DELTA("key_show_detailed_delta", R.string.metadata_label_watchface_pref),
|
||||
CWF_PREF_WATCH_SHOW_BGI("key_show_bgi", R.string.metadata_label_watchface_pref),
|
||||
CWF_PREF_WATCH_SHOW_IOB("key_show_iob", R.string.metadata_label_watchface_pref),
|
||||
CWF_PREF_WATCH_SHOW_COB("key_show_cob", R.string.metadata_label_watchface_pref),
|
||||
CWF_PREF_WATCH_SHOW_DELTA("key_show_delta", R.string.metadata_label_watchface_pref),
|
||||
CWF_PREF_WATCH_SHOW_AVG_DELTA("key_show_avg_delta", R.string.metadata_label_watchface_pref),
|
||||
CWF_PREF_WATCH_SHOW_UPLOADER_BATTERY("key_show_uploader_battery", R.string.metadata_label_watchface_pref),
|
||||
CWF_PREF_WATCH_SHOW_RIG_BATTERY("key_show_rig_battery", R.string.metadata_label_watchface_pref),
|
||||
CWF_PREF_WATCH_SHOW_TEMP_BASAL("key_show_temp_basal", R.string.metadata_label_watchface_pref),
|
||||
CWF_PREF_WATCH_SHOW_DIRECTION("key_show_direction", R.string.metadata_label_watchface_pref),
|
||||
CWF_PREF_WATCH_SHOW_AGO("key_show_ago", R.string.metadata_label_watchface_pref),
|
||||
CWF_PREF_WATCH_SHOW_BG("key_show_bg", R.string.metadata_label_watchface_pref);
|
||||
companion object {
|
||||
fun fromKey(key: String): CustomWatchfaceMetadataKey? =
|
||||
|
||||
fun fromKey(key: String): CwfMetadataKey? =
|
||||
values().firstOrNull { it.key == key }
|
||||
}
|
||||
}
|
||||
|
||||
enum class ViewKeys(val key: String, @StringRes val comment: Int?) {
|
||||
|
||||
BACKGROUND("background", null),
|
||||
CHART("chart", null),
|
||||
COVER_CHART("cover_chart", null),
|
||||
FREETEXT1("freetext1", null),
|
||||
FREETEXT2("freetext2", null),
|
||||
FREETEXT3("freetext3", null),
|
||||
FREETEXT4("freetext4", null),
|
||||
IOB1("iob1", null),
|
||||
IOB2("iob2", null),
|
||||
COB1("cob1", null),
|
||||
COB2("cob2", null),
|
||||
DELTA("delta", null),
|
||||
AVG_DELTA("avg_delta", null),
|
||||
UPLOADER_BATTERY("uploader_battery", null),
|
||||
RIG_BATTERY("rig_battery", null),
|
||||
BASALRATE("basalRate", null),
|
||||
BGI("bgi", null),
|
||||
TIME("time", null),
|
||||
HOUR("hour", null),
|
||||
MINUTE("minute", null),
|
||||
SECOND("second", null),
|
||||
TIMEPERIOD("timePeriod", null),
|
||||
DAY_NAME("day_name", null),
|
||||
DAY("day", null),
|
||||
MONTH("month", null),
|
||||
LOOP("loop", null),
|
||||
DIRECTION("direction", null),
|
||||
TIMESTAMP("timestamp", null),
|
||||
SGV("sgv", null),
|
||||
COVER_PLATE("cover_plate", null),
|
||||
HOUR_HAND("hour_hand", null),
|
||||
MINUTE_HAND("minute_hand", null),
|
||||
SECOND_HAND("second_hand", null)
|
||||
}
|
||||
|
||||
enum class JsonKeys(val key: String, val viewType: ViewType, @StringRes val comment: Int?) {
|
||||
METADATA("metadata", ViewType.NONE, null),
|
||||
ENABLESECOND("enableSecond", ViewType.NONE, null),
|
||||
HIGHCOLOR("highColor", ViewType.NONE, null),
|
||||
MIDCOLOR("midColor", ViewType.NONE, null),
|
||||
LOWCOLOR("lowColor", ViewType.NONE, null),
|
||||
LOWBATCOLOR("lowBatColor", ViewType.NONE, null),
|
||||
CARBCOLOR("carbColor", ViewType.NONE, null),
|
||||
BASALBACKGROUNDCOLOR("basalBackgroundColor", ViewType.NONE, null),
|
||||
BASALCENTERCOLOR("basalCenterColor", ViewType.NONE, null),
|
||||
GRIDCOLOR("gridColor", ViewType.NONE, null),
|
||||
POINTSIZE("pointSize", ViewType.NONE, null),
|
||||
WIDTH("width", ViewType.ALLVIEWS, null),
|
||||
HEIGHT("height", ViewType.ALLVIEWS, null),
|
||||
TOPMARGIN("topmargin", ViewType.ALLVIEWS, null),
|
||||
LEFTMARGIN("leftmargin", ViewType.ALLVIEWS, null),
|
||||
ROTATION("rotation", ViewType.TEXTVIEW, null),
|
||||
VISIBILITY("visibility", ViewType.ALLVIEWS, null),
|
||||
TEXTSIZE("textsize", ViewType.TEXTVIEW, null),
|
||||
TEXTVALUE("textvalue", ViewType.TEXTVIEW, null),
|
||||
GRAVITY("gravity", ViewType.TEXTVIEW, null),
|
||||
FONT("font", ViewType.TEXTVIEW, null),
|
||||
FONTSTYLE("fontStyle", ViewType.TEXTVIEW, null),
|
||||
FONTCOLOR("fontColor", ViewType.TEXTVIEW, null),
|
||||
COLOR("color", ViewType.IMAGEVIEW, null)
|
||||
}
|
||||
|
||||
enum class JsonKeyValues(val key: String, val jsonKey: JsonKeys) {
|
||||
GONE("gone", JsonKeys.VISIBILITY),
|
||||
VISIBLE("visible", JsonKeys.VISIBILITY),
|
||||
INVISIBLE("invisible", JsonKeys.VISIBILITY),
|
||||
CENTER("center", JsonKeys.GRAVITY),
|
||||
LEFT("left", JsonKeys.GRAVITY),
|
||||
RIGHT("right", JsonKeys.GRAVITY),
|
||||
SANS_SERIF("sans_serif", JsonKeys.FONT),
|
||||
DEFAULT("default", JsonKeys.FONT),
|
||||
DEFAULT_BOLD("default_bold", JsonKeys.FONT),
|
||||
MONOSPACE("monospace", JsonKeys.FONT),
|
||||
SERIF("serif", JsonKeys.FONT),
|
||||
ROBOTO_CONDENSED_BOLD("roboto_condensed_bold", JsonKeys.FONT),
|
||||
ROBOTO_CONDENSED_LIGHT("roboto_condensed_light", JsonKeys.FONT),
|
||||
ROBOTO_CONDENSED_REGULAR("roboto_condensed_regular", JsonKeys.FONT),
|
||||
ROBOTO_SLAB_LIGHT("roboto_slab_light", JsonKeys.FONT),
|
||||
NORMAL("normal", JsonKeys.FONTSTYLE),
|
||||
BOLD("bold", JsonKeys.FONTSTYLE),
|
||||
BOLD_ITALIC("bold_italic", JsonKeys.FONTSTYLE),
|
||||
ITALIC("italic", JsonKeys.FONTSTYLE),
|
||||
BGCOLOR("bgColor", JsonKeys.COLOR),
|
||||
BGCOLOR1("bgColor", JsonKeys.FONTCOLOR)
|
||||
}
|
||||
|
||||
enum class ViewType(@StringRes val comment: Int?) {
|
||||
NONE(null),
|
||||
TEXTVIEW(null),
|
||||
IMAGEVIEW(null),
|
||||
ALLVIEWS(null)
|
||||
}
|
||||
|
||||
class ZipWatchfaceFormat {
|
||||
companion object {
|
||||
|
||||
const val CUSTOM_WF_EXTENTION = ".zip"
|
||||
const val CUSTOM_JSON_FILE = "CustomWatchface.json"
|
||||
const val CWF_EXTENTION = ".zip"
|
||||
const val CWF_JSON_FILE = "CustomWatchface.json"
|
||||
|
||||
fun loadCustomWatchface(cwfFile: File, authorization: Boolean): CustomWatchfaceData? {
|
||||
fun loadCustomWatchface(cwfFile: File, authorization: Boolean): CwfData? {
|
||||
var json = JSONObject()
|
||||
var metadata: CustomWatchfaceMetadataMap = mutableMapOf()
|
||||
val drawableDatas: CustomWatchfaceDrawableDataMap = mutableMapOf()
|
||||
var metadata: CwfMetadataMap = mutableMapOf()
|
||||
val drawableDatas: CwfDrawableDataMap = mutableMapOf()
|
||||
|
||||
try {
|
||||
val zipInputStream = ZipInputStream(cwfFile.inputStream())
|
||||
|
@ -143,25 +246,25 @@ class ZipWatchfaceFormat {
|
|||
}
|
||||
zipInputStream.closeEntry()
|
||||
|
||||
if (entryName == CUSTOM_JSON_FILE) {
|
||||
if (entryName == CWF_JSON_FILE) {
|
||||
val jsonString = byteArrayOutputStream.toByteArray().toString(Charsets.UTF_8)
|
||||
json = JSONObject(jsonString)
|
||||
metadata = loadMetadata(json)
|
||||
metadata[CustomWatchfaceMetadataKey.CWF_FILENAME] = cwfFile.name
|
||||
metadata[CustomWatchfaceMetadataKey.CWF_AUTHORIZATION] = authorization.toString()
|
||||
metadata[CwfMetadataKey.CWF_FILENAME] = cwfFile.name
|
||||
metadata[CwfMetadataKey.CWF_AUTHORIZATION] = authorization.toString()
|
||||
} else {
|
||||
val customWatchfaceDrawableDataKey = CustomWatchfaceDrawableDataKey.fromFileName(entryName)
|
||||
val cwfDrawableFileMap = CwfDrawableFileMap.fromFileName(entryName)
|
||||
val drawableFormat = DrawableFormat.fromFileName(entryName)
|
||||
if (customWatchfaceDrawableDataKey != CustomWatchfaceDrawableDataKey.UNKNOWN && drawableFormat != DrawableFormat.UNKNOWN) {
|
||||
drawableDatas[customWatchfaceDrawableDataKey] = DrawableData(byteArrayOutputStream.toByteArray(), drawableFormat)
|
||||
if (cwfDrawableFileMap != CwfDrawableFileMap.UNKNOWN && drawableFormat != DrawableFormat.UNKNOWN) {
|
||||
drawableDatas[cwfDrawableFileMap] = DrawableData(byteArrayOutputStream.toByteArray(), drawableFormat)
|
||||
}
|
||||
}
|
||||
zipEntry = zipInputStream.nextEntry
|
||||
}
|
||||
|
||||
// Valid CWF file must contains a valid json file with a name within metadata and a custom watchface image
|
||||
if (metadata.containsKey(CustomWatchfaceMetadataKey.CWF_NAME) && drawableDatas.containsKey(CustomWatchfaceDrawableDataKey.CUSTOM_WATCHFACE))
|
||||
return CustomWatchfaceData(json.toString(4), metadata, drawableDatas)
|
||||
if (metadata.containsKey(CwfMetadataKey.CWF_NAME) && drawableDatas.containsKey(CwfDrawableFileMap.CUSTOM_WATCHFACE))
|
||||
return CwfData(json.toString(4), metadata, drawableDatas)
|
||||
else
|
||||
return null
|
||||
|
||||
|
@ -170,14 +273,14 @@ class ZipWatchfaceFormat {
|
|||
}
|
||||
}
|
||||
|
||||
fun saveCustomWatchface(file: File, customWatchface: CustomWatchfaceData) {
|
||||
fun saveCustomWatchface(file: File, customWatchface: CwfData) {
|
||||
|
||||
try {
|
||||
val outputStream = FileOutputStream(file)
|
||||
val zipOutputStream = ZipOutputStream(BufferedOutputStream(outputStream))
|
||||
|
||||
// Ajouter le fichier JSON au ZIP
|
||||
val jsonEntry = ZipEntry(CUSTOM_JSON_FILE)
|
||||
val jsonEntry = ZipEntry(CWF_JSON_FILE)
|
||||
zipOutputStream.putNextEntry(jsonEntry)
|
||||
zipOutputStream.write(customWatchface.json.toByteArray())
|
||||
zipOutputStream.closeEntry()
|
||||
|
@ -196,13 +299,13 @@ class ZipWatchfaceFormat {
|
|||
|
||||
}
|
||||
|
||||
fun loadMetadata(contents: JSONObject): CustomWatchfaceMetadataMap {
|
||||
val metadata: CustomWatchfaceMetadataMap = mutableMapOf()
|
||||
fun loadMetadata(contents: JSONObject): CwfMetadataMap {
|
||||
val metadata: CwfMetadataMap = mutableMapOf()
|
||||
|
||||
if (contents.has("metadata")) {
|
||||
val meta = contents.getJSONObject("metadata")
|
||||
if (contents.has(JsonKeys.METADATA.key)) {
|
||||
val meta = contents.getJSONObject(JsonKeys.METADATA.key)
|
||||
for (key in meta.keys()) {
|
||||
val metaKey = CustomWatchfaceMetadataKey.fromKey(key)
|
||||
val metaKey = CwfMetadataKey.fromKey(key)
|
||||
if (metaKey != null) {
|
||||
metadata[metaKey] = meta.getString(key)
|
||||
}
|
||||
|
|
|
@ -284,7 +284,7 @@ sealed class EventData : Event() {
|
|||
}
|
||||
@Serializable
|
||||
data class ActionSetCustomWatchface(
|
||||
val customWatchfaceData: CustomWatchfaceData
|
||||
val customWatchfaceData: CwfData
|
||||
) : EventData()
|
||||
|
||||
@Serializable
|
||||
|
|
|
@ -2,7 +2,7 @@ package info.nightscout.interfaces.maintenance
|
|||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceData
|
||||
import info.nightscout.rx.weardata.CwfData
|
||||
|
||||
interface ImportExportPrefs {
|
||||
|
||||
|
@ -11,7 +11,7 @@ interface ImportExportPrefs {
|
|||
fun importSharedPreferences(fragment: Fragment)
|
||||
fun importCustomWatchface(activity: FragmentActivity)
|
||||
fun importCustomWatchface(fragment: Fragment)
|
||||
fun exportCustomWatchface(customWatchface: CustomWatchfaceData)
|
||||
fun exportCustomWatchface(customWatchface: CwfData)
|
||||
fun prefsFileExists(): Boolean
|
||||
fun verifyStoragePermissions(fragment: Fragment, onGranted: Runnable)
|
||||
fun exportSharedPreferences(f: Fragment)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package info.nightscout.interfaces.maintenance
|
||||
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceData
|
||||
import info.nightscout.rx.weardata.CwfData
|
||||
import java.io.File
|
||||
|
||||
interface PrefFileListProvider {
|
||||
|
@ -13,7 +13,7 @@ interface PrefFileListProvider {
|
|||
fun newExportCsvFile(): File
|
||||
fun newCwfFile(filename: String): File
|
||||
fun listPreferenceFiles(loadMetadata: Boolean = false): MutableList<PrefsFile>
|
||||
fun listCustomWatchfaceFiles(): MutableList<CustomWatchfaceData>
|
||||
fun listCustomWatchfaceFiles(): MutableList<CwfData>
|
||||
fun checkMetadata(metadata: Map<PrefsMetadataKey, PrefMetadata>): Map<PrefsMetadataKey, PrefMetadata>
|
||||
fun formatExportedAgo(utcTime: String): String
|
||||
}
|
|
@ -55,8 +55,8 @@ import info.nightscout.rx.events.EventAppExit
|
|||
import info.nightscout.rx.events.EventDiaconnG8PumpLogReset
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceData
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceMetadataKey
|
||||
import info.nightscout.rx.weardata.CwfData
|
||||
import info.nightscout.rx.weardata.CwfMetadataKey
|
||||
import info.nightscout.rx.weardata.ZipWatchfaceFormat
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
|
@ -315,9 +315,9 @@ class ImportExportPrefsImpl @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun exportCustomWatchface(customWatchface: CustomWatchfaceData) {
|
||||
override fun exportCustomWatchface(customWatchface: CwfData) {
|
||||
prefFileList.ensureExportDirExists()
|
||||
val newFile = prefFileList.newCwfFile(customWatchface.metadata[CustomWatchfaceMetadataKey.CWF_FILENAME] ?:"")
|
||||
val newFile = prefFileList.newCwfFile(customWatchface.metadata[CwfMetadataKey.CWF_FILENAME] ?:"")
|
||||
ZipWatchfaceFormat.saveCustomWatchface(newFile, customWatchface)
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ import info.nightscout.interfaces.maintenance.PrefsMetadataKey
|
|||
import info.nightscout.interfaces.maintenance.PrefsStatus
|
||||
import info.nightscout.interfaces.storage.Storage
|
||||
import info.nightscout.interfaces.versionChecker.VersionCheckerUtils
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceData
|
||||
import info.nightscout.rx.weardata.CwfData
|
||||
import info.nightscout.rx.weardata.ZipWatchfaceFormat
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
|
@ -92,11 +92,11 @@ class PrefFileListProviderImpl @Inject constructor(
|
|||
return prefFiles
|
||||
}
|
||||
|
||||
override fun listCustomWatchfaceFiles(): MutableList<CustomWatchfaceData> {
|
||||
val customWatchfaceFiles = mutableListOf<CustomWatchfaceData>()
|
||||
override fun listCustomWatchfaceFiles(): MutableList<CwfData> {
|
||||
val customWatchfaceFiles = mutableListOf<CwfData>()
|
||||
val customAwtchfaceAuthorization = sp.getBoolean(info.nightscout.core.utils.R.string.key_wear_custom_watchface_autorization, false)
|
||||
// searching dedicated dir, only for new CWF format
|
||||
exportsPath.walk().filter { it.isFile && it.name.endsWith(ZipWatchfaceFormat.CUSTOM_WF_EXTENTION) }.forEach { file ->
|
||||
exportsPath.walk().filter { it.isFile && it.name.endsWith(ZipWatchfaceFormat.CWF_EXTENTION) }.forEach { file ->
|
||||
// Here loadCustomWatchface will unzip, check and load CustomWatchface
|
||||
ZipWatchfaceFormat.loadCustomWatchface(file, customAwtchfaceAuthorization)?.also { customWatchface ->
|
||||
customWatchfaceFiles.add(customWatchface)
|
||||
|
@ -148,7 +148,7 @@ class PrefFileListProviderImpl @Inject constructor(
|
|||
}
|
||||
override fun newCwfFile(filename: String): File {
|
||||
val timeLocal = LocalDateTime.now().toString(DateTimeFormat.forPattern("yyyy-MM-dd'_'HHmmss"))
|
||||
return File(exportsPath, "${filename}_$timeLocal${ZipWatchfaceFormat.CUSTOM_WF_EXTENTION}")
|
||||
return File(exportsPath, "${filename}_$timeLocal${ZipWatchfaceFormat.CWF_EXTENTION}")
|
||||
}
|
||||
|
||||
// check metadata for known issues, change their status and add info with explanations
|
||||
|
|
|
@ -19,11 +19,12 @@ import info.nightscout.rx.bus.RxBus
|
|||
import info.nightscout.rx.events.EventMobileDataToWear
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.weardata.CUSTOM_VERSION
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceData
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceDrawableDataKey
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceMetadataKey.*
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceMetadataMap
|
||||
import info.nightscout.rx.weardata.CwfData
|
||||
import info.nightscout.rx.weardata.CwfDrawableFileMap
|
||||
import info.nightscout.rx.weardata.CwfMetadataKey.*
|
||||
import info.nightscout.rx.weardata.CwfMetadataMap
|
||||
import info.nightscout.rx.weardata.EventData
|
||||
import info.nightscout.shared.extensions.toVisibility
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import javax.inject.Inject
|
||||
|
@ -54,7 +55,7 @@ class CustomWatchfaceImportListActivity: TranslatedDaggerAppCompatActivity() {
|
|||
binding.recyclerview.adapter = RecyclerViewAdapter(prefFileListProvider.listCustomWatchfaceFiles())
|
||||
}
|
||||
|
||||
inner class RecyclerViewAdapter internal constructor(private var customWatchfaceFileList: List<CustomWatchfaceData>) : RecyclerView.Adapter<RecyclerViewAdapter.PrefFileViewHolder>() {
|
||||
inner class RecyclerViewAdapter internal constructor(private var customWatchfaceFileList: List<CwfData>) : RecyclerView.Adapter<RecyclerViewAdapter.PrefFileViewHolder>() {
|
||||
|
||||
inner class PrefFileViewHolder(val customWatchfaceImportListItemBinding: CustomWatchfaceImportListItemBinding) : RecyclerView.ViewHolder(customWatchfaceImportListItemBinding.root) {
|
||||
|
||||
|
@ -62,7 +63,7 @@ class CustomWatchfaceImportListActivity: TranslatedDaggerAppCompatActivity() {
|
|||
with(customWatchfaceImportListItemBinding) {
|
||||
root.isClickable = true
|
||||
customWatchfaceImportListItemBinding.root.setOnClickListener {
|
||||
val customWatchfaceFile = filelistName.tag as CustomWatchfaceData
|
||||
val customWatchfaceFile = filelistName.tag as CwfData
|
||||
val customWF = EventData.ActionSetCustomWatchface(customWatchfaceFile)
|
||||
val i = Intent()
|
||||
setResult(FragmentActivity.RESULT_OK, i)
|
||||
|
@ -85,7 +86,7 @@ class CustomWatchfaceImportListActivity: TranslatedDaggerAppCompatActivity() {
|
|||
override fun onBindViewHolder(holder: PrefFileViewHolder, position: Int) {
|
||||
val customWatchfaceFile = customWatchfaceFileList[position]
|
||||
val metadata = customWatchfaceFile.metadata
|
||||
val drawable = customWatchfaceFile.drawableDatas[CustomWatchfaceDrawableDataKey
|
||||
val drawable = customWatchfaceFile.drawableDatas[CwfDrawableFileMap
|
||||
.CUSTOM_WATCHFACE]?.toDrawable(resources)
|
||||
with(holder.customWatchfaceImportListItemBinding) {
|
||||
filelistName.text = rh.gs(info.nightscout.shared.R.string.metadata_wear_import_filename, metadata[CWF_FILENAME])
|
||||
|
@ -101,6 +102,9 @@ class CustomWatchfaceImportListActivity: TranslatedDaggerAppCompatActivity() {
|
|||
cwfVersion.text = rh.gs(CWF_VERSION.label, metadata[CWF_VERSION] ?:"")
|
||||
val colorAttr = if (checkCustomVersion(metadata)) info.nightscout.core.ui.R.attr.metadataTextOkColor else info.nightscout.core.ui.R.attr.metadataTextWarningColor
|
||||
cwfVersion.setTextColor(rh.gac(cwfVersion.context, colorAttr))
|
||||
prefWarning.visibility = metadata.keys.any { it.isPref }.toVisibility()
|
||||
cwfPrefNumber.text = "${metadata.count { it.key.isPref }}"
|
||||
cwfPrefNumber.visibility=prefWarning.visibility
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -113,7 +117,7 @@ class CustomWatchfaceImportListActivity: TranslatedDaggerAppCompatActivity() {
|
|||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
private fun checkCustomVersion(metadata: CustomWatchfaceMetadataMap): Boolean {
|
||||
private fun checkCustomVersion(metadata: CwfMetadataMap): Boolean {
|
||||
metadata[CWF_VERSION]?.let { version ->
|
||||
val currentAppVer = versionCheckerUtils.versionDigits(CUSTOM_VERSION)
|
||||
val metadataVer = versionCheckerUtils.versionDigits(version)
|
||||
|
|
|
@ -90,18 +90,24 @@
|
|||
android:textSize="11sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/created_at"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="0dp"
|
||||
android:paddingStart="0dp"
|
||||
android:paddingEnd="10dp"
|
||||
android:text="created at: lqkjdshflqkdjhflqdskfhlqdsf"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?attr/importListFileNameColor"
|
||||
android:textSize="11sp" />
|
||||
<TextView
|
||||
android:id="@+id/created_at"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="0dp"
|
||||
android:paddingStart="0dp"
|
||||
android:paddingEnd="10dp"
|
||||
android:text="created at: lqkjdshflqkdjhflqdskfhlqdsf"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?attr/importListFileNameColor"
|
||||
android:textSize="11sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="0dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cwf_version"
|
||||
|
@ -111,10 +117,39 @@
|
|||
android:layout_marginTop="0dp"
|
||||
android:paddingStart="0dp"
|
||||
android:paddingEnd="10dp"
|
||||
android:layout_weight="1"
|
||||
android:text="CWF version:"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?attr/importListFileNameColor"
|
||||
android:textSize="11sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cwf_pref_number"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginTop="0dp"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?attr/warningColor"
|
||||
android:textSize="11sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/pref_warning"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="1dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="1dp"
|
||||
android:foreground="@drawable/ic_meta_format"
|
||||
android:foregroundTint="?attr/warningColor" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.StringRes
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.core.ui.toast.ToastUtils
|
||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
|
@ -16,9 +15,9 @@ import info.nightscout.rx.bus.RxBus
|
|||
import info.nightscout.rx.events.EventMobileToWear
|
||||
import info.nightscout.rx.events.EventWearUpdateGui
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceData
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceDrawableDataKey
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceMetadataKey
|
||||
import info.nightscout.rx.weardata.CwfData
|
||||
import info.nightscout.rx.weardata.CwfDrawableFileMap
|
||||
import info.nightscout.rx.weardata.CwfMetadataKey
|
||||
import info.nightscout.rx.weardata.EventData
|
||||
import info.nightscout.shared.extensions.toVisibility
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
|
@ -106,8 +105,8 @@ class WearFragment : DaggerFragment() {
|
|||
_binding ?: return
|
||||
wearPlugin.savedCustomWatchface?.let {
|
||||
wearPlugin.checkCustomWatchfacePreferences()
|
||||
binding.customName.text = rh.gs(R.string.wear_custom_watchface, it.metadata[CustomWatchfaceMetadataKey.CWF_NAME])
|
||||
binding.coverChart.setImageDrawable(it.drawableDatas[CustomWatchfaceDrawableDataKey.CUSTOM_WATCHFACE]?.toDrawable(resources))
|
||||
binding.customName.text = rh.gs(R.string.wear_custom_watchface, it.metadata[CwfMetadataKey.CWF_NAME])
|
||||
binding.coverChart.setImageDrawable(it.drawableDatas[CwfDrawableFileMap.CUSTOM_WATCHFACE]?.toDrawable(resources))
|
||||
} ?:apply {
|
||||
binding.customName.text = rh.gs(R.string.wear_custom_watchface, rh.gs(info.nightscout.shared.R.string.wear_default_watchface))
|
||||
binding.coverChart.setImageDrawable(null)
|
||||
|
@ -116,7 +115,7 @@ class WearFragment : DaggerFragment() {
|
|||
binding.customWatchfaceLayout.visibility = (wearPlugin.connectedDevice != rh.gs(R.string.no_watch_connected)).toVisibility()
|
||||
}
|
||||
|
||||
private fun loadCustom(cwf: CustomWatchfaceData) {
|
||||
private fun loadCustom(cwf: CwfData) {
|
||||
wearPlugin.savedCustomWatchface = cwf
|
||||
}
|
||||
}
|
|
@ -20,8 +20,8 @@ import info.nightscout.rx.events.EventOverviewBolusProgress
|
|||
import info.nightscout.rx.events.EventPreferenceChange
|
||||
import info.nightscout.rx.events.EventWearUpdateGui
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceData
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceMetadataKey
|
||||
import info.nightscout.rx.weardata.CwfData
|
||||
import info.nightscout.rx.weardata.CwfMetadataKey
|
||||
import info.nightscout.rx.weardata.EventData
|
||||
import info.nightscout.shared.interfaces.ResourceHelper
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
|
@ -58,7 +58,7 @@ class WearPlugin @Inject constructor(
|
|||
private val disposable = CompositeDisposable()
|
||||
|
||||
var connectedDevice = "---"
|
||||
var savedCustomWatchface: CustomWatchfaceData? = null
|
||||
var savedCustomWatchface: CwfData? = null
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
@ -113,10 +113,10 @@ class WearPlugin @Inject constructor(
|
|||
fun checkCustomWatchfacePreferences() {
|
||||
savedCustomWatchface?.let { cwf ->
|
||||
val cwf_authorization = sp.getBoolean(info.nightscout.core.utils.R.string.key_wear_custom_watchface_autorization, false)
|
||||
if (cwf_authorization != cwf.metadata[CustomWatchfaceMetadataKey.CWF_AUTHORIZATION]?.toBooleanStrictOrNull()) {
|
||||
if (cwf_authorization != cwf.metadata[CwfMetadataKey.CWF_AUTHORIZATION]?.toBooleanStrictOrNull()) {
|
||||
// resend new customWatchface to Watch with updated authorization for preferences update
|
||||
val newCwf = cwf.copy()
|
||||
newCwf.metadata[CustomWatchfaceMetadataKey.CWF_AUTHORIZATION] = sp.getBoolean(info.nightscout.core.utils.R.string.key_wear_custom_watchface_autorization, false).toString()
|
||||
newCwf.metadata[CwfMetadataKey.CWF_AUTHORIZATION] = sp.getBoolean(info.nightscout.core.utils.R.string.key_wear_custom_watchface_autorization, false).toString()
|
||||
rxBus.send(EventMobileDataToWear(EventData.ActionSetCustomWatchface(newCwf)))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -357,7 +357,7 @@
|
|||
<string name="wear_predictions_title">Predictions</string>
|
||||
<string name="wear_custom_watchface_settings">Custom Watchface Settings</string>
|
||||
<string name="wear_custom_watchface_authorization_title">Custom Watchface Authorization</string>
|
||||
<string name="wear_custom_watchface_authorization_summary">Authorize loaded Custom Watchface to modify AAPS and Watch settings according to the watchface design</string>
|
||||
<string name="wear_custom_watchface_authorization_summary">Authorize loaded custom watchface to change and lock some watch display settings to suit watchface design</string>
|
||||
<string name="wear_custom_watchface">Custom Watchface: %1$s</string>
|
||||
<string name="wear_load_watchface">Load Watchface</string>
|
||||
<string name="wear_send_watchface">Send Watchface</string>
|
||||
|
|
|
@ -33,14 +33,17 @@ import info.nightscout.androidaps.databinding.ActivityCustomBinding
|
|||
import info.nightscout.androidaps.watchfaces.utils.BaseWatchFace
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import info.nightscout.rx.weardata.CUSTOM_VERSION
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceData
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceDrawableDataKey
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceDrawableDataMap
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceMetadataKey
|
||||
import info.nightscout.rx.weardata.CustomWatchfaceMetadataMap
|
||||
import info.nightscout.rx.weardata.CwfData
|
||||
import info.nightscout.rx.weardata.CwfDrawableFileMap
|
||||
import info.nightscout.rx.weardata.CwfDrawableDataMap
|
||||
import info.nightscout.rx.weardata.CwfMetadataKey
|
||||
import info.nightscout.rx.weardata.CwfMetadataMap
|
||||
import info.nightscout.rx.weardata.DrawableData
|
||||
import info.nightscout.rx.weardata.DrawableFormat
|
||||
import info.nightscout.rx.weardata.EventData
|
||||
import info.nightscout.rx.weardata.JsonKeyValues
|
||||
import info.nightscout.rx.weardata.JsonKeys.*
|
||||
import info.nightscout.rx.weardata.ViewKeys
|
||||
import info.nightscout.rx.weardata.ZipWatchfaceFormat
|
||||
import info.nightscout.shared.extensions.toVisibility
|
||||
import info.nightscout.shared.extensions.toVisibilityKeepSpace
|
||||
|
@ -86,7 +89,7 @@ class CustomWatchface : BaseWatchFace() {
|
|||
@SuppressLint("UseCompatLoadingForDrawables")
|
||||
override fun setDataFields() {
|
||||
super.setDataFields()
|
||||
binding.direction2.setImageDrawable(this.resources.getDrawable(TrendArrow.icon(singleBg.slopeArrow)))
|
||||
binding.direction2.setImageDrawable(this.resources.getDrawable(TrendArrowMap.icon(singleBg.slopeArrow)))
|
||||
// rotate the second hand.
|
||||
binding.secondHand.rotation = TimeOfDay().secondOfMinute * 6f
|
||||
// rotate the minute hand.
|
||||
|
@ -133,8 +136,8 @@ class CustomWatchface : BaseWatchFace() {
|
|||
}
|
||||
|
||||
override fun updateSecondVisibility() {
|
||||
binding.second.visibility = showSecond.toVisibility()
|
||||
binding.secondHand.visibility = showSecond.toVisibility()
|
||||
binding.second.visibility = (binding.second.visibility == View.VISIBLE && showSecond).toVisibility()
|
||||
binding.secondHand.visibility = (binding.secondHand.visibility == View.VISIBLE && showSecond).toVisibility()
|
||||
}
|
||||
|
||||
@SuppressLint("UseCompatLoadingForDrawables")
|
||||
|
@ -145,17 +148,17 @@ class CustomWatchface : BaseWatchFace() {
|
|||
try {
|
||||
val json = JSONObject(it.customWatchfaceData.json)
|
||||
val drawableDataMap = it.customWatchfaceData.drawableDatas
|
||||
enableSecond = (if (json.has("enableSecond")) json.getBoolean("enableSecond") else false) && sp.getBoolean(R.string.key_show_seconds, true)
|
||||
enableSecond = (if (json.has(ENABLESECOND.key)) json.getBoolean(ENABLESECOND.key) else false) && sp.getBoolean(R.string.key_show_seconds, true)
|
||||
|
||||
highColor = if (json.has("highColor")) Color.parseColor(json.getString("highColor")) else ContextCompat.getColor(this, R.color.dark_highColor)
|
||||
midColor = if (json.has("midColor")) Color.parseColor(json.getString("midColor")) else ContextCompat.getColor(this, R.color.inrange)
|
||||
lowColor = if (json.has("lowColor")) Color.parseColor(json.getString("lowColor")) else ContextCompat.getColor(this, R.color.low)
|
||||
lowBatColor = if (json.has("lowBatColor")) Color.parseColor(json.getString("lowBatColor")) else ContextCompat.getColor(this, R.color.dark_uploaderBatteryEmpty)
|
||||
carbColor = if (json.has("carbColor")) Color.parseColor(json.getString("carbColor")) else ContextCompat.getColor(this, R.color.carbs)
|
||||
basalBackgroundColor = if (json.has("basalBackgroundColor")) Color.parseColor(json.getString("basalBackgroundColor")) else ContextCompat.getColor(this, R.color.basal_dark)
|
||||
basalCenterColor = if (json.has("basalCenterColor")) Color.parseColor(json.getString("basalCenterColor")) else ContextCompat.getColor(this, R.color.basal_light)
|
||||
gridColor = if (json.has("gridColor")) Color.parseColor(json.getString("gridColor")) else Color.WHITE
|
||||
pointSize = if (json.has("pointSize")) json.getInt("pointSize") else 2
|
||||
highColor = if (json.has(HIGHCOLOR.key)) Color.parseColor(json.getString(HIGHCOLOR.key)) else ContextCompat.getColor(this, R.color.dark_highColor)
|
||||
midColor = if (json.has(MIDCOLOR.key)) Color.parseColor(json.getString(MIDCOLOR.key)) else ContextCompat.getColor(this, R.color.inrange)
|
||||
lowColor = if (json.has(LOWCOLOR.key)) Color.parseColor(json.getString(LOWCOLOR.key)) else ContextCompat.getColor(this, R.color.low)
|
||||
lowBatColor = if (json.has(LOWBATCOLOR.key)) Color.parseColor(json.getString(LOWBATCOLOR.key)) else ContextCompat.getColor(this, R.color.dark_uploaderBatteryEmpty)
|
||||
carbColor = if (json.has(CARBCOLOR.key)) Color.parseColor(json.getString(CARBCOLOR.key)) else ContextCompat.getColor(this, R.color.carbs)
|
||||
basalBackgroundColor = if (json.has(BASALBACKGROUNDCOLOR.key)) Color.parseColor(json.getString(BASALBACKGROUNDCOLOR.key)) else ContextCompat.getColor(this, R.color.basal_dark)
|
||||
basalCenterColor = if (json.has(BASALCENTERCOLOR.key)) Color.parseColor(json.getString(BASALCENTERCOLOR.key)) else ContextCompat.getColor(this, R.color.basal_light)
|
||||
gridColor = if (json.has(GRIDCOLOR.key)) Color.parseColor(json.getString(GRIDCOLOR.key)) else Color.WHITE
|
||||
pointSize = if (json.has(POINTSIZE.key)) json.getInt(POINTSIZE.key) else 2
|
||||
bgColor = when (singleBg.sgvLevel) {
|
||||
1L -> highColor
|
||||
0L -> midColor
|
||||
|
@ -163,55 +166,55 @@ class CustomWatchface : BaseWatchFace() {
|
|||
else -> midColor
|
||||
}
|
||||
val backGroundDrawable = when (singleBg.sgvLevel) {
|
||||
1L -> drawableDataMap[CustomWatchfaceDrawableDataKey.BACKGROUND_HIGH]?.toDrawable(resources) ?: drawableDataMap[CustomWatchfaceDrawableDataKey.BACKGROUND]?.toDrawable(resources)
|
||||
0L -> drawableDataMap[CustomWatchfaceDrawableDataKey.BACKGROUND]?.toDrawable(resources)
|
||||
-1L -> drawableDataMap[CustomWatchfaceDrawableDataKey.BACKGROUND_LOW]?.toDrawable(resources) ?: drawableDataMap[CustomWatchfaceDrawableDataKey.BACKGROUND]?.toDrawable(resources)
|
||||
else -> drawableDataMap[CustomWatchfaceDrawableDataKey.BACKGROUND]?.toDrawable(resources)
|
||||
1L -> drawableDataMap[CwfDrawableFileMap.BACKGROUND_HIGH]?.toDrawable(resources) ?: drawableDataMap[CwfDrawableFileMap.BACKGROUND]?.toDrawable(resources)
|
||||
0L -> drawableDataMap[CwfDrawableFileMap.BACKGROUND]?.toDrawable(resources)
|
||||
-1L -> drawableDataMap[CwfDrawableFileMap.BACKGROUND_LOW]?.toDrawable(resources) ?: drawableDataMap[CwfDrawableFileMap.BACKGROUND]?.toDrawable(resources)
|
||||
else -> drawableDataMap[CwfDrawableFileMap.BACKGROUND]?.toDrawable(resources)
|
||||
}
|
||||
|
||||
binding.mainLayout.forEach { view ->
|
||||
CustomViews.fromId(view.id)?.let { id ->
|
||||
ViewMap.fromId(view.id)?.let { id ->
|
||||
if (json.has(id.key)) {
|
||||
val viewJson = json.getJSONObject(id.key)
|
||||
val wrapContent = LayoutParams.WRAP_CONTENT
|
||||
val width = if (viewJson.has("width")) (viewJson.getInt("width") * zoomFactor).toInt() else wrapContent
|
||||
val height = if (viewJson.has("height")) (viewJson.getInt("height") * zoomFactor).toInt() else wrapContent
|
||||
val width = if (viewJson.has(WIDTH.key)) (viewJson.getInt(WIDTH.key) * zoomFactor).toInt() else wrapContent
|
||||
val height = if (viewJson.has(HEIGHT.key)) (viewJson.getInt(HEIGHT.key) * zoomFactor).toInt() else wrapContent
|
||||
val params = FrameLayout.LayoutParams(width, height)
|
||||
params.topMargin = if (viewJson.has("topmargin")) (viewJson.getInt("topmargin") * zoomFactor).toInt() else 0
|
||||
params.leftMargin = if (viewJson.has("leftmargin")) (viewJson.getInt("leftmargin") * zoomFactor).toInt() else 0
|
||||
params.topMargin = if (viewJson.has(TOPMARGIN.key)) (viewJson.getInt(TOPMARGIN.key) * zoomFactor).toInt() else 0
|
||||
params.leftMargin = if (viewJson.has(LEFTMARGIN.key)) (viewJson.getInt(LEFTMARGIN.key) * zoomFactor).toInt() else 0
|
||||
view.layoutParams = params
|
||||
view.visibility = if (viewJson.has("visibility")) setVisibility(viewJson.getString("visibility"), id.visibility(sp)) else View.GONE
|
||||
view.visibility = if (viewJson.has(VISIBILITY.key)) setVisibility(viewJson.getString(VISIBILITY.key), id.visibility(sp)) else View.GONE
|
||||
if (view is TextView) {
|
||||
view.rotation = if (viewJson.has("rotation")) viewJson.getInt("rotation").toFloat() else 0F
|
||||
view.setTextSize(TypedValue.COMPLEX_UNIT_PX, ((if (viewJson.has("textsize")) viewJson.getInt("textsize") else 22) * zoomFactor).toFloat())
|
||||
view.gravity = GravityMap.gravity(if (viewJson.has("gravity")) viewJson.getString("gravity") else GravityMap.CENTER.key)
|
||||
view.rotation = if (viewJson.has(ROTATION.key)) viewJson.getInt(ROTATION.key).toFloat() else 0F
|
||||
view.setTextSize(TypedValue.COMPLEX_UNIT_PX, ((if (viewJson.has(TEXTSIZE.key)) viewJson.getInt(TEXTSIZE.key) else 22) * zoomFactor).toFloat())
|
||||
view.gravity = GravityMap.gravity(if (viewJson.has(GRAVITY.key)) viewJson.getString(GRAVITY.key) else GravityMap.CENTER.key)
|
||||
view.setTypeface(
|
||||
FontMap.font(if (viewJson.has("font")) viewJson.getString("font") else FontMap.DEFAULT.key),
|
||||
StyleMap.style(if (viewJson.has("fontStyle")) viewJson.getString("fontStyle") else StyleMap.NORMAL.key)
|
||||
FontMap.font(if (viewJson.has(FONT.key)) viewJson.getString(FONT.key) else FontMap.DEFAULT.key),
|
||||
StyleMap.style(if (viewJson.has(FONTSTYLE.key)) viewJson.getString(FONTSTYLE.key) else StyleMap.NORMAL.key)
|
||||
)
|
||||
if (viewJson.has("fontColor"))
|
||||
view.setTextColor(getColor(viewJson.getString("fontColor")))
|
||||
if (viewJson.has(FONTCOLOR.key))
|
||||
view.setTextColor(getColor(viewJson.getString(FONTCOLOR.key)))
|
||||
|
||||
if (viewJson.has("textvalue"))
|
||||
view.text = viewJson.getString("textvalue")
|
||||
if (viewJson.has(TEXTVALUE.key))
|
||||
view.text = viewJson.getString(TEXTVALUE.key)
|
||||
}
|
||||
|
||||
if (view is ImageView) {
|
||||
view.clearColorFilter()
|
||||
val drawable = if (id.key == CustomWatchfaceDrawableDataKey.BACKGROUND.key)
|
||||
val drawable = if (id.key == CwfDrawableFileMap.BACKGROUND.key)
|
||||
backGroundDrawable
|
||||
else
|
||||
drawableDataMap[CustomWatchfaceDrawableDataKey.fromKey(id.key)]?.toDrawable(resources)
|
||||
drawableDataMap[CwfDrawableFileMap.fromKey(id.key)]?.toDrawable(resources)
|
||||
drawable?.let {
|
||||
if (viewJson.has("color"))
|
||||
it.colorFilter = changeDrawableColor(getColor(viewJson.getString("color")))
|
||||
if (viewJson.has(COLOR.key))
|
||||
it.colorFilter = changeDrawableColor(getColor(viewJson.getString(COLOR.key)))
|
||||
else
|
||||
it.clearColorFilter()
|
||||
view.setImageDrawable(it)
|
||||
} ?: apply {
|
||||
view.setImageDrawable(CustomWatchfaceDrawableDataKey.fromKey(id.key).icon?.let { context.getDrawable(it) })
|
||||
if (viewJson.has("color"))
|
||||
view.setColorFilter(getColor(viewJson.getString("color")))
|
||||
view.setImageDrawable(CwfDrawableFileMap.fromKey(id.key).icon?.let { context.getDrawable(it) })
|
||||
if (viewJson.has(COLOR.key))
|
||||
view.setColorFilter(getColor(viewJson.getString(COLOR.key)))
|
||||
else
|
||||
view.clearColorFilter()
|
||||
}
|
||||
|
@ -226,6 +229,7 @@ class CustomWatchface : BaseWatchFace() {
|
|||
}
|
||||
binding.background.visibility = View.VISIBLE
|
||||
updateSecondVisibility()
|
||||
setSecond() // Update second visibility for time view
|
||||
} catch (e: Exception) {
|
||||
aapsLogger.debug(LTag.WEAR, "Crash during Custom watch load")
|
||||
persistence.store(defaultWatchface(), false) // relaod correct values to avoid crash of watchface
|
||||
|
@ -233,12 +237,12 @@ class CustomWatchface : BaseWatchFace() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun updatePref(metadata: CustomWatchfaceMetadataMap) {
|
||||
val cwf_authorization = metadata[CustomWatchfaceMetadataKey.CWF_AUTHORIZATION]?.toBooleanStrictOrNull()
|
||||
private fun updatePref(metadata: CwfMetadataMap) {
|
||||
val cwf_authorization = metadata[CwfMetadataKey.CWF_AUTHORIZATION]?.toBooleanStrictOrNull()
|
||||
cwf_authorization?.let { authorization ->
|
||||
if (authorization) {
|
||||
PrefMap.values().forEach { pref ->
|
||||
metadata[CustomWatchfaceMetadataKey.fromKey(pref.key)]?.toBooleanStrictOrNull()?.let { sp.putBoolean(pref.prefKey, it) }
|
||||
metadata[CwfMetadataKey.fromKey(pref.key)]?.toBooleanStrictOrNull()?.let { sp.putBoolean(pref.prefKey, it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -246,77 +250,66 @@ class CustomWatchface : BaseWatchFace() {
|
|||
|
||||
private fun defaultWatchface(): EventData.ActionSetCustomWatchface {
|
||||
val metadata = JSONObject()
|
||||
.put(CustomWatchfaceMetadataKey.CWF_NAME.key, getString(info.nightscout.shared.R.string.wear_default_watchface))
|
||||
.put(CustomWatchfaceMetadataKey.CWF_FILENAME.key, getString(info.nightscout.shared.R.string.wear_default_watchface))
|
||||
.put(CustomWatchfaceMetadataKey.CWF_AUTHOR.key, "Philoul")
|
||||
.put(CustomWatchfaceMetadataKey.CWF_CREATED_AT.key, dateUtil.dateString(dateUtil.now()))
|
||||
.put(CustomWatchfaceMetadataKey.CWF_AUTHOR_VERSION.key, CUSTOM_VERSION)
|
||||
.put(CustomWatchfaceMetadataKey.CWF_VERSION.key, CUSTOM_VERSION)
|
||||
.put(CustomWatchfaceMetadataKey.CWF_COMMENT.key, getString(info.nightscout.shared.R.string.default_custom_watchface_comment))
|
||||
.put(CwfMetadataKey.CWF_NAME.key, getString(info.nightscout.shared.R.string.wear_default_watchface))
|
||||
.put(CwfMetadataKey.CWF_FILENAME.key, getString(info.nightscout.shared.R.string.wear_default_watchface))
|
||||
.put(CwfMetadataKey.CWF_AUTHOR.key, "Philoul")
|
||||
.put(CwfMetadataKey.CWF_CREATED_AT.key, dateUtil.dateString(dateUtil.now()))
|
||||
.put(CwfMetadataKey.CWF_AUTHOR_VERSION.key, CUSTOM_VERSION)
|
||||
.put(CwfMetadataKey.CWF_VERSION.key, CUSTOM_VERSION)
|
||||
.put(CwfMetadataKey.CWF_COMMENT.key, getString(info.nightscout.shared.R.string.default_custom_watchface_comment))
|
||||
val json = JSONObject()
|
||||
.put("metadata", metadata)
|
||||
.put("highColor", String.format("#%06X", 0xFFFFFF and highColor))
|
||||
.put("midColor", String.format("#%06X", 0xFFFFFF and midColor))
|
||||
.put("lowColor", String.format("#%06X", 0xFFFFFF and lowColor))
|
||||
.put("lowBatColor", String.format("#%06X", 0xFFFFFF and lowBatColor))
|
||||
.put("carbColor", String.format("#%06X", 0xFFFFFF and carbColor))
|
||||
.put("basalBackgroundColor", String.format("#%06X", 0xFFFFFF and basalBackgroundColor))
|
||||
.put("basalCenterColor", String.format("#%06X", 0xFFFFFF and basalCenterColor))
|
||||
.put("gridColor", String.format("#%06X", 0xFFFFFF and Color.WHITE))
|
||||
.put("pointSize", 2)
|
||||
.put("enableSecond", true)
|
||||
.put(METADATA.key, metadata)
|
||||
.put(HIGHCOLOR.key, String.format("#%06X", 0xFFFFFF and highColor))
|
||||
.put(MIDCOLOR.key, String.format("#%06X", 0xFFFFFF and midColor))
|
||||
.put(LOWCOLOR.key, String.format("#%06X", 0xFFFFFF and lowColor))
|
||||
.put(LOWBATCOLOR.key, String.format("#%06X", 0xFFFFFF and lowBatColor))
|
||||
.put(CARBCOLOR.key, String.format("#%06X", 0xFFFFFF and carbColor))
|
||||
.put(BASALBACKGROUNDCOLOR.key, String.format("#%06X", 0xFFFFFF and basalBackgroundColor))
|
||||
.put(BASALCENTERCOLOR.key, String.format("#%06X", 0xFFFFFF and basalCenterColor))
|
||||
.put(GRIDCOLOR.key, String.format("#%06X", 0xFFFFFF and Color.WHITE))
|
||||
.put(POINTSIZE.key, 2)
|
||||
.put(ENABLESECOND.key, true)
|
||||
|
||||
binding.mainLayout.forEach { view ->
|
||||
val params = view.layoutParams as FrameLayout.LayoutParams
|
||||
CustomViews.fromId(view.id)?.let {
|
||||
ViewMap.fromId(view.id)?.let {
|
||||
if (view is TextView) {
|
||||
json.put(
|
||||
it.key,
|
||||
JSONObject()
|
||||
.put("width", (params.width / zoomFactor).toInt())
|
||||
.put("height", (params.height / zoomFactor).toInt())
|
||||
.put("topmargin", (params.topMargin / zoomFactor).toInt())
|
||||
.put("leftmargin", (params.leftMargin / zoomFactor).toInt())
|
||||
.put("rotation", view.rotation.toInt())
|
||||
.put("visibility", getVisibility(view.visibility))
|
||||
.put("textsize", view.textSize.toInt())
|
||||
.put("gravity", GravityMap.key(view.gravity))
|
||||
.put("font", FontMap.key())
|
||||
.put("fontStyle", StyleMap.key(view.typeface.style))
|
||||
.put("fontColor", String.format("#%06X", 0xFFFFFF and view.currentTextColor))
|
||||
.put(WIDTH.key, (params.width / zoomFactor).toInt())
|
||||
.put(HEIGHT.key, (params.height / zoomFactor).toInt())
|
||||
.put(TOPMARGIN.key, (params.topMargin / zoomFactor).toInt())
|
||||
.put(LEFTMARGIN.key, (params.leftMargin / zoomFactor).toInt())
|
||||
.put(ROTATION.key, view.rotation.toInt())
|
||||
.put(VISIBILITY.key, getVisibility(view.visibility))
|
||||
.put(TEXTSIZE.key, view.textSize.toInt())
|
||||
.put(GRAVITY.key, GravityMap.key(view.gravity))
|
||||
.put(FONT.key, FontMap.key())
|
||||
.put(FONTSTYLE.key, StyleMap.key(view.typeface.style))
|
||||
.put(FONTCOLOR.key, String.format("#%06X", 0xFFFFFF and view.currentTextColor))
|
||||
)
|
||||
}
|
||||
if (view is ImageView) {
|
||||
if (view is ImageView || view is lecho.lib.hellocharts.view.LineChartView) {
|
||||
json.put(
|
||||
it.key,
|
||||
JSONObject()
|
||||
.put("width", (params.width / zoomFactor).toInt())
|
||||
.put("height", (params.height / zoomFactor).toInt())
|
||||
.put("topmargin", (params.topMargin / zoomFactor).toInt())
|
||||
.put("leftmargin", (params.leftMargin / zoomFactor).toInt())
|
||||
.put("visibility", getVisibility(view.visibility))
|
||||
)
|
||||
}
|
||||
if (view is lecho.lib.hellocharts.view.LineChartView) {
|
||||
json.put(
|
||||
it.key,
|
||||
JSONObject()
|
||||
.put("width", (params.width / zoomFactor).toInt())
|
||||
.put("height", (params.height / zoomFactor).toInt())
|
||||
.put("topmargin", (params.topMargin / zoomFactor).toInt())
|
||||
.put("leftmargin", (params.leftMargin / zoomFactor).toInt())
|
||||
.put("visibility", getVisibility(view.visibility))
|
||||
.put(WIDTH.key, (params.width / zoomFactor).toInt())
|
||||
.put(HEIGHT.key, (params.height / zoomFactor).toInt())
|
||||
.put(TOPMARGIN.key, (params.topMargin / zoomFactor).toInt())
|
||||
.put(LEFTMARGIN.key, (params.leftMargin / zoomFactor).toInt())
|
||||
.put(VISIBILITY.key, getVisibility(view.visibility))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
val metadataMap = ZipWatchfaceFormat.loadMetadata(json)
|
||||
val drawableDataMap: CustomWatchfaceDrawableDataMap = mutableMapOf()
|
||||
val drawableDataMap: CwfDrawableDataMap = mutableMapOf()
|
||||
getResourceByteArray(info.nightscout.shared.R.drawable.watchface_custom)?.let {
|
||||
val drawableData = DrawableData(it, DrawableFormat.PNG)
|
||||
drawableDataMap[CustomWatchfaceDrawableDataKey.CUSTOM_WATCHFACE] = drawableData
|
||||
drawableDataMap[CwfDrawableFileMap.CUSTOM_WATCHFACE] = drawableData
|
||||
}
|
||||
return EventData.ActionSetCustomWatchface(CustomWatchfaceData(json.toString(4), metadataMap, drawableDataMap))
|
||||
return EventData.ActionSetCustomWatchface(CwfData(json.toString(4), metadataMap, drawableDataMap))
|
||||
}
|
||||
|
||||
private fun setDefaultColors() {
|
||||
|
@ -331,17 +324,17 @@ class CustomWatchface : BaseWatchFace() {
|
|||
}
|
||||
|
||||
private fun setVisibility(visibility: String, pref: Boolean = true): Int = when (visibility) {
|
||||
"visible" -> pref.toVisibility()
|
||||
"invisible" -> pref.toVisibilityKeepSpace()
|
||||
"gone" -> View.GONE
|
||||
JsonKeyValues.VISIBLE.key -> pref.toVisibility()
|
||||
JsonKeyValues.INVISIBLE.key -> pref.toVisibilityKeepSpace()
|
||||
JsonKeyValues.GONE.key -> View.GONE
|
||||
else -> View.GONE
|
||||
}
|
||||
|
||||
private fun getVisibility(visibility: Int): String = when (visibility) {
|
||||
View.VISIBLE -> "visible"
|
||||
View.INVISIBLE -> "invisible"
|
||||
View.GONE -> "gone"
|
||||
else -> "gone"
|
||||
View.VISIBLE -> JsonKeyValues.VISIBLE.key
|
||||
View.INVISIBLE -> JsonKeyValues.INVISIBLE.key
|
||||
View.GONE -> JsonKeyValues.GONE.key
|
||||
else -> JsonKeyValues.GONE.key
|
||||
}
|
||||
|
||||
private fun getResourceByteArray(resourceId: Int): ByteArray? {
|
||||
|
@ -377,68 +370,67 @@ class CustomWatchface : BaseWatchFace() {
|
|||
}
|
||||
|
||||
private fun getColor(color: String): Int =
|
||||
if (color == "bgColor")
|
||||
if (color == JsonKeyValues.BGCOLOR.key)
|
||||
bgColor
|
||||
else
|
||||
try { Color.parseColor(color) } catch (e: Exception) { Color.GRAY }
|
||||
|
||||
private enum class CustomViews(val key: String, @IdRes val id: Int, @StringRes val pref: Int?) {
|
||||
private enum class ViewMap(val key: String, @IdRes val id: Int, @StringRes val pref: Int?) {
|
||||
|
||||
BACKGROUND(CustomWatchfaceDrawableDataKey.BACKGROUND.key, R.id.background, null),
|
||||
CHART("chart", R.id.chart, null),
|
||||
COVER_CHART(CustomWatchfaceDrawableDataKey.COVERCHART.key, R.id.cover_chart, null),
|
||||
FREETEXT1("freetext1", R.id.freetext1, null),
|
||||
FREETEXT2("freetext2", R.id.freetext2, null),
|
||||
FREETEXT3("freetext3", R.id.freetext3, null),
|
||||
FREETEXT4("freetext4", R.id.freetext4, null),
|
||||
IOB1("iob1", R.id.iob1, R.string.key_show_iob),
|
||||
IOB2("iob2", R.id.iob2, R.string.key_show_iob),
|
||||
COB1("cob1", R.id.cob1, R.string.key_show_cob),
|
||||
COB2("cob2", R.id.cob2, R.string.key_show_cob),
|
||||
DELTA("delta", R.id.delta, R.string.key_show_delta),
|
||||
AVG_DELTA("avg_delta", R.id.avg_delta, R.string.key_show_avg_delta),
|
||||
UPLOADER_BATTERY("uploader_battery", R.id.uploader_battery, R.string.key_show_uploader_battery),
|
||||
RIG_BATTERY("rig_battery", R.id.rig_battery, R.string.key_show_rig_battery),
|
||||
BASALRATE("basalRate", R.id.basalRate, R.string.key_show_temp_basal),
|
||||
BGI("bgi", R.id.bgi, null),
|
||||
TIME("time", R.id.time, null),
|
||||
HOUR("hour", R.id.hour, null),
|
||||
MINUTE("minute", R.id.minute, null),
|
||||
SECOND("second", R.id.second, R.string.key_show_seconds),
|
||||
TIMEPERIOD("timePeriod", R.id.timePeriod, null),
|
||||
DAY_NAME("day_name", R.id.day_name, null),
|
||||
DAY("day", R.id.day, null),
|
||||
MONTH("month", R.id.month, null),
|
||||
LOOP("loop", R.id.loop, R.string.key_show_external_status),
|
||||
DIRECTION("direction", R.id.direction2, R.string.key_show_direction),
|
||||
TIMESTAMP("timestamp", R.id.timestamp, R.string.key_show_ago),
|
||||
SGV("sgv", R.id.sgv, R.string.key_show_bg),
|
||||
COVER_PLATE(CustomWatchfaceDrawableDataKey.COVERPLATE.key, R.id.cover_plate, null),
|
||||
HOUR_HABD(CustomWatchfaceDrawableDataKey.HOURHAND.key, R.id.hour_hand, null),
|
||||
MINUTE_HAND(CustomWatchfaceDrawableDataKey.MINUTEHAND.key, R.id.minute_hand, null),
|
||||
SECOND_HAND(CustomWatchfaceDrawableDataKey.SECONDHAND.key, R.id.second_hand, R.string.key_show_seconds);
|
||||
BACKGROUND(ViewKeys.BACKGROUND.key, R.id.background, null),
|
||||
CHART(ViewKeys.CHART.key, R.id.chart, null),
|
||||
COVER_CHART(ViewKeys.COVER_CHART.key, R.id.cover_chart, null),
|
||||
FREETEXT1(ViewKeys.FREETEXT1.key, R.id.freetext1, null),
|
||||
FREETEXT2(ViewKeys.FREETEXT2.key, R.id.freetext2, null),
|
||||
FREETEXT3(ViewKeys.FREETEXT3.key, R.id.freetext3, null),
|
||||
FREETEXT4(ViewKeys.FREETEXT4.key, R.id.freetext4, null),
|
||||
IOB1(ViewKeys.IOB1.key, R.id.iob1, R.string.key_show_iob),
|
||||
IOB2(ViewKeys.IOB2.key, R.id.iob2, R.string.key_show_iob),
|
||||
COB1(ViewKeys.COB1.key, R.id.cob1, R.string.key_show_cob),
|
||||
COB2(ViewKeys.COB2.key, R.id.cob2, R.string.key_show_cob),
|
||||
DELTA(ViewKeys.DELTA.key, R.id.delta, R.string.key_show_delta),
|
||||
AVG_DELTA(ViewKeys.AVG_DELTA.key, R.id.avg_delta, R.string.key_show_avg_delta),
|
||||
UPLOADER_BATTERY(ViewKeys.UPLOADER_BATTERY.key, R.id.uploader_battery, R.string.key_show_uploader_battery),
|
||||
RIG_BATTERY(ViewKeys.RIG_BATTERY.key, R.id.rig_battery, R.string.key_show_rig_battery),
|
||||
BASALRATE(ViewKeys.BASALRATE.key, R.id.basalRate, R.string.key_show_temp_basal),
|
||||
BGI(ViewKeys.BGI.key, R.id.bgi, R.string.key_show_bgi),
|
||||
TIME(ViewKeys.TIME.key, R.id.time, null),
|
||||
HOUR(ViewKeys.HOUR.key, R.id.hour, null),
|
||||
MINUTE(ViewKeys.MINUTE.key, R.id.minute, null),
|
||||
SECOND(ViewKeys.SECOND.key, R.id.second, R.string.key_show_seconds),
|
||||
TIMEPERIOD(ViewKeys.TIMEPERIOD.key, R.id.timePeriod, null),
|
||||
DAY_NAME(ViewKeys.DAY_NAME.key, R.id.day_name, null),
|
||||
DAY(ViewKeys.DAY.key, R.id.day, null),
|
||||
MONTH(ViewKeys.MONTH.key, R.id.month, null),
|
||||
LOOP(ViewKeys.LOOP.key, R.id.loop, R.string.key_show_external_status),
|
||||
DIRECTION(ViewKeys.DIRECTION.key, R.id.direction2, R.string.key_show_direction),
|
||||
TIMESTAMP(ViewKeys.TIMESTAMP.key, R.id.timestamp, R.string.key_show_ago),
|
||||
SGV(ViewKeys.SGV.key, R.id.sgv, R.string.key_show_bg),
|
||||
COVER_PLATE(ViewKeys.COVER_PLATE.key, R.id.cover_plate, null),
|
||||
HOUR_HAND(ViewKeys.HOUR_HAND.key, R.id.hour_hand, null),
|
||||
MINUTE_HAND(ViewKeys.MINUTE_HAND.key, R.id.minute_hand, null),
|
||||
SECOND_HAND(ViewKeys.SECOND_HAND.key, R.id.second_hand, R.string.key_show_seconds);
|
||||
|
||||
companion object {
|
||||
|
||||
fun fromId(id: Int): CustomViews? = values().firstOrNull { it.id == id }
|
||||
fun fromId(id: Int): ViewMap? = values().firstOrNull { it.id == id }
|
||||
}
|
||||
|
||||
fun visibility(sp: SP): Boolean = this.pref?.let { sp.getBoolean(it, true) }
|
||||
?: true
|
||||
}
|
||||
|
||||
private enum class TrendArrow(val text: String, val symbol: String, @DrawableRes val icon: Int) {
|
||||
NONE("NONE", "??", R.drawable.ic_invalid),
|
||||
TRIPLE_UP("TripleUp", "X", R.drawable.ic_doubleup),
|
||||
DOUBLE_UP("DoubleUp", "\u21c8", R.drawable.ic_doubleup),
|
||||
SINGLE_UP("SingleUp", "\u2191", R.drawable.ic_singleup),
|
||||
FORTY_FIVE_UP("FortyFiveUp", "\u2197", R.drawable.ic_fortyfiveup),
|
||||
FLAT("Flat", "\u2192", R.drawable.ic_flat),
|
||||
FORTY_FIVE_DOWN("FortyFiveDown", "\u2198", R.drawable.ic_fortyfivedown),
|
||||
SINGLE_DOWN("SingleDown", "\u2193", R.drawable.ic_singledown),
|
||||
DOUBLE_DOWN("DoubleDown", "\u21ca", R.drawable.ic_doubledown),
|
||||
TRIPLE_DOWN("TripleDown", "X", R.drawable.ic_doubledown)
|
||||
;
|
||||
private enum class TrendArrowMap(val symbol: String, @DrawableRes val icon: Int) {
|
||||
NONE("??", R.drawable.ic_invalid),
|
||||
TRIPLE_UP("X", R.drawable.ic_doubleup),
|
||||
DOUBLE_UP("\u21c8", R.drawable.ic_doubleup),
|
||||
SINGLE_UP("\u2191", R.drawable.ic_singleup),
|
||||
FORTY_FIVE_UP("\u2197", R.drawable.ic_fortyfiveup),
|
||||
FLAT("\u2192", R.drawable.ic_flat),
|
||||
FORTY_FIVE_DOWN("\u2198", R.drawable.ic_fortyfivedown),
|
||||
SINGLE_DOWN("\u2193", R.drawable.ic_singledown),
|
||||
DOUBLE_DOWN("\u21ca", R.drawable.ic_doubledown),
|
||||
TRIPLE_DOWN("X", R.drawable.ic_doubledown);
|
||||
|
||||
companion object {
|
||||
|
||||
|
@ -447,9 +439,9 @@ class CustomWatchface : BaseWatchFace() {
|
|||
}
|
||||
|
||||
private enum class GravityMap(val key: String, val gravity: Int) {
|
||||
CENTER("center", Gravity.CENTER),
|
||||
LEFT("left", Gravity.LEFT),
|
||||
RIGHT("right", Gravity.RIGHT);
|
||||
CENTER(JsonKeyValues.CENTER.key, Gravity.CENTER),
|
||||
LEFT(JsonKeyValues.LEFT.key, Gravity.LEFT),
|
||||
RIGHT(JsonKeyValues.RIGHT.key, Gravity.RIGHT);
|
||||
|
||||
companion object {
|
||||
|
||||
|
@ -459,15 +451,15 @@ class CustomWatchface : BaseWatchFace() {
|
|||
}
|
||||
|
||||
private enum class FontMap(val key: String, var font: Typeface, @FontRes val fontRessources: Int?) {
|
||||
SANS_SERIF("sans-serif", Typeface.SANS_SERIF, null),
|
||||
DEFAULT("default", Typeface.DEFAULT, null),
|
||||
DEFAULT_BOLD("default-bold", Typeface.DEFAULT_BOLD, null),
|
||||
MONOSPACE("monospace", Typeface.MONOSPACE, null),
|
||||
SERIF("serif", Typeface.SERIF, null),
|
||||
ROBOTO_CONDENSED_BOLD("roboto_condensed_bold", Typeface.DEFAULT, R.font.roboto_condensed_bold),
|
||||
ROBOTO_CONDENSED_LIGHT("roboto_condensed_light", Typeface.DEFAULT, R.font.roboto_condensed_light),
|
||||
ROBOTO_CONDENSED_REGULAR("roboto_condensed_regular", Typeface.DEFAULT, R.font.roboto_condensed_regular),
|
||||
ROBOTO_SLAB_LIGHT("roboto_slab_light", Typeface.DEFAULT, R.font.roboto_slab_light);
|
||||
SANS_SERIF(JsonKeyValues.SANS_SERIF.key, Typeface.SANS_SERIF, null),
|
||||
DEFAULT(JsonKeyValues.DEFAULT.key, Typeface.DEFAULT, null),
|
||||
DEFAULT_BOLD(JsonKeyValues.DEFAULT_BOLD.key, Typeface.DEFAULT_BOLD, null),
|
||||
MONOSPACE(JsonKeyValues.MONOSPACE.key, Typeface.MONOSPACE, null),
|
||||
SERIF(JsonKeyValues.SERIF.key, Typeface.SERIF, null),
|
||||
ROBOTO_CONDENSED_BOLD(JsonKeyValues.ROBOTO_CONDENSED_BOLD.key, Typeface.DEFAULT, R.font.roboto_condensed_bold),
|
||||
ROBOTO_CONDENSED_LIGHT(JsonKeyValues.ROBOTO_CONDENSED_LIGHT.key, Typeface.DEFAULT, R.font.roboto_condensed_light),
|
||||
ROBOTO_CONDENSED_REGULAR(JsonKeyValues.ROBOTO_CONDENSED_REGULAR.key, Typeface.DEFAULT, R.font.roboto_condensed_regular),
|
||||
ROBOTO_SLAB_LIGHT(JsonKeyValues.ROBOTO_SLAB_LIGHT.key, Typeface.DEFAULT, R.font.roboto_slab_light);
|
||||
|
||||
companion object {
|
||||
fun init(context: Context) = values().forEach { it.font = it.fontRessources?.let { font -> ResourcesCompat.getFont(context, font) } ?: it.font }
|
||||
|
@ -477,10 +469,10 @@ class CustomWatchface : BaseWatchFace() {
|
|||
}
|
||||
|
||||
private enum class StyleMap(val key: String, val style: Int) {
|
||||
NORMAL("normal", Typeface.NORMAL),
|
||||
BOLD("bold", Typeface.BOLD),
|
||||
BOLD_ITALIC("bold-italic", Typeface.BOLD_ITALIC),
|
||||
ITALIC("italic", Typeface.ITALIC);
|
||||
NORMAL(JsonKeyValues.NORMAL.key, Typeface.NORMAL),
|
||||
BOLD(JsonKeyValues.BOLD.key, Typeface.BOLD),
|
||||
BOLD_ITALIC(JsonKeyValues.BOLD_ITALIC.key, Typeface.BOLD_ITALIC),
|
||||
ITALIC(JsonKeyValues.ITALIC.key, Typeface.ITALIC);
|
||||
|
||||
companion object {
|
||||
|
||||
|
@ -491,19 +483,20 @@ class CustomWatchface : BaseWatchFace() {
|
|||
|
||||
// This class containt mapping between keys used within json of Custom Watchface and preferences
|
||||
private enum class PrefMap(val key: String, @StringRes val prefKey: Int) {
|
||||
SHOW_IOB(CustomWatchfaceMetadataKey.CWF_PREF_WATCH_SHOW_IOB.key, R.string.key_show_iob),
|
||||
SHOW_DETAILED_IOB(CustomWatchfaceMetadataKey.CWF_PREF_WATCH_SHOW_DETAILED_IOB.key, R.string.key_show_detailed_iob),
|
||||
SHOW_COB(CustomWatchfaceMetadataKey.CWF_PREF_WATCH_SHOW_COB.key, R.string.key_show_cob),
|
||||
SHOW_DELTA(CustomWatchfaceMetadataKey.CWF_PREF_WATCH_SHOW_DELTA.key, R.string.key_show_delta),
|
||||
SHOW_AVG_DELTA(CustomWatchfaceMetadataKey.CWF_PREF_WATCH_SHOW_AVG_DELTA.key, R.string.key_show_avg_delta),
|
||||
SHOW_DETAILED_DELTA(CustomWatchfaceMetadataKey.CWF_PREF_WATCH_SHOW_DETAILED_DELTA.key, R.string.key_show_detailed_delta),
|
||||
SHOW_UPLOADER_BATTERY(CustomWatchfaceMetadataKey.CWF_PREF_WATCH_SHOW_UPLOADER_BATTERY.key, R.string.key_show_uploader_battery),
|
||||
SHOW_RIG_BATTERY(CustomWatchfaceMetadataKey.CWF_PREF_WATCH_SHOW_RIG_BATTERY.key, R.string.key_show_rig_battery),
|
||||
SHOW_TEMP_BASAL(CustomWatchfaceMetadataKey.CWF_PREF_WATCH_SHOW_TEMP_BASAL.key, R.string.key_show_temp_basal),
|
||||
SHOW_DIRECTION(CustomWatchfaceMetadataKey.CWF_PREF_WATCH_SHOW_DIRECTION.key, R.string.key_show_direction),
|
||||
SHOW_AGO(CustomWatchfaceMetadataKey.CWF_PREF_WATCH_SHOW_AGO.key, R.string.key_show_ago),
|
||||
SHOW_BG(CustomWatchfaceMetadataKey.CWF_PREF_WATCH_SHOW_BG.key, R.string.key_show_bg),
|
||||
SHOW_BGI(CustomWatchfaceMetadataKey.CWF_PREF_WATCH_SHOW_BGI.key, R.string.key_show_bgi)
|
||||
SHOW_IOB(CwfMetadataKey.CWF_PREF_WATCH_SHOW_IOB.key, R.string.key_show_iob),
|
||||
SHOW_DETAILED_IOB(CwfMetadataKey.CWF_PREF_WATCH_SHOW_DETAILED_IOB.key, R.string.key_show_detailed_iob),
|
||||
SHOW_COB(CwfMetadataKey.CWF_PREF_WATCH_SHOW_COB.key, R.string.key_show_cob),
|
||||
SHOW_DELTA(CwfMetadataKey.CWF_PREF_WATCH_SHOW_DELTA.key, R.string.key_show_delta),
|
||||
SHOW_AVG_DELTA(CwfMetadataKey.CWF_PREF_WATCH_SHOW_AVG_DELTA.key, R.string.key_show_avg_delta),
|
||||
SHOW_DETAILED_DELTA(CwfMetadataKey.CWF_PREF_WATCH_SHOW_DETAILED_DELTA.key, R.string.key_show_detailed_delta),
|
||||
SHOW_UPLOADER_BATTERY(CwfMetadataKey.CWF_PREF_WATCH_SHOW_UPLOADER_BATTERY.key, R.string.key_show_uploader_battery),
|
||||
SHOW_RIG_BATTERY(CwfMetadataKey.CWF_PREF_WATCH_SHOW_RIG_BATTERY.key, R.string.key_show_rig_battery),
|
||||
SHOW_TEMP_BASAL(CwfMetadataKey.CWF_PREF_WATCH_SHOW_TEMP_BASAL.key, R.string.key_show_temp_basal),
|
||||
SHOW_DIRECTION(CwfMetadataKey.CWF_PREF_WATCH_SHOW_DIRECTION.key, R.string.key_show_direction),
|
||||
SHOW_AGO(CwfMetadataKey.CWF_PREF_WATCH_SHOW_AGO.key, R.string.key_show_ago),
|
||||
SHOW_BG(CwfMetadataKey.CWF_PREF_WATCH_SHOW_BG.key, R.string.key_show_bg),
|
||||
SHOW_BGI(CwfMetadataKey.CWF_PREF_WATCH_SHOW_BGI.key, R.string.key_show_bgi),
|
||||
SHOW_LOOP_STATUS(CwfMetadataKey.CWF_PREF_WATCH_SHOW_LOOP_STATUS.key, R.string.key_show_external_status)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -330,7 +330,7 @@ abstract class BaseWatchFace : WatchFace() {
|
|||
binding.basalRate?.text = status.currentBasal
|
||||
binding.basalRate?.visibility = sp.getBoolean(R.string.key_show_temp_basal, true).toVisibility()
|
||||
binding.bgi?.text = status.bgi
|
||||
binding.bgi?.visibility = sp.getBoolean(R.string.key_show_bgi, true).toVisibility()
|
||||
binding.bgi?.visibility = showBgi.toVisibility()
|
||||
val iobString =
|
||||
if (detailedIob) "${status.iobSum} ${status.iobDetail}"
|
||||
else status.iobSum + getString(R.string.units_short)
|
||||
|
|
Loading…
Reference in a new issue