diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java index 0d65d80f6b..661eaea15f 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -234,7 +234,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { new java.util.TimerTask() { @Override public void run() { - RxBus.Companion.getINSTANCE().send(new EventRefreshOverview("resetDatabases")); + RxBus.Companion.getINSTANCE().send(new EventRefreshOverview("resetDatabases", false)); } }, 3000 diff --git a/app/src/main/java/info/nightscout/androidaps/events/EventRefreshOverview.kt b/app/src/main/java/info/nightscout/androidaps/events/EventRefreshOverview.kt index 533a25dd40..25b22d4e81 100644 --- a/app/src/main/java/info/nightscout/androidaps/events/EventRefreshOverview.kt +++ b/app/src/main/java/info/nightscout/androidaps/events/EventRefreshOverview.kt @@ -1,3 +1,3 @@ package info.nightscout.androidaps.events -class EventRefreshOverview(var from: String) : Event() +class EventRefreshOverview(var from: String, val now : Boolean = false) : Event() diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt index 8a0a6ee04b..28ab89ecba 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt @@ -5,6 +5,7 @@ import android.app.NotificationManager import android.content.ActivityNotFoundException import android.content.Context import android.content.Intent +import android.graphics.Color import android.graphics.Paint import android.os.Bundle import android.os.Handler @@ -17,7 +18,9 @@ import android.view.MenuItem import android.view.View import android.view.View.OnLongClickListener import android.view.ViewGroup +import android.widget.LinearLayout import androidx.recyclerview.widget.LinearLayoutManager +import com.jjoe64.graphview.GraphView import dagger.android.HasAndroidInjector import dagger.android.support.DaggerFragment import info.nightscout.androidaps.Config @@ -93,6 +96,7 @@ import java.util.concurrent.Executors import java.util.concurrent.ScheduledFuture import java.util.concurrent.TimeUnit import javax.inject.Inject +import kotlin.collections.ArrayList import kotlin.math.abs import kotlin.math.ceil import kotlin.math.max @@ -130,6 +134,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList private var smallWidth = false private var smallHeight = false private lateinit var dm: DisplayMetrics + private var axisWidth: Int = 0 private var rangeToDisplay = 6 // for graph private var loopHandler = Handler() private var refreshLoop: Runnable? = null @@ -137,6 +142,8 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList private val worker = Executors.newSingleThreadScheduledExecutor() private var scheduledUpdate: ScheduledFuture<*>? = null + private val secondaryGraphs = ArrayList() + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { @@ -173,15 +180,11 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList overview_notifications?.setHasFixedSize(false) 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?.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_iobgraph?.gridLabelRenderer?.labelVerticalWidth = axisWidth - overview_iobgraph?.gridLabelRenderer?.numVerticalLabels = 3 + rangeToDisplay = sp.getInt(R.string.key_rangetodisplay, 6) overview_bggraph?.setOnLongClickListener { @@ -193,6 +196,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList false } overviewMenus.setupChartMenu(overview_chartMenuButton) + prepareGraphs() overview_accepttempbutton?.setOnClickListener(this) overview_treatmentbutton?.setOnClickListener(this) @@ -218,8 +222,12 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList super.onResume() disposable.add(rxBus .toObservable(EventRefreshOverview::class.java) - .observeOn(Schedulers.io()) - .subscribe({ scheduleUpdateGUI(it.from) }) { fabricPrivacy.logException(it) }) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ + prepareGraphs() + if (it.now) updateGUI(it.from) + else scheduleUpdateGUI(it.from) + }) { fabricPrivacy.logException(it) }) disposable.add(rxBus .toObservable(EventExtendedBolusChange::class.java) .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) { class UpdateRunnable : Runnable { override fun run() { @@ -746,19 +778,20 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList graphData.addInRangeArea(fromTime, endTime, lowLine, highLine) // **** BG **** - if (predictionsAvailable && sp.getBoolean("showprediction", false)) graphData.addBgReadings(fromTime, toTime, lowLine, highLine, - apsResult?.predictions) else graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null) + if (predictionsAvailable && overviewMenus.setting[0][OverviewMenus.CharType.PRE.ordinal]) + graphData.addBgReadings(fromTime, toTime, lowLine, highLine, apsResult?.predictions) + else graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null) // set manual x bounds to have nice steps graphData.formatAxis(fromTime, endTime) // Treatments graphData.addTreatments(fromTime, endTime) - if (sp.getBoolean("showactivityprimary", true)) + if (overviewMenus.setting[0][OverviewMenus.CharType.ACT.ordinal]) graphData.addActivity(fromTime, endTime, false, 0.8) // 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) // add target line @@ -768,57 +801,53 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList graphData.addNowLine(now) // ------------------ 2nd graph - val secondGraphData = GraphData(injector, overview_iobgraph, iobCobCalculatorPlugin) - var useIobForScale = false - var useCobForScale = false - var useDevForScale = false - var useRatioForScale = false - var useDSForScale = false - var useIAForScale = false - // finally enforce drawing of graphs - when { - sp.getBoolean("showiob", true) -> - useIobForScale = true - sp.getBoolean("showcob", true) -> - useCobForScale = true - sp.getBoolean("showdeviations", false) -> - useDevForScale = true - sp.getBoolean("showratios", false) -> - useRatioForScale = true - sp.getBoolean("showactivitysecondary", false) -> - useIAForScale = true - sp.getBoolean("showdevslope", false) -> - useDSForScale = true + val secondaryGraphsData: ArrayList = ArrayList() + for (g in 0 until secondaryGraphs.size) { + val secondGraphData = GraphData(injector, secondaryGraphs[g], iobCobCalculatorPlugin) + var useIobForScale = false + var useCobForScale = false + var useDevForScale = false + var useRatioForScale = false + var useDSForScale = false + var useIAForScale = false + when { + overviewMenus.setting[g + 1][OverviewMenus.CharType.IOB.ordinal] -> useIobForScale = true + overviewMenus.setting[g + 1][OverviewMenus.CharType.COB.ordinal] -> useCobForScale = true + overviewMenus.setting[g + 1][OverviewMenus.CharType.DEV.ordinal] -> useDevForScale = true + overviewMenus.setting[g + 1][OverviewMenus.CharType.SEN.ordinal] -> useRatioForScale = true + overviewMenus.setting[g + 1][OverviewMenus.CharType.ACT.ordinal] -> useIAForScale = true + overviewMenus.setting[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] -> useDSForScale = true + } + + 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 (overviewMenus.setting[g + 1][OverviewMenus.CharType.COB.ordinal]) secondGraphData.addCob(fromTime, now, useCobForScale, if (useCobForScale) 1.0 else 0.5) + if (overviewMenus.setting[g + 1][OverviewMenus.CharType.DEV.ordinal]) secondGraphData.addDeviations(fromTime, now, useDevForScale, 1.0) + if (overviewMenus.setting[g + 1][OverviewMenus.CharType.SEN.ordinal]) secondGraphData.addRatio(fromTime, now, useRatioForScale, 1.0) + if (overviewMenus.setting[g + 1][OverviewMenus.CharType.ACT.ordinal]) secondGraphData.addActivity(fromTime, endTime, useIAForScale, 0.8) + if (overviewMenus.setting[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] && buildHelper.isDev()) secondGraphData.addDeviationSlope(fromTime, now, useDSForScale, 1.0) + + // set manual x bounds to have nice steps + secondGraphData.formatAxis(fromTime, endTime) + secondGraphData.addNowLine(now) + secondaryGraphsData.add(secondGraphData) } - if (sp.getBoolean("showiob", true)) secondGraphData.addIob(fromTime, now, useIobForScale, 1.0, sp.getBoolean("showprediction", false)) - if (sp.getBoolean("showcob", true)) 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 (sp.getBoolean("showratios", false)) secondGraphData.addRatio(fromTime, now, useRatioForScale, 1.0) - if (sp.getBoolean("showactivitysecondary", true)) secondGraphData.addActivity(fromTime, endTime, useIAForScale, 0.8) - if (sp.getBoolean("showdevslope", false) && buildHelper.isDev()) secondGraphData.addDeviationSlope(fromTime, now, useDSForScale, 1.0) - - // **** NOW line **** - // set manual x bounds to have nice steps - secondGraphData.formatAxis(fromTime, endTime) - secondGraphData.addNowLine(now) - // do GUI update val activity = activity 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 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() } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewMenus.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewMenus.kt index 3e3714a89d..0368974841 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewMenus.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewMenus.kt @@ -10,8 +10,12 @@ import android.view.Menu import android.view.MenuItem import android.view.View import android.widget.ImageButton +import androidx.annotation.ColorRes +import androidx.annotation.StringRes import androidx.appcompat.widget.PopupMenu 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.R 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.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP +import java.lang.reflect.Type import javax.inject.Inject import javax.inject.Singleton @@ -57,131 +62,95 @@ class OverviewMenus @Inject constructor( private val loopPlugin: LoopPlugin ) { - enum class CharType { - PRE, BAS, IOB, COB, DEV, SEN, ACTPRIM, ACTSEC, DEVSLOPE + enum class CharType(@StringRes val nameId: Int, @ColorRes val colorId: Int, val primary: Boolean, val secondary: Boolean) { + 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> = 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>::class.java).toMutableList() + else { + setting = ArrayList() + setting.add(Array(CharType.values().size) { true }) + } } fun setupChartMenu(chartButton: ImageButton) { + loadGraphConfig() + val numOfGraphs = setting.size // 1 main + x secondary + chartButton.setOnClickListener { v: View -> val predictionsAvailable: Boolean = when { Config.APS -> loopPlugin.lastRun?.request?.hasPredictions ?: false Config.NSCLIENT -> true else -> false } - //var item: MenuItem - val dividerItem: MenuItem - //var title: CharSequence - var titleMaxChars = 0 - //var s: SpannableString val popup = PopupMenu(v.context, v) - if (predictionsAvailable) { - val item = popup.menu.add(Menu.NONE, CharType.PRE.ordinal, Menu.NONE, "Predictions") - val title = item.title - if (titleMaxChars < title.length) titleMaxChars = title.length - val s = SpannableString(title) - s.setSpan(ForegroundColorSpan(resourceHelper.gc(R.color.prediction)), 0, s.length, 0) - item.title = s - item.isCheckable = true - item.isChecked = sp.getBoolean("showprediction", true) + + for (g in 0 until numOfGraphs) { + if (g != 0 && g < numOfGraphs) { + val dividerItem = popup.menu.add(Menu.NONE, g, Menu.NONE, "------- " + "Graph" + " " + g + " -------") + dividerItem.isCheckable = true + dividerItem.isChecked = true + } + CharType.values().forEach { m -> + 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 s = SpannableString(title) + s.setSpan(ForegroundColorSpan(resourceHelper.gc(m.colorId)), 0, s.length, 0) + item.title = s + item.isCheckable = true + item.isChecked = setting[g][m.ordinal] + } + } } - run { - val item = popup.menu.add(Menu.NONE, CharType.BAS.ordinal, Menu.NONE, resourceHelper.gs(R.string.overview_show_basals)) - val title = item.title - if (titleMaxChars < title.length) titleMaxChars = title.length - val s = SpannableString(title) - s.setSpan(ForegroundColorSpan(resourceHelper.gc(R.color.basal)), 0, s.length, 0) - item.title = s - item.isCheckable = true - item.isChecked = sp.getBoolean("showbasals", true) - } - 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 { - val item = popup.menu.add(Menu.NONE, CharType.COB.ordinal, Menu.NONE, resourceHelper.gs(R.string.overview_show_cob)) - val title = item.title - if (titleMaxChars < title.length) titleMaxChars = title.length - 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) + if (numOfGraphs < MAX_GRAPHS) { + val dividerItem = popup.menu.add(Menu.NONE, numOfGraphs, Menu.NONE, "------- " + "Graph" + " " + numOfGraphs + " -------") + dividerItem.isCheckable = true + dividerItem.isChecked = false } - // Fairly good estimate for required divider text size... - dividerItem.title = String(CharArray(titleMaxChars + 10)).replace("\u0000", "_") popup.setOnMenuItemClickListener { - when (it.itemId) { - CharType.PRE.ordinal -> sp.putBoolean("showprediction", !it.isChecked) - CharType.BAS.ordinal -> sp.putBoolean("showbasals", !it.isChecked) - CharType.IOB.ordinal -> sp.putBoolean("showiob", !it.isChecked) - CharType.COB.ordinal -> sp.putBoolean("showcob", !it.isChecked) - CharType.DEV.ordinal -> sp.putBoolean("showdeviations", !it.isChecked) - CharType.SEN.ordinal -> sp.putBoolean("showratios", !it.isChecked) - CharType.ACTPRIM.ordinal -> sp.putBoolean("showactivityprimary", !it.isChecked) - CharType.ACTSEC.ordinal -> sp.putBoolean("showactivitysecondary", !it.isChecked) - CharType.DEVSLOPE.ordinal -> sp.putBoolean("showdevslope", !it.isChecked) + // id < 100 graph header - divider 1, 2, 3 ..... + if (it.itemId == numOfGraphs) { + // add new empty + setting.add(Array(CharType.values().size) { false }) + } else if (it.itemId < 100) { + // remove graph + setting.removeAt(it.itemId) + } else { + val graphNumber = it.itemId / 100 - 1 + 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 } chartButton.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinFragment.kt index 21737cac6d..c2e61f19b9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinFragment.kt @@ -25,6 +25,6 @@ class InsulinFragment : DaggerFragment() { insulin_name?.setText(activePlugin.getActiveInsulin().getFriendlyName()) insulin_comment?.setText(activePlugin.getActiveInsulin().getComment()) insulin_dia?.text = resourceHelper.gs(R.string.dia) + ": " + activePlugin.getActiveInsulin().getDia() + "h" - insuling_graph?.show(activePlugin.getActiveInsulin()) + insulin_graph?.show(activePlugin.getActiveInsulin()) } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java index 5700a235a3..5521396b6b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java @@ -644,7 +644,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr } finally { pump.activity = null; rxBus.send(new EventComboPumpUpdateGUI()); - rxBus.send(new EventRefreshOverview("Bolus")); + rxBus.send(new EventRefreshOverview("Bolus", false)); cancelBolus = false; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java index a75398554e..bab8408935 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java @@ -464,7 +464,7 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface, lastUpdated = System.currentTimeMillis(); new Handler(Looper.getMainLooper()).post(() -> { 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) { 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 historyEvents) { @@ -1662,7 +1662,7 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface, activeTBR = null; activeBoluses = 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())); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java index 1c23665406..2f6c190179 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java @@ -1073,7 +1073,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter private void finishAction(String overviewKey) { if (overviewKey != null) - rxBus.send(new EventRefreshOverview(overviewKey)); + rxBus.send(new EventRefreshOverview(overviewKey, false)); triggerUIChange(); diff --git a/app/src/main/res/layout/insulin_fragment.xml b/app/src/main/res/layout/insulin_fragment.xml index 5f2a75850a..d1789ea80e 100644 --- a/app/src/main/res/layout/insulin_fragment.xml +++ b/app/src/main/res/layout/insulin_fragment.xml @@ -35,7 +35,7 @@ android:textAppearance="?android:attr/textAppearanceMedium" /> diff --git a/app/src/main/res/layout/overview_fragment.xml b/app/src/main/res/layout/overview_fragment.xml index 35ddd5eed4..64e32cf747 100644 --- a/app/src/main/res/layout/overview_fragment.xml +++ b/app/src/main/res/layout/overview_fragment.xml @@ -452,10 +452,11 @@ app:layout_constraintTop_toTopOf="@+id/overview_bggraph" /> - - - @@ -208,8 +208,8 @@ android:layout_height="wrap_content" android:layout_weight="0" android:gravity="center_horizontal" - android:paddingEnd="2dp" android:paddingStart="2dp" + android:paddingEnd="2dp" android:text=":" android:textSize="14sp" /> @@ -230,10 +230,10 @@ @@ -256,8 +256,8 @@ android:layout_height="wrap_content" android:layout_weight="0" android:gravity="center_horizontal" - android:paddingEnd="2dp" android:paddingStart="2dp" + android:paddingEnd="2dp" android:text=":" android:textSize="14sp" /> @@ -278,10 +278,10 @@ @@ -304,8 +304,8 @@ android:layout_height="wrap_content" android:layout_weight="0" android:gravity="center_horizontal" - android:paddingEnd="2dp" android:paddingStart="2dp" + android:paddingEnd="2dp" android:text=":" android:textSize="14sp" /> @@ -326,10 +326,10 @@ @@ -373,10 +373,10 @@ @@ -425,10 +425,10 @@ @@ -454,10 +454,10 @@ @@ -512,8 +512,8 @@ android:id="@+id/overview_chartMenuButton" android:layout_width="30dp" android:layout_height="wrap_content" - android:layout_alignParentEnd="true" android:layout_alignParentTop="true" + android:layout_alignParentEnd="true" android:paddingTop="5dp" app:srcCompat="@drawable/ic_arrow_drop_down_white_24dp" /> @@ -526,10 +526,11 @@ - + android:layout_height="wrap_content" + android:orientation="vertical" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1ac8463df0..47f535c51a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1801,4 +1801,7 @@ By reseting authenticator you make all already provisioned authenticators invalid. You will need to set up them again! On connect On disconnect + Predictions + Deviation slope + graphconfig