Skip to content

Commit f451024

Browse files
authored
improve dynamic view (#297)
* improve dynamic view * final fixes
1 parent 334aa61 commit f451024

File tree

13 files changed

+267
-28
lines changed

13 files changed

+267
-28
lines changed

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ android {
1212
applicationId "org.blitzortung.android.app"
1313
minSdkVersion 21
1414
targetSdkVersion 34
15-
versionCode 331
16-
versionName '2.3.0'
15+
versionCode 332
16+
versionName '2.3.1'
1717
multiDexEnabled false
1818
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1919
}

app/src/main/java/org/blitzortung/android/app/Main.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ class Main : FragmentActivity(), OnSharedPreferenceChangeListener {
432432
setHistoricStatusString()
433433
mapFragment.mapView.addMapListener(strikeListOverlay)
434434
mapFragment.mapView.addMapListener(dataHandler)
435+
mapFragment.mapView.addMapListener(binding.regionView)
435436

436437
fadeOverlay = FadeOverlay(strikeColorHandler)
437438

@@ -509,6 +510,7 @@ class Main : FragmentActivity(), OnSharedPreferenceChangeListener {
509510
requestUpdates(alertHandler.dataEventConsumer)
510511
requestUpdates(historyController.dataConsumer)
511512
requestUpdates(binding.histogramView.dataConsumer)
513+
requestUpdates(binding.regionView.dataConsumer)
512514
}
513515
}
514516

@@ -561,6 +563,7 @@ class Main : FragmentActivity(), OnSharedPreferenceChangeListener {
561563
Log.v(LOG_TAG, "Main.onStop()")
562564

563565
mapFragment.mapView.overlays.removeAll(setOf(fadeOverlay, ownLocationOverlay, strikeListOverlay))
566+
mapFragment.mapView.removeMapListener(binding.regionView)
564567
mapFragment.mapView.removeMapListener(ownLocationOverlay)
565568
mapFragment.mapView.removeMapListener(strikeListOverlay)
566569
mapFragment.mapView.removeMapListener(dataHandler)

app/src/main/java/org/blitzortung/android/app/view/HistogramView.kt

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,10 @@ class HistogramView @JvmOverloads constructor(
4646
private val backgroundPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
4747
private val foregroundPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
4848
private val textPaint: Paint
49-
private val smallTextPaint: Paint
5049
private val defaultForegroundColor: Int
5150
private val backgroundRect: RectF
5251
private var strikesOverlay: StrikeListOverlay? = null
5352
private var histogram: IntArray? = null
54-
private var gridParameters: GridParameters? = null
55-
private var parameters: Parameters? = null
5653
lateinit var mapFragment: MapFragment
5754

5855
val dataConsumer = { event: Event ->
@@ -71,11 +68,6 @@ class HistogramView @JvmOverloads constructor(
7168
textSize = this@HistogramView.textSize
7269
textAlign = Paint.Align.RIGHT
7370
}
74-
smallTextPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
75-
color = defaultForegroundColor
76-
textSize = this@HistogramView.textSize * SMALL_TEXT_SCALE
77-
textAlign = Paint.Align.RIGHT
78-
}
7971

8072
foregroundPaint.strokeWidth = 5f
8173

@@ -111,13 +103,6 @@ class HistogramView @JvmOverloads constructor(
111103

112104
var topCoordinate = padding
113105

114-
val gridParameters = gridParameters
115-
if (gridParameters != null && !gridParameters.isGlobal) {
116-
val text = "%.1f..%.1f %.1f..%.1f".format(gridParameters.longitudeStart, gridParameters.longitudeEnd, gridParameters.latitudeEnd, gridParameters.latitudeStart)
117-
canvas.drawText(text, width - padding, topCoordinate + textSize / 1.2f * SMALL_TEXT_SCALE, smallTextPaint)
118-
topCoordinate += (textSize + padding) * SMALL_TEXT_SCALE
119-
}
120-
121106
val maximumCount = histogram.maxOrNull() ?: 0
122107

123108
canvas.drawText(
@@ -167,8 +152,6 @@ class HistogramView @JvmOverloads constructor(
167152
histogram = null
168153
} else {
169154
val histogram = dataEvent.histogram
170-
gridParameters = dataEvent.gridParameters
171-
parameters = dataEvent.parameters
172155

173156
val hasHistogram = histogram != null && histogram.isNotEmpty()
174157

app/src/main/java/org/blitzortung/android/app/view/PreferenceKey.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ enum class PreferenceKey(val key: String) {
5454
KEEP_ZOOM_GOTO_OWN_LOCATION("keep_zoom_goto_own_location"),
5555
ANIMATION_INTERVAL_DURATION("animation_interval_duration"),
5656
ANIMATION_SLEEP_DURATION("animation_sleep_duration"),
57-
ANIMATION_CYCLE_SLEEP_DURATION("animation_cycle_sleep_duration");
57+
ANIMATION_CYCLE_SLEEP_DURATION("animation_cycle_sleep_duration"),
58+
DIAGNOSIS_ENABLED("diagnosis_enabled");
5859

5960
override fun toString(): String {
6061
return key
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
package org.blitzortung.android.app.view
2+
3+
import android.content.Context
4+
import android.content.SharedPreferences
5+
import android.graphics.Canvas
6+
import android.graphics.Paint
7+
import android.graphics.RectF
8+
import android.preference.PreferenceManager
9+
import android.util.AttributeSet
10+
import android.util.Log
11+
import android.view.ViewGroup
12+
import android.widget.RelativeLayout
13+
import org.blitzortung.android.app.Main
14+
import org.blitzortung.android.app.R
15+
import org.blitzortung.android.data.beans.GridParameters
16+
import org.blitzortung.android.data.provider.result.ResultEvent
17+
import org.blitzortung.android.protocol.Event
18+
import org.blitzortung.android.util.TabletAwareView
19+
import org.osmdroid.events.MapListener
20+
import org.osmdroid.events.ScrollEvent
21+
import org.osmdroid.events.ZoomEvent
22+
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
23+
import org.osmdroid.util.BoundingBox
24+
25+
private const val SMALL_TEXT_SCALE = 0.6f
26+
27+
class RegionView @JvmOverloads constructor(
28+
context: Context,
29+
attrs: AttributeSet? = null,
30+
defStyle: Int = 0
31+
) : TabletAwareView(context, attrs, defStyle), MapListener, OnSharedPreferenceChangeListener {
32+
33+
private val backgroundPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
34+
private val foregroundPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
35+
private val textPaint: Paint
36+
private val defaultForegroundColor: Int
37+
private val backgroundRect: RectF
38+
private var mapArea: BoundingBox? = null
39+
private var zoomLevel: Double? = null
40+
41+
private var gridParameters: GridParameters? = null
42+
43+
val dataConsumer = { event: Event ->
44+
if (event is ResultEvent) {
45+
updateHistogram(event)
46+
}
47+
}
48+
49+
init {
50+
backgroundPaint.color = 0x00b0b0b0
51+
52+
defaultForegroundColor = context.resources.getColor(R.color.text_foreground)
53+
54+
textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
55+
color = defaultForegroundColor
56+
textSize = this@RegionView.textSize * SMALL_TEXT_SCALE
57+
textAlign = Paint.Align.RIGHT
58+
}
59+
60+
foregroundPaint.strokeWidth = 5f
61+
62+
backgroundRect = RectF()
63+
64+
val preferences = PreferenceManager.getDefaultSharedPreferences(context)
65+
preferences.registerOnSharedPreferenceChangeListener(this)
66+
onSharedPreferenceChanged(preferences, PreferenceKey.DIAGNOSIS_ENABLED)
67+
}
68+
69+
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
70+
val getSize = fun(spec: Int) = MeasureSpec.getSize(spec)
71+
72+
val parentWidth = getSize(widthMeasureSpec) * sizeFactor
73+
val parentHeight = getSize(heightMeasureSpec) * sizeFactor
74+
75+
super.onMeasure(
76+
MeasureSpec.makeMeasureSpec(parentWidth.toInt(), MeasureSpec.EXACTLY),
77+
MeasureSpec.makeMeasureSpec(parentHeight.toInt(), MeasureSpec.EXACTLY)
78+
)
79+
}
80+
81+
override fun onDraw(canvas: Canvas) {
82+
83+
backgroundRect.set(0f, 0f, width.toFloat(), height.toFloat())
84+
canvas.drawRect(backgroundRect, backgroundPaint)
85+
86+
87+
var topCoordinate = 2 * padding
88+
89+
gridParameters?.let {
90+
if (!it.isGlobal) {
91+
val text = "%.1f..%.1f %.1f..%.1f".format(
92+
it.longitudeStart,
93+
it.longitudeEnd,
94+
it.latitudeEnd,
95+
it.latitudeStart
96+
)
97+
canvas.drawText(
98+
text,
99+
width - 2 * padding,
100+
topCoordinate + textSize / 1.2f * SMALL_TEXT_SCALE,
101+
textPaint
102+
)
103+
topCoordinate += (textSize + padding) * SMALL_TEXT_SCALE
104+
105+
val xdelta = it.longitudeEnd - it.longitudeStart
106+
val ydelta = it.latitudeStart - it.latitudeEnd
107+
val text2 = "%.1f %.1f".format(
108+
xdelta,
109+
ydelta,
110+
)
111+
canvas.drawText(
112+
text2,
113+
width - 2 * padding,
114+
topCoordinate + textSize / 1.2f * SMALL_TEXT_SCALE,
115+
textPaint
116+
)
117+
topCoordinate += (textSize + padding) * SMALL_TEXT_SCALE
118+
119+
val x0 = it.longitudeStart
120+
val y0 = it.latitudeStart
121+
122+
val xs = xdelta / (width - 2 * padding)
123+
val ys = ydelta / (height - 2 * padding)
124+
125+
mapArea?.let {
126+
val x1 = padding + ((it.lonEast - x0) / xs).toFloat()
127+
val x2 = padding + ((it.lonWest - x0) / xs).toFloat()
128+
val y1 = padding + ((y0 - it.latNorth) / ys).toFloat()
129+
val y2 = padding + ((y0 - it.latSouth) / ys).toFloat()
130+
131+
foregroundPaint.strokeWidth = 1f
132+
drawBox(canvas, x1, y1, x2, y2, foregroundPaint);
133+
}
134+
topCoordinate += textSize
135+
136+
foregroundPaint.strokeWidth = 3f
137+
foregroundPaint.color = defaultForegroundColor
138+
drawBox(canvas, padding, padding, width - padding, height - padding, foregroundPaint)
139+
}
140+
141+
zoomLevel?.let {
142+
val text = "Zoom %.1f".format(it )
143+
canvas.drawText(
144+
text,
145+
width - 2 * padding,
146+
height - 2 * padding ,
147+
textPaint
148+
)
149+
}
150+
}
151+
}
152+
153+
private fun drawBox(
154+
canvas: Canvas,
155+
x1: Float,
156+
y1: Float,
157+
x2: Float,
158+
y2: Float,
159+
paint: Paint
160+
) {
161+
canvas.drawLine(x1, y2, x2, y2, paint)
162+
canvas.drawLine(x1, y1, x2, y1, paint)
163+
canvas.drawLine(x2, y1, x2, y2, paint)
164+
canvas.drawLine(x1, y1, x1, y2, paint)
165+
}
166+
167+
168+
private fun updateHistogram(dataEvent: ResultEvent) {
169+
if (dataEvent.failed) {
170+
visibility = INVISIBLE
171+
gridParameters = null
172+
} else {
173+
gridParameters = dataEvent.gridParameters
174+
175+
invalidate()
176+
}
177+
}
178+
179+
private fun isVisible(gridParameters: GridParameters?) = gridParameters != null && !gridParameters.isGlobal
180+
override fun onScroll(event: ScrollEvent?): Boolean {
181+
return if (event != null) {
182+
this.mapArea = event.source.boundingBox
183+
zoomLevel = event.source.zoomLevelDouble
184+
updateViewSize()
185+
true
186+
} else {
187+
false
188+
}
189+
}
190+
191+
override fun onZoom(event: ZoomEvent?): Boolean {
192+
return if (event != null) {
193+
mapArea = event.source.boundingBox
194+
zoomLevel = event.zoomLevel
195+
updateViewSize()
196+
true
197+
} else {
198+
false
199+
}
200+
}
201+
202+
private fun updateViewSize() {
203+
mapArea?.let {
204+
val lonDelta = it.lonEast - it.lonWest
205+
val pixelSize = lonDelta / width
206+
val latDelta = it.latNorth - it.latSouth
207+
val height = Math.max((latDelta / pixelSize).toInt(), (3 * padding + 3 * textSize).toInt())
208+
layoutParams.height= height
209+
invalidate()
210+
}
211+
}
212+
213+
override fun onSharedPreferenceChanged(
214+
sharedPreferences: SharedPreferences,
215+
key: PreferenceKey
216+
) {
217+
when (key) {
218+
PreferenceKey.DIAGNOSIS_ENABLED-> {
219+
val diagnosisEnabled = sharedPreferences.get(key, false)
220+
visibility = if (diagnosisEnabled) {
221+
VISIBLE
222+
} else {
223+
INVISIBLE
224+
}
225+
}
226+
227+
else -> {}
228+
}
229+
}
230+
231+
}

app/src/main/java/org/blitzortung/android/data/MainDataHandler.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -446,10 +446,10 @@ class MainDataHandler @Inject constructor(
446446
fun updateAutoGridSize(zoomLevel: Double): Boolean =
447447
if (autoGridSize) {
448448
val gridSize = when {
449-
zoomLevel >= 8f -> 5000
450-
zoomLevel in 5f..8f -> 10000
451-
zoomLevel in 4f..5f -> 25000
452-
zoomLevel in 2f..4f -> 50000
449+
zoomLevel >= 7.5f -> 5000
450+
zoomLevel in 5f..7.5f -> 10000
451+
zoomLevel in 3.5f..5f -> 25000
452+
zoomLevel in 2.5f..3.5f -> 50000
453453
else -> 100000
454454
}
455455
if (parameters.gridSize != gridSize) {

app/src/main/java/org/blitzortung/android/data/provider/LocalData.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ private const val LOCAL_DATA_AREA = MIN_DATA_AREA
1919

2020
private const val DATA_AREA_SCALING = 0.5
2121

22+
private const val LOCAL_REGION_THRESHOLD = 10000
23+
2224
@Singleton
2325
class LocalData @Inject constructor() {
2426

@@ -41,7 +43,7 @@ class LocalData @Inject constructor() {
4143
}
4244

4345
GLOBAL_REGION -> {
44-
if (localReference != null && parameters.gridSize <= 10000) {
46+
if (localReference != null && parameters.gridSize <= LOCAL_REGION_THRESHOLD) {
4547
Log.d(LOG_TAG, "LocalData.updateParameters() global -> local")
4648
parameters.copy(region = LOCAL_REGION, localReference = localReference, dataArea = dataArea)
4749
} else {

app/src/main/res/layout/main.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,14 @@
119119
android:layout_alignParentLeft="true"
120120
local:tablet_scaleable="true" />
121121

122+
<org.blitzortung.android.app.view.RegionView
123+
android:id="@+id/region_view"
124+
android:layout_width="110dp"
125+
android:layout_height="110dp"
126+
android:layout_above="@+id/histogram_view"
127+
android:layout_alignParentRight="true"
128+
local:tablet_scaleable="true" />
129+
122130
<org.blitzortung.android.app.view.HistogramView
123131
android:id="@+id/histogram_view"
124132
android:layout_width="110dp"

app/src/main/res/values-de/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,4 +391,6 @@ Ivan Karev (karev.ivan@gmail.com)\nTschechisch: Jakub Mareček (jakubmarecek715@
391391
<string name="animation_cycle_sleep_duration_summary">Wartezeit vor dem Start eines neuen Animationszyklus in Millisekunden</string>
392392
<string name="animation_settings">Animation</string>
393393
<string name="animation_settings_summary">Parameter der Animation</string>
394+
<string name="diagnosis">Diagnosefeatures</string>
395+
<string name="diagnosis_summary">Aktiviert Features für die App-Analyse</string>
394396
</resources>

app/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,4 +410,6 @@ Russian by Ivan Karev (karev.ivan@gmail.com)\n
410410
<item>12</item>
411411
<item>24</item>
412412
</string-array>
413+
<string name="diagnosis">Diagnosis features</string>
414+
<string name="diagnosis_summary">Enable features supporting diagnosis of app functionality.</string>
413415
</resources>

0 commit comments

Comments
 (0)