Multiple graph support

This commit is contained in:
Milos Kozak 2020-04-07 11:55:56 +02:00
parent 731bd1c8cb
commit 93784fc8be
14 changed files with 208 additions and 203 deletions

View file

@ -234,7 +234,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
new java.util.TimerTask() { new java.util.TimerTask() {
@Override @Override
public void run() { public void run() {
RxBus.Companion.getINSTANCE().send(new EventRefreshOverview("resetDatabases")); RxBus.Companion.getINSTANCE().send(new EventRefreshOverview("resetDatabases", false));
} }
}, },
3000 3000

View file

@ -1,3 +1,3 @@
package info.nightscout.androidaps.events package info.nightscout.androidaps.events
class EventRefreshOverview(var from: String) : Event() class EventRefreshOverview(var from: String, val now : Boolean = false) : Event()

View file

@ -5,6 +5,7 @@ import android.app.NotificationManager
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Color
import android.graphics.Paint import android.graphics.Paint
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
@ -17,7 +18,9 @@ import android.view.MenuItem
import android.view.View import android.view.View
import android.view.View.OnLongClickListener import android.view.View.OnLongClickListener
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.jjoe64.graphview.GraphView
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import dagger.android.support.DaggerFragment import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.Config import info.nightscout.androidaps.Config
@ -93,6 +96,7 @@ import java.util.concurrent.Executors
import java.util.concurrent.ScheduledFuture import java.util.concurrent.ScheduledFuture
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject
import kotlin.collections.ArrayList
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.ceil import kotlin.math.ceil
import kotlin.math.max import kotlin.math.max
@ -130,6 +134,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
private var smallWidth = false private var smallWidth = false
private var smallHeight = false private var smallHeight = false
private lateinit var dm: DisplayMetrics private lateinit var dm: DisplayMetrics
private var axisWidth: Int = 0
private var rangeToDisplay = 6 // for graph private var rangeToDisplay = 6 // for graph
private var loopHandler = Handler() private var loopHandler = Handler()
private var refreshLoop: Runnable? = null private var refreshLoop: Runnable? = null
@ -137,6 +142,8 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
private val worker = Executors.newSingleThreadScheduledExecutor() private val worker = Executors.newSingleThreadScheduledExecutor()
private var scheduledUpdate: ScheduledFuture<*>? = null private var scheduledUpdate: ScheduledFuture<*>? = null
private val secondaryGraphs = ArrayList<GraphView>()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? { savedInstanceState: Bundle?): View? {
@ -173,15 +180,11 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
overview_notifications?.setHasFixedSize(false) overview_notifications?.setHasFixedSize(false)
overview_notifications?.layoutManager = LinearLayoutManager(view.context) overview_notifications?.layoutManager = LinearLayoutManager(view.context)
val axisWidth = if (dm.densityDpi <= 120) 3 else if (dm.densityDpi <= 160) 10 else if (dm.densityDpi <= 320) 35 else if (dm.densityDpi <= 420) 50 else if (dm.densityDpi <= 560) 70 else 80 axisWidth = if (dm.densityDpi <= 120) 3 else if (dm.densityDpi <= 160) 10 else if (dm.densityDpi <= 320) 35 else if (dm.densityDpi <= 420) 50 else if (dm.densityDpi <= 560) 70 else 80
overview_bggraph?.gridLabelRenderer?.gridColor = resourceHelper.gc(R.color.graphgrid) overview_bggraph?.gridLabelRenderer?.gridColor = resourceHelper.gc(R.color.graphgrid)
overview_bggraph?.gridLabelRenderer?.reloadStyles() overview_bggraph?.gridLabelRenderer?.reloadStyles()
overview_iobgraph?.gridLabelRenderer?.gridColor = resourceHelper.gc(R.color.graphgrid)
overview_iobgraph?.gridLabelRenderer?.reloadStyles()
overview_iobgraph?.gridLabelRenderer?.isHorizontalLabelsVisible = false
overview_bggraph?.gridLabelRenderer?.labelVerticalWidth = axisWidth overview_bggraph?.gridLabelRenderer?.labelVerticalWidth = axisWidth
overview_iobgraph?.gridLabelRenderer?.labelVerticalWidth = axisWidth
overview_iobgraph?.gridLabelRenderer?.numVerticalLabels = 3
rangeToDisplay = sp.getInt(R.string.key_rangetodisplay, 6) rangeToDisplay = sp.getInt(R.string.key_rangetodisplay, 6)
overview_bggraph?.setOnLongClickListener { overview_bggraph?.setOnLongClickListener {
@ -193,6 +196,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
false false
} }
overviewMenus.setupChartMenu(overview_chartMenuButton) overviewMenus.setupChartMenu(overview_chartMenuButton)
prepareGraphs()
overview_accepttempbutton?.setOnClickListener(this) overview_accepttempbutton?.setOnClickListener(this)
overview_treatmentbutton?.setOnClickListener(this) overview_treatmentbutton?.setOnClickListener(this)
@ -218,8 +222,12 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
super.onResume() super.onResume()
disposable.add(rxBus disposable.add(rxBus
.toObservable(EventRefreshOverview::class.java) .toObservable(EventRefreshOverview::class.java)
.observeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ scheduleUpdateGUI(it.from) }) { fabricPrivacy.logException(it) }) .subscribe({
prepareGraphs()
if (it.now) updateGUI(it.from)
else scheduleUpdateGUI(it.from)
}) { fabricPrivacy.logException(it) })
disposable.add(rxBus disposable.add(rxBus
.toObservable(EventExtendedBolusChange::class.java) .toObservable(EventExtendedBolusChange::class.java)
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
@ -464,6 +472,30 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
} }
private fun prepareGraphs() {
val numOfGraphs = overviewMenus.setting.size
if (numOfGraphs != secondaryGraphs.size - 1) {
//aapsLogger.debug("New secondary graph count ${numOfGraphs-1}")
// rebuild needed
secondaryGraphs.clear()
overview_iobgraph.removeAllViews()
for (i in 1 until numOfGraphs) {
val graph = GraphView(context)
graph.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, resourceHelper.dpToPx(100)).also { it.setMargins(0, 0, 0, resourceHelper.dpToPx(10)) }
graph.gridLabelRenderer?.gridColor = resourceHelper.gc(R.color.graphgrid)
graph.gridLabelRenderer?.reloadStyles()
graph.gridLabelRenderer?.isHorizontalLabelsVisible = false
graph.gridLabelRenderer?.labelVerticalWidth = axisWidth
graph.gridLabelRenderer?.numVerticalLabels = 3
graph.viewport.backgroundColor = Color.argb(20, 255, 255, 255) // 8% of gray
overview_iobgraph.addView(graph)
secondaryGraphs.add(graph)
}
}
}
private fun scheduleUpdateGUI(from: String) { private fun scheduleUpdateGUI(from: String) {
class UpdateRunnable : Runnable { class UpdateRunnable : Runnable {
override fun run() { override fun run() {
@ -746,19 +778,20 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
graphData.addInRangeArea(fromTime, endTime, lowLine, highLine) graphData.addInRangeArea(fromTime, endTime, lowLine, highLine)
// **** BG **** // **** BG ****
if (predictionsAvailable && sp.getBoolean("showprediction", false)) graphData.addBgReadings(fromTime, toTime, lowLine, highLine, if (predictionsAvailable && overviewMenus.setting[0][OverviewMenus.CharType.PRE.ordinal])
apsResult?.predictions) else graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null) graphData.addBgReadings(fromTime, toTime, lowLine, highLine, apsResult?.predictions)
else graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null)
// set manual x bounds to have nice steps // set manual x bounds to have nice steps
graphData.formatAxis(fromTime, endTime) graphData.formatAxis(fromTime, endTime)
// Treatments // Treatments
graphData.addTreatments(fromTime, endTime) graphData.addTreatments(fromTime, endTime)
if (sp.getBoolean("showactivityprimary", true)) if (overviewMenus.setting[0][OverviewMenus.CharType.ACT.ordinal])
graphData.addActivity(fromTime, endTime, false, 0.8) graphData.addActivity(fromTime, endTime, false, 0.8)
// add basal data // add basal data
if (pump.pumpDescription.isTempBasalCapable && sp.getBoolean("showbasals", true)) if (pump.pumpDescription.isTempBasalCapable && overviewMenus.setting[0][OverviewMenus.CharType.BAS.ordinal])
graphData.addBasals(fromTime, now, lowLine / graphData.maxY / 1.2) graphData.addBasals(fromTime, now, lowLine / graphData.maxY / 1.2)
// add target line // add target line
@ -768,57 +801,53 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
graphData.addNowLine(now) graphData.addNowLine(now)
// ------------------ 2nd graph // ------------------ 2nd graph
val secondGraphData = GraphData(injector, overview_iobgraph, iobCobCalculatorPlugin) val secondaryGraphsData: ArrayList<GraphData> = ArrayList()
for (g in 0 until secondaryGraphs.size) {
val secondGraphData = GraphData(injector, secondaryGraphs[g], iobCobCalculatorPlugin)
var useIobForScale = false var useIobForScale = false
var useCobForScale = false var useCobForScale = false
var useDevForScale = false var useDevForScale = false
var useRatioForScale = false var useRatioForScale = false
var useDSForScale = false var useDSForScale = false
var useIAForScale = false var useIAForScale = false
// finally enforce drawing of graphs
when { when {
sp.getBoolean("showiob", true) -> overviewMenus.setting[g + 1][OverviewMenus.CharType.IOB.ordinal] -> useIobForScale = true
useIobForScale = true overviewMenus.setting[g + 1][OverviewMenus.CharType.COB.ordinal] -> useCobForScale = true
sp.getBoolean("showcob", true) -> overviewMenus.setting[g + 1][OverviewMenus.CharType.DEV.ordinal] -> useDevForScale = true
useCobForScale = true overviewMenus.setting[g + 1][OverviewMenus.CharType.SEN.ordinal] -> useRatioForScale = true
sp.getBoolean("showdeviations", false) -> overviewMenus.setting[g + 1][OverviewMenus.CharType.ACT.ordinal] -> useIAForScale = true
useDevForScale = true overviewMenus.setting[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] -> useDSForScale = true
sp.getBoolean("showratios", false) ->
useRatioForScale = true
sp.getBoolean("showactivitysecondary", false) ->
useIAForScale = true
sp.getBoolean("showdevslope", false) ->
useDSForScale = true
} }
if (sp.getBoolean("showiob", true)) secondGraphData.addIob(fromTime, now, useIobForScale, 1.0, sp.getBoolean("showprediction", false)) if (overviewMenus.setting[g + 1][OverviewMenus.CharType.IOB.ordinal]) secondGraphData.addIob(fromTime, now, useIobForScale, 1.0, overviewMenus.setting[g + 1][OverviewMenus.CharType.PRE.ordinal])
if (sp.getBoolean("showcob", true)) secondGraphData.addCob(fromTime, now, useCobForScale, if (useCobForScale) 1.0 else 0.5) if (overviewMenus.setting[g + 1][OverviewMenus.CharType.COB.ordinal]) secondGraphData.addCob(fromTime, now, useCobForScale, if (useCobForScale) 1.0 else 0.5)
if (sp.getBoolean("showdeviations", false)) secondGraphData.addDeviations(fromTime, now, useDevForScale, 1.0) if (overviewMenus.setting[g + 1][OverviewMenus.CharType.DEV.ordinal]) secondGraphData.addDeviations(fromTime, now, useDevForScale, 1.0)
if (sp.getBoolean("showratios", false)) secondGraphData.addRatio(fromTime, now, useRatioForScale, 1.0) if (overviewMenus.setting[g + 1][OverviewMenus.CharType.SEN.ordinal]) secondGraphData.addRatio(fromTime, now, useRatioForScale, 1.0)
if (sp.getBoolean("showactivitysecondary", true)) secondGraphData.addActivity(fromTime, endTime, useIAForScale, 0.8) if (overviewMenus.setting[g + 1][OverviewMenus.CharType.ACT.ordinal]) secondGraphData.addActivity(fromTime, endTime, useIAForScale, 0.8)
if (sp.getBoolean("showdevslope", false) && buildHelper.isDev()) secondGraphData.addDeviationSlope(fromTime, now, useDSForScale, 1.0) if (overviewMenus.setting[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] && buildHelper.isDev()) secondGraphData.addDeviationSlope(fromTime, now, useDSForScale, 1.0)
// **** NOW line ****
// set manual x bounds to have nice steps // set manual x bounds to have nice steps
secondGraphData.formatAxis(fromTime, endTime) secondGraphData.formatAxis(fromTime, endTime)
secondGraphData.addNowLine(now) secondGraphData.addNowLine(now)
secondaryGraphsData.add(secondGraphData)
}
// do GUI update // do GUI update
val activity = activity val activity = activity
activity?.runOnUiThread { activity?.runOnUiThread {
if (sp.getBoolean("showiob", true)
|| sp.getBoolean("showcob", true)
|| sp.getBoolean("showdeviations", false)
|| sp.getBoolean("showratios", false)
|| sp.getBoolean("showactivitysecondary", false)
|| sp.getBoolean("showdevslope", false)) {
overview_iobgraph?.visibility = View.VISIBLE
} else {
overview_iobgraph?.visibility = View.GONE
}
// finally enforce drawing of graphs // finally enforce drawing of graphs
graphData.performUpdate() graphData.performUpdate()
secondGraphData.performUpdate() for (g in 0 until secondaryGraphs.size) {
secondaryGraphs[g].visibility = (
overviewMenus.setting[g + 1][OverviewMenus.CharType.IOB.ordinal] ||
overviewMenus.setting[g + 1][OverviewMenus.CharType.COB.ordinal] ||
overviewMenus.setting[g + 1][OverviewMenus.CharType.DEV.ordinal] ||
overviewMenus.setting[g + 1][OverviewMenus.CharType.SEN.ordinal] ||
overviewMenus.setting[g + 1][OverviewMenus.CharType.ACT.ordinal] ||
overviewMenus.setting[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal]
).toVisibility()
secondaryGraphsData[g].performUpdate()
}
} }
}).start() }).start()
} }

View file

@ -10,8 +10,12 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.widget.ImageButton import android.widget.ImageButton
import androidx.annotation.ColorRes
import androidx.annotation.StringRes
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import info.nightscout.androidaps.Config import info.nightscout.androidaps.Config
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.activities.ErrorHelperActivity
@ -38,6 +42,7 @@ import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import java.lang.reflect.Type
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@ -57,131 +62,95 @@ class OverviewMenus @Inject constructor(
private val loopPlugin: LoopPlugin private val loopPlugin: LoopPlugin
) { ) {
enum class CharType { enum class CharType(@StringRes val nameId: Int, @ColorRes val colorId: Int, val primary: Boolean, val secondary: Boolean) {
PRE, BAS, IOB, COB, DEV, SEN, ACTPRIM, ACTSEC, DEVSLOPE PRE(R.string.overview_show_predictions, R.color.prediction, primary = true, secondary = false),
BAS(R.string.overview_show_basals, R.color.basal, primary = true, secondary = false),
IOB(R.string.overview_show_iob, R.color.iob, primary = false, secondary = true),
COB(R.string.overview_show_cob, R.color.cob, primary = false, secondary = true),
DEV(R.string.overview_show_deviations, R.color.deviations, primary = false, secondary = true),
SEN(R.string.overview_show_sensitivity, R.color.ratio, primary = false, secondary = true),
ACT(R.string.overview_show_activity, R.color.activity, primary = true, secondary = true),
DEVSLOPE(R.string.overview_show_deviationslope, R.color.devslopepos, primary = false, secondary = true)
}
companion object {
const val MAX_GRAPHS = 5 // including main
}
var setting: MutableList<Array<Boolean>> = ArrayList()
private fun storeGraphConfig() {
val sts = Gson().toJson(setting)
sp.putString(R.string.key_graphconfig, sts)
aapsLogger.debug(sts)
}
private fun loadGraphConfig() {
val sts = sp.getString(R.string.key_graphconfig, "")
if (sts.isNotEmpty())
setting = Gson().fromJson(sts, Array<Array<Boolean>>::class.java).toMutableList()
else {
setting = ArrayList()
setting.add(Array(CharType.values().size) { true })
}
} }
fun setupChartMenu(chartButton: ImageButton) { fun setupChartMenu(chartButton: ImageButton) {
loadGraphConfig()
val numOfGraphs = setting.size // 1 main + x secondary
chartButton.setOnClickListener { v: View -> chartButton.setOnClickListener { v: View ->
val predictionsAvailable: Boolean = when { val predictionsAvailable: Boolean = when {
Config.APS -> loopPlugin.lastRun?.request?.hasPredictions ?: false Config.APS -> loopPlugin.lastRun?.request?.hasPredictions ?: false
Config.NSCLIENT -> true Config.NSCLIENT -> true
else -> false else -> false
} }
//var item: MenuItem
val dividerItem: MenuItem
//var title: CharSequence
var titleMaxChars = 0
//var s: SpannableString
val popup = PopupMenu(v.context, v) val popup = PopupMenu(v.context, v)
if (predictionsAvailable) {
val item = popup.menu.add(Menu.NONE, CharType.PRE.ordinal, Menu.NONE, "Predictions") for (g in 0 until numOfGraphs) {
val title = item.title if (g != 0 && g < numOfGraphs) {
if (titleMaxChars < title.length) titleMaxChars = title.length val dividerItem = popup.menu.add(Menu.NONE, g, Menu.NONE, "------- " + "Graph" + " " + g + " -------")
val s = SpannableString(title) dividerItem.isCheckable = true
s.setSpan(ForegroundColorSpan(resourceHelper.gc(R.color.prediction)), 0, s.length, 0) dividerItem.isChecked = true
item.title = s
item.isCheckable = true
item.isChecked = sp.getBoolean("showprediction", true)
} }
run { CharType.values().forEach { m ->
val item = popup.menu.add(Menu.NONE, CharType.BAS.ordinal, Menu.NONE, resourceHelper.gs(R.string.overview_show_basals)) if (g == 0 && !m.primary) return@forEach
if (g > 0 && !m.secondary) return@forEach
var insert = true
if (m == CharType.PRE) insert = predictionsAvailable
if (m == CharType.DEVSLOPE) insert = buildHelper.isDev()
if (insert) {
val item = popup.menu.add(Menu.NONE, m.ordinal + 100 * (g + 1), Menu.NONE, resourceHelper.gs(m.nameId))
val title = item.title val title = item.title
if (titleMaxChars < title.length) titleMaxChars = title.length
val s = SpannableString(title) val s = SpannableString(title)
s.setSpan(ForegroundColorSpan(resourceHelper.gc(R.color.basal)), 0, s.length, 0) s.setSpan(ForegroundColorSpan(resourceHelper.gc(m.colorId)), 0, s.length, 0)
item.title = s item.title = s
item.isCheckable = true item.isCheckable = true
item.isChecked = sp.getBoolean("showbasals", true) item.isChecked = setting[g][m.ordinal]
} }
run {
val item = popup.menu.add(Menu.NONE, CharType.ACTPRIM.ordinal, Menu.NONE, resourceHelper.gs(R.string.overview_show_activity))
val title = item.title
if (titleMaxChars < title.length) titleMaxChars = title.length
val s = SpannableString(title)
s.setSpan(ForegroundColorSpan(resourceHelper.gc(R.color.activity)), 0, s.length, 0)
item.title = s
item.isCheckable = true
item.isChecked = sp.getBoolean("showactivityprimary", true)
dividerItem = popup.menu.add("")
dividerItem.isEnabled = false
} }
run {
val item = popup.menu.add(Menu.NONE, CharType.IOB.ordinal, Menu.NONE, resourceHelper.gs(R.string.overview_show_iob))
val title = item.title
if (titleMaxChars < title.length) titleMaxChars = title.length
val s = SpannableString(title)
s.setSpan(ForegroundColorSpan(resourceHelper.gc(R.color.iob)), 0, s.length, 0)
item.title = s
item.isCheckable = true
item.isChecked = sp.getBoolean("showiob", true)
} }
run { if (numOfGraphs < MAX_GRAPHS) {
val item = popup.menu.add(Menu.NONE, CharType.COB.ordinal, Menu.NONE, resourceHelper.gs(R.string.overview_show_cob)) val dividerItem = popup.menu.add(Menu.NONE, numOfGraphs, Menu.NONE, "------- " + "Graph" + " " + numOfGraphs + " -------")
val title = item.title dividerItem.isCheckable = true
if (titleMaxChars < title.length) titleMaxChars = title.length dividerItem.isChecked = false
val s = SpannableString(title)
s.setSpan(ForegroundColorSpan(resourceHelper.gc(R.color.cob)), 0, s.length, 0)
item.title = s
item.isCheckable = true
item.isChecked = sp.getBoolean("showcob", true)
}
run {
val item = popup.menu.add(Menu.NONE, CharType.DEV.ordinal, Menu.NONE, resourceHelper.gs(R.string.overview_show_deviations))
val title = item.title
if (titleMaxChars < title.length) titleMaxChars = title.length
val s = SpannableString(title)
s.setSpan(ForegroundColorSpan(resourceHelper.gc(R.color.deviations)), 0, s.length, 0)
item.title = s
item.isCheckable = true
item.isChecked = sp.getBoolean("showdeviations", false)
}
run {
val item = popup.menu.add(Menu.NONE, CharType.SEN.ordinal, Menu.NONE, resourceHelper.gs(R.string.overview_show_sensitivity))
val title = item.title
if (titleMaxChars < title.length) titleMaxChars = title.length
val s = SpannableString(title)
s.setSpan(ForegroundColorSpan(resourceHelper.gc(R.color.ratio)), 0, s.length, 0)
item.title = s
item.isCheckable = true
item.isChecked = sp.getBoolean("showratios", false)
}
run {
val item = popup.menu.add(Menu.NONE, CharType.ACTSEC.ordinal, Menu.NONE, resourceHelper.gs(R.string.overview_show_activity))
val title = item.title
if (titleMaxChars < title.length) titleMaxChars = title.length
val s = SpannableString(title)
s.setSpan(ForegroundColorSpan(resourceHelper.gc(R.color.activity)), 0, s.length, 0)
item.title = s
item.isCheckable = true
item.isChecked = sp.getBoolean("showactivitysecondary", true)
}
if (buildHelper.isDev()) {
val item = popup.menu.add(Menu.NONE, CharType.DEVSLOPE.ordinal, Menu.NONE, "Deviation slope")
val title = item.title
if (titleMaxChars < title.length) titleMaxChars = title.length
val s = SpannableString(title)
s.setSpan(ForegroundColorSpan(resourceHelper.gc(R.color.devslopepos)), 0, s.length, 0)
item.title = s
item.isCheckable = true
item.isChecked = sp.getBoolean("showdevslope", false)
} }
// Fairly good estimate for required divider text size...
dividerItem.title = String(CharArray(titleMaxChars + 10)).replace("\u0000", "_")
popup.setOnMenuItemClickListener { popup.setOnMenuItemClickListener {
when (it.itemId) { // id < 100 graph header - divider 1, 2, 3 .....
CharType.PRE.ordinal -> sp.putBoolean("showprediction", !it.isChecked) if (it.itemId == numOfGraphs) {
CharType.BAS.ordinal -> sp.putBoolean("showbasals", !it.isChecked) // add new empty
CharType.IOB.ordinal -> sp.putBoolean("showiob", !it.isChecked) setting.add(Array(CharType.values().size) { false })
CharType.COB.ordinal -> sp.putBoolean("showcob", !it.isChecked) } else if (it.itemId < 100) {
CharType.DEV.ordinal -> sp.putBoolean("showdeviations", !it.isChecked) // remove graph
CharType.SEN.ordinal -> sp.putBoolean("showratios", !it.isChecked) setting.removeAt(it.itemId)
CharType.ACTPRIM.ordinal -> sp.putBoolean("showactivityprimary", !it.isChecked) } else {
CharType.ACTSEC.ordinal -> sp.putBoolean("showactivitysecondary", !it.isChecked) val graphNumber = it.itemId / 100 - 1
CharType.DEVSLOPE.ordinal -> sp.putBoolean("showdevslope", !it.isChecked) val item = it.itemId % 100
setting[graphNumber][item] = !it.isChecked
} }
rxBus.send(EventRefreshOverview("OnMenuItemClickListener")) storeGraphConfig()
setupChartMenu(chartButton)
rxBus.send(EventRefreshOverview("OnMenuItemClickListener", now = true))
return@setOnMenuItemClickListener true return@setOnMenuItemClickListener true
} }
chartButton.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp) chartButton.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp)

View file

@ -25,6 +25,6 @@ class InsulinFragment : DaggerFragment() {
insulin_name?.setText(activePlugin.getActiveInsulin().getFriendlyName()) insulin_name?.setText(activePlugin.getActiveInsulin().getFriendlyName())
insulin_comment?.setText(activePlugin.getActiveInsulin().getComment()) insulin_comment?.setText(activePlugin.getActiveInsulin().getComment())
insulin_dia?.text = resourceHelper.gs(R.string.dia) + ": " + activePlugin.getActiveInsulin().getDia() + "h" insulin_dia?.text = resourceHelper.gs(R.string.dia) + ": " + activePlugin.getActiveInsulin().getDia() + "h"
insuling_graph?.show(activePlugin.getActiveInsulin()) insulin_graph?.show(activePlugin.getActiveInsulin())
} }
} }

View file

@ -644,7 +644,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr
} finally { } finally {
pump.activity = null; pump.activity = null;
rxBus.send(new EventComboPumpUpdateGUI()); rxBus.send(new EventComboPumpUpdateGUI());
rxBus.send(new EventRefreshOverview("Bolus")); rxBus.send(new EventRefreshOverview("Bolus", false));
cancelBolus = false; cancelBolus = false;
} }
} }

View file

@ -464,7 +464,7 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface,
lastUpdated = System.currentTimeMillis(); lastUpdated = System.currentTimeMillis();
new Handler(Looper.getMainLooper()).post(() -> { new Handler(Looper.getMainLooper()).post(() -> {
rxBus.send(new EventLocalInsightUpdateGUI()); rxBus.send(new EventLocalInsightUpdateGUI());
rxBus.send(new EventRefreshOverview("LocalInsightPlugin::fetchStatus")); rxBus.send(new EventRefreshOverview("LocalInsightPlugin::fetchStatus", false));
}); });
} }
@ -1215,7 +1215,7 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface,
} catch (Exception e) { } catch (Exception e) {
aapsLogger.error("Exception while reading history", e); aapsLogger.error("Exception while reading history", e);
} }
new Handler(Looper.getMainLooper()).post(() -> rxBus.send(new EventRefreshOverview("LocalInsightPlugin::readHistory"))); new Handler(Looper.getMainLooper()).post(() -> rxBus.send(new EventRefreshOverview("LocalInsightPlugin::readHistory", false)));
} }
private void processHistoryEvents(String serial, List<HistoryEvent> historyEvents) { private void processHistoryEvents(String serial, List<HistoryEvent> historyEvents) {
@ -1662,7 +1662,7 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface,
activeTBR = null; activeTBR = null;
activeBoluses = null; activeBoluses = null;
tbrOverNotificationBlock = null; tbrOverNotificationBlock = null;
new Handler(Looper.getMainLooper()).post(() -> rxBus.send(new EventRefreshOverview("LocalInsightPlugin::onStateChanged"))); new Handler(Looper.getMainLooper()).post(() -> rxBus.send(new EventRefreshOverview("LocalInsightPlugin::onStateChanged", false)));
} }
new Handler(Looper.getMainLooper()).post(() -> rxBus.send(new EventLocalInsightUpdateGUI())); new Handler(Looper.getMainLooper()).post(() -> rxBus.send(new EventLocalInsightUpdateGUI()));
} }

View file

@ -1073,7 +1073,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter
private void finishAction(String overviewKey) { private void finishAction(String overviewKey) {
if (overviewKey != null) if (overviewKey != null)
rxBus.send(new EventRefreshOverview(overviewKey)); rxBus.send(new EventRefreshOverview(overviewKey, false));
triggerUIChange(); triggerUIChange();

View file

@ -35,7 +35,7 @@
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
<info.nightscout.androidaps.plugins.insulin.ActivityGraph <info.nightscout.androidaps.plugins.insulin.ActivityGraph
android:id="@+id/insuling_graph" android:id="@+id/insulin_graph"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_margin="20dp" android:layout_margin="20dp"
android:layout_height="200dip" /> android:layout_height="200dip" />

View file

@ -452,10 +452,11 @@
app:layout_constraintTop_toTopOf="@+id/overview_bggraph" /> app:layout_constraintTop_toTopOf="@+id/overview_bggraph" />
<com.jjoe64.graphview.GraphView <LinearLayout
android:id="@+id/overview_iobgraph" android:id="@+id/overview_iobgraph"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="100dp" android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

View file

@ -452,10 +452,11 @@
app:layout_constraintTop_toTopOf="@+id/overview_bggraph" /> app:layout_constraintTop_toTopOf="@+id/overview_bggraph" />
<com.jjoe64.graphview.GraphView <LinearLayout
android:id="@+id/overview_iobgraph" android:id="@+id/overview_iobgraph"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="100dp" android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/overview_accepttempbutton" app:layout_constraintBottom_toTopOf="@+id/overview_accepttempbutton"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

View file

@ -534,10 +534,11 @@
app:layout_constraintTop_toTopOf="@+id/overview_bggraph" /> app:layout_constraintTop_toTopOf="@+id/overview_bggraph" />
<com.jjoe64.graphview.GraphView <LinearLayout
android:id="@+id/overview_iobgraph" android:id="@+id/overview_iobgraph"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="100dp" android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

View file

@ -98,8 +98,8 @@
android:layout_marginLeft="5dp" android:layout_marginLeft="5dp"
android:layout_marginRight="5dp" android:layout_marginRight="5dp"
android:gravity="center_vertical|center_horizontal" android:gravity="center_vertical|center_horizontal"
android:paddingBottom="3dp"
android:paddingTop="3dp" android:paddingTop="3dp"
android:paddingBottom="3dp"
android:text="@string/initializing" android:text="@string/initializing"
android:textAppearance="?android:attr/textAppearanceSmall" /> android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout> </LinearLayout>
@ -208,8 +208,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp" android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":" android:text=":"
android:textSize="14sp" /> android:textSize="14sp" />
@ -230,10 +230,10 @@
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
@ -256,8 +256,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp" android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":" android:text=":"
android:textSize="14sp" /> android:textSize="14sp" />
@ -278,10 +278,10 @@
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
@ -304,8 +304,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp" android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":" android:text=":"
android:textSize="14sp" /> android:textSize="14sp" />
@ -326,10 +326,10 @@
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
<LinearLayout <LinearLayout
@ -351,8 +351,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp" android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":" android:text=":"
android:textSize="14sp" /> android:textSize="14sp" />
@ -373,10 +373,10 @@
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
</LinearLayout> </LinearLayout>
@ -425,10 +425,10 @@
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
@ -454,10 +454,10 @@
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
<LinearLayout <LinearLayout
@ -482,10 +482,10 @@
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
</LinearLayout> </LinearLayout>
@ -512,8 +512,8 @@
android:id="@+id/overview_chartMenuButton" android:id="@+id/overview_chartMenuButton"
android:layout_width="30dp" android:layout_width="30dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:paddingTop="5dp" android:paddingTop="5dp"
app:srcCompat="@drawable/ic_arrow_drop_down_white_24dp" /> app:srcCompat="@drawable/ic_arrow_drop_down_white_24dp" />
@ -526,10 +526,11 @@
</RelativeLayout> </RelativeLayout>
<com.jjoe64.graphview.GraphView <LinearLayout
android:id="@+id/overview_iobgraph" android:id="@+id/overview_iobgraph"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="100dp" /> android:layout_height="wrap_content"
android:orientation="vertical" />
</LinearLayout> </LinearLayout>

View file

@ -1801,4 +1801,7 @@
<string name="smscommunicator_otp_reset_warning">By reseting authenticator you make all already provisioned authenticators invalid. You will need to set up them again!</string> <string name="smscommunicator_otp_reset_warning">By reseting authenticator you make all already provisioned authenticators invalid. You will need to set up them again!</string>
<string name="onconnect">On connect</string> <string name="onconnect">On connect</string>
<string name="ondisconnect">On disconnect</string> <string name="ondisconnect">On disconnect</string>
<string name="overview_show_predictions">Predictions</string>
<string name="overview_show_deviationslope">Deviation slope</string>
<string name="key_graphconfig" translatable="false">graphconfig</string>
</resources> </resources>