From 6dd46fff881c3e07993332fe9e2a3186d01a8460 Mon Sep 17 00:00:00 2001 From: bailuk Date: Tue, 9 Apr 2024 17:42:33 +0200 Subject: [PATCH 01/10] GTK: Change file list layout --- .../kotlin/ch/bailu/aat_gtk/view/list/FileList.kt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt index b744717f7..39fae4db6 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt @@ -159,12 +159,14 @@ class FileList(app: Application, } } - vbox.append(fileNameLabel) vbox.append(Box(Orientation.HORIZONTAL, Layout.margin).apply { append(Box(Orientation.HORIZONTAL, 0).apply { addCssClass(Strings.linked) append( - SolidDirectoryQueryComboView(appContext).combo.apply { addCssClass(Strings.linked) }) + SolidDirectoryQueryComboView(appContext).combo.apply { + addCssClass(Strings.linked) + hexpand = true + }) append(Button().apply { iconName = Icons.folderSymbolic onClicked { @@ -173,9 +175,9 @@ class FileList(app: Application, } }) }) + }) - append(Separator(Orientation.VERTICAL)) - + vbox.append(Box(Orientation.HORIZONTAL, Layout.margin).apply { append(Box(Orientation.HORIZONTAL, 0).apply { append(trackFrameButton) append(trackCenterButton) @@ -183,6 +185,8 @@ class FileList(app: Application, append(menuButton) addCssClass(Strings.linked) }) + append(Separator(Orientation.VERTICAL)) + append(fileNameLabel) }) vbox.append(ScrolledWindow().apply { From d5ebaea04899414c6d08cb2e4c2e7ae4ac2c379e Mon Sep 17 00:00:00 2001 From: bailuk Date: Tue, 9 Apr 2024 19:24:20 +0200 Subject: [PATCH 02/10] GTK/Android: Improve getGpxDirectories helper function --- .../ch/bailu/aat/map/layer/EditorBarLayer.kt | 50 +++++++------------ .../kotlin/ch/bailu/aat/menus/EditorMenu.kt | 10 ++-- .../ch/bailu/aat/util/fs/AndroidFileAction.kt | 2 +- .../aat/util/ui/AppSelectDirectoryDialog.kt | 33 ++++++------ .../solid/SolidDirectoryQueryComboView.kt | 26 +++++----- .../ch/bailu/aat_lib/util/fs/AppDirectory.kt | 35 +++++++++---- 6 files changed, 78 insertions(+), 78 deletions(-) diff --git a/aat-android/src/main/kotlin/ch/bailu/aat/map/layer/EditorBarLayer.kt b/aat-android/src/main/kotlin/ch/bailu/aat/map/layer/EditorBarLayer.kt index 784223d40..42925ee56 100644 --- a/aat-android/src/main/kotlin/ch/bailu/aat/map/layer/EditorBarLayer.kt +++ b/aat-android/src/main/kotlin/ch/bailu/aat/map/layer/EditorBarLayer.kt @@ -16,10 +16,9 @@ import ch.bailu.aat_lib.map.edge.Position import ch.bailu.aat_lib.map.layer.gpx.GpxDynLayer import ch.bailu.aat_lib.preferences.StorageInterface import ch.bailu.aat_lib.resources.Res -import ch.bailu.aat_lib.service.ServicesInterface class EditorBarLayer( - appContext: AppContext, + private val appContext: AppContext, context: Context, private val mcontext: MapContext, dispatcher: DispatcherInterface, @@ -35,15 +34,10 @@ class EditorBarLayer( private val down: View = bar.addImageButton(R.drawable.go_down) private val undo: View = bar.addImageButton(R.drawable.edit_redo) private val redo: View = bar.addImageButton(R.drawable.edit_redo) - private val services: ServicesInterface - private val selector: EditorNodeViewLayer - private val content: GpxDynLayer + private val content: GpxDynLayer = GpxDynLayer(appContext.storage, mcontext, appContext.services) + private val selector = EditorNodeViewLayer(appContext, context, mcontext, edit) init { - services = appContext.services - content = GpxDynLayer(appContext.storage, mcontext, appContext.services) - selector = EditorNodeViewLayer(appContext, context, mcontext, edit) - ToolTip.set(add, Res.str().tt_edit_add()) ToolTip.set(remove, Res.str().tt_edit_remove()) ToolTip.set(up, Res.str().tt_edit_up()) @@ -73,30 +67,22 @@ class EditorBarLayer( } } - override fun onClick(v: View) { - super.onClick(v) + override fun onClick(view: View) { + super.onClick(view) val editor = edit.editor - if (v === add) { - val p = mcontext.getMapView().getMapViewPosition().center - editor.add( - GpxPoint( - p, - services.elevationService.getElevation(p.latitudeE6, p.longitudeE6).toFloat(), - 0 - ) - ) - } else if (v === remove) { - editor.remove() - } else if (v === up){ - editor.up() - } else if (v === down){ - editor.down() - } else if (v === undo){ - editor.undo() - } else if (v === redo){ - editor.redo() - } else if (v === menu){ - EditorMenu(v.context, services, editor, edit.file).showAsPopup(v.context, v) + + when(view) { + add -> { + val pos = mcontext.getMapView().getMapViewPosition().center + val ele = appContext.services.elevationService.getElevation(pos.latitudeE6, pos.longitudeE6).toFloat() + editor.add(GpxPoint(pos, ele,0)) + } + remove -> editor.remove() + up -> editor.up() + down -> editor.down() + undo -> editor.undo() + redo -> editor.redo() + menu -> EditorMenu(appContext, view.context, editor, edit.file).showAsPopup(view.context, view) } } diff --git a/aat-android/src/main/kotlin/ch/bailu/aat/menus/EditorMenu.kt b/aat-android/src/main/kotlin/ch/bailu/aat/menus/EditorMenu.kt index eb2f7ffff..40dec4b19 100644 --- a/aat-android/src/main/kotlin/ch/bailu/aat/menus/EditorMenu.kt +++ b/aat-android/src/main/kotlin/ch/bailu/aat/menus/EditorMenu.kt @@ -8,10 +8,10 @@ import ch.bailu.aat.R import ch.bailu.aat.preferences.system.AndroidSolidDataDirectoryDefault import ch.bailu.aat.util.ui.AppSelectDirectoryDialog import ch.bailu.aat.views.preferences.dialog.AbsSelectOverlayDialog +import ch.bailu.aat_lib.app.AppContext import ch.bailu.aat_lib.gpx.interfaces.GpxType import ch.bailu.aat_lib.preferences.map.SolidCustomOverlayList import ch.bailu.aat_lib.preferences.system.SolidDataDirectory -import ch.bailu.aat_lib.service.ServicesInterface import ch.bailu.aat_lib.service.cache.Obj import ch.bailu.aat_lib.service.cache.gpx.ObjGpx import ch.bailu.aat_lib.service.editor.EditorInterface @@ -20,8 +20,8 @@ import ch.bailu.foc.Foc import ch.bailu.foc_android.FocAndroidFactory class EditorMenu( + private val appContext: AppContext, private val context: Context, - private val scontext: ServicesInterface, private val editor: EditorInterface, private val file: Foc ) : AbsMenu() { @@ -57,7 +57,7 @@ class EditorMenu( } private fun saveCopyTo() { - object : AppSelectDirectoryDialog(context, file) { + object : AppSelectDirectoryDialog(appContext, context, file) { override fun copyTo(context: Context, srcFile: Foc, destDirectory: Foc) { editor.saveTo(destDirectory) } @@ -67,8 +67,8 @@ class EditorMenu( private fun attach() { object : AbsSelectOverlayDialog(context) { override fun onFileSelected(slist: SolidCustomOverlayList, index: Int, file: Foc) { - scontext.insideContext { - val handle = scontext.cacheService.getObject( + appContext.services.insideContext { + val handle = appContext.services.cacheService.getObject( file.path, Obj.Factory() ) diff --git a/aat-android/src/main/kotlin/ch/bailu/aat/util/fs/AndroidFileAction.kt b/aat-android/src/main/kotlin/ch/bailu/aat/util/fs/AndroidFileAction.kt index d01118654..b91af5a58 100644 --- a/aat-android/src/main/kotlin/ch/bailu/aat/util/fs/AndroidFileAction.kt +++ b/aat-android/src/main/kotlin/ch/bailu/aat/util/fs/AndroidFileAction.kt @@ -66,7 +66,7 @@ object AndroidFileAction { } fun copyToDir(context: Context, appContext: AppContext, src: Foc) { - object : AppSelectDirectoryDialog(context, src) { + object : AppSelectDirectoryDialog(appContext, context, src) { override fun copyTo( context: Context, srcFile: Foc, diff --git a/aat-android/src/main/kotlin/ch/bailu/aat/util/ui/AppSelectDirectoryDialog.kt b/aat-android/src/main/kotlin/ch/bailu/aat/util/ui/AppSelectDirectoryDialog.kt index aaa2c6d02..00c8b44cf 100644 --- a/aat-android/src/main/kotlin/ch/bailu/aat/util/ui/AppSelectDirectoryDialog.kt +++ b/aat-android/src/main/kotlin/ch/bailu/aat/util/ui/AppSelectDirectoryDialog.kt @@ -4,30 +4,31 @@ import android.app.AlertDialog import android.content.Context import android.content.DialogInterface import ch.bailu.aat.R -import ch.bailu.aat.preferences.system.AndroidSolidDataDirectoryDefault -import ch.bailu.aat_lib.preferences.system.SolidDataDirectory +import ch.bailu.aat_lib.app.AppContext import ch.bailu.aat_lib.util.fs.AppDirectory import ch.bailu.foc.Foc -import ch.bailu.foc_android.FocAndroidFactory -abstract class AppSelectDirectoryDialog(private val context: Context, private val srcFile: Foc) { - private val directories: Array +abstract class AppSelectDirectoryDialog(appContext: AppContext, context: Context, private val srcFile: Foc) { + private val directories = AppDirectory.getGpxDirectories(appContext) init { - val sdirectory = SolidDataDirectory(AndroidSolidDataDirectoryDefault(context), FocAndroidFactory(context)) - directories = AppDirectory.getGpxDirectories(sdirectory) - val names = arrayOfNulls(directories.size) - for (i in names.indices) names[i] = directories[i].name - val dialog = AlertDialog.Builder(context) - dialog.setTitle(srcFile.name + ": " + context.getString(R.string.file_copy)) + AlertDialog.Builder(context).apply { + setTitle(srcFile.name + ": " + context.getString(R.string.file_copy)) - dialog.setItems(names) { dialogInterface: DialogInterface, index: Int -> - copyTo(context, srcFile, directories[index]) - dialogInterface.dismiss() + setItems(toNameArray(directories)) { dialogInterface: DialogInterface, index: Int -> + copyTo(context, srcFile, directories[index].file) + dialogInterface.dismiss() + } + + create() + show() } + } - dialog.create() - dialog.show() + private fun toNameArray(directories: ArrayList): Array { + return Array(directories.size) { + directories[it].name + } } abstract fun copyTo(context: Context, srcFile: Foc, destDirectory: Foc) diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/solid/SolidDirectoryQueryComboView.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/solid/SolidDirectoryQueryComboView.kt index a512604d4..c9a19159f 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/solid/SolidDirectoryQueryComboView.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/solid/SolidDirectoryQueryComboView.kt @@ -6,41 +6,39 @@ import ch.bailu.aat_lib.preferences.SolidDirectoryQuery import ch.bailu.aat_lib.preferences.StorageInterface import ch.bailu.aat_lib.util.fs.AppDirectory import ch.bailu.gtk.gtk.ComboBoxText -import ch.bailu.gtk.type.Str class SolidDirectoryQueryComboView(appContext: AppContext) : OnPreferencesChanged { - private val solid = SolidDirectoryQuery(appContext.storage, appContext) - private val sdirectory = appContext.dataDirectory - private val directories = AppDirectory.getGpxDirectories(sdirectory) + private val solidDirectoryQuery = SolidDirectoryQuery(appContext.storage, appContext) + private val directories = AppDirectory.getGpxDirectories(appContext) val combo = ComboBoxText() init { - var index = 0 - directories.forEach { - combo.insertText(index++, Str(it.name)) + directories.forEachIndexed { index, gpxDirectoryEntry -> + combo.insertText(index, gpxDirectoryEntry.name) } + indexFromSolid() + combo.onChanged { - solid.setValue(directories[combo.active].path) + solidDirectoryQuery.setValue(directories[combo.active].file.path) } - solid.register(this) + + solidDirectoryQuery.register(this) } override fun onPreferencesChanged(storage: StorageInterface, key: String) { - if (key == solid.getKey()) { + if (key == solidDirectoryQuery.getKey()) { indexFromSolid() } } private fun indexFromSolid() { - var index = 0 - directories.forEach { - if (it == solid.getValueAsFile()) { + directories.forEachIndexed { index, directory -> + if (directory.file == solidDirectoryQuery.getValueAsFile()) { combo.active = index } - index++ } } } diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/util/fs/AppDirectory.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/util/fs/AppDirectory.kt index 4a6ae3359..04aeac2f1 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/util/fs/AppDirectory.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/util/fs/AppDirectory.kt @@ -1,7 +1,10 @@ package ch.bailu.aat_lib.util.fs +import ch.bailu.aat_lib.app.AppContext import ch.bailu.aat_lib.preferences.map.SolidTileCacheDirectory +import ch.bailu.aat_lib.preferences.presets.SolidPreset import ch.bailu.aat_lib.preferences.system.SolidDataDirectory +import ch.bailu.aat_lib.resources.Res import ch.bailu.foc.Foc import java.io.IOException import java.util.Locale @@ -116,15 +119,27 @@ object AppDirectory { return name.toString() } - fun getGpxDirectories(sdirectory: SolidDataDirectory): Array { - return arrayOf( - getTrackListDirectory(sdirectory, 0), - getTrackListDirectory(sdirectory, 1), - getTrackListDirectory(sdirectory, 2), - getTrackListDirectory(sdirectory, 3), - getTrackListDirectory(sdirectory, 4), - getDataDirectory(sdirectory, DIR_OVERLAY), - getDataDirectory(sdirectory, DIR_IMPORT) - ) + /** + * List of gpx directories as name / directory pair + * All presets (according to SolidPreset) and overlay and import directories + */ + fun getGpxDirectories(appContext: AppContext): ArrayList { + val result = ArrayList() + val solidPreset = SolidPreset(appContext.storage) + + for (index in 0 until solidPreset.length()) { + val name = solidPreset.getValueAsString(index) + val directory = getTrackListDirectory(appContext.dataDirectory, index) + result.add(GpxDirectoryEntry(name, directory)) + } + getDataDirectory(appContext.dataDirectory, DIR_OVERLAY).apply { + result.add(GpxDirectoryEntry(Res.str().p_overlay(), this)) + } + getDataDirectory(appContext.dataDirectory, DIR_IMPORT).apply { + result.add(GpxDirectoryEntry(this.name, this)) + } + return result } + + data class GpxDirectoryEntry(val name: String, val file: Foc) } From b57cb65b17160ac62a17caebbdb760da1c82ba1d Mon Sep 17 00:00:00 2001 From: bailuk Date: Tue, 9 Apr 2024 20:07:50 +0200 Subject: [PATCH 03/10] Add spinner to GPX list and change signature of Broadcaster.register so that functional parameter is the last one --- .../kotlin/ch/bailu/aat/activities/AbsOsmApiActivity.kt | 4 ++-- .../kotlin/ch/bailu/aat/dispatcher/AndroidBroadcaster.kt | 2 +- .../main/kotlin/ch/bailu/aat/dispatcher/SensorSource.kt | 2 +- .../kotlin/ch/bailu/aat/services/sensor/SensorService.kt | 6 +++--- .../bailu/aat/services/tileremover/TileRemoverService.kt | 4 ++-- .../kotlin/ch/bailu/aat_gtk/dispatcher/GtkBroadcaster.kt | 2 +- .../main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt | 8 +++++++- .../kotlin/ch/bailu/aat_gtk/view/messages/MessageBar.kt | 4 ++-- .../java/ch/bailu/aat_lib/description/EditorSource.kt | 2 +- .../main/java/ch/bailu/aat_lib/dispatcher/Broadcaster.kt | 2 +- .../ch/bailu/aat_lib/dispatcher/CurrentLocationSource.kt | 2 +- .../main/java/ch/bailu/aat_lib/dispatcher/FileSource.kt | 2 +- .../java/ch/bailu/aat_lib/dispatcher/IteratorSource.kt | 2 +- .../java/ch/bailu/aat_lib/dispatcher/TrackerSource.kt | 2 +- .../main/java/ch/bailu/aat_lib/map/tile/TileProvider.kt | 2 +- .../java/ch/bailu/aat_lib/service/cache/CacheService.java | 2 +- .../ch/bailu/aat_lib/service/cache/ObjectBroadcaster.java | 4 ++-- .../aat_lib/service/directory/DirectorySynchronizer.kt | 2 +- .../bailu/aat_lib/service/directory/IteratorAbstract.kt | 2 +- .../aat_lib/service/elevation/loader/Dem3TileLoader.java | 2 +- .../service/elevation/updater/ElevationUpdater.java | 3 +-- .../ch/bailu/aat_lib/service/tracker/TrackerService.java | 2 +- 22 files changed, 34 insertions(+), 29 deletions(-) diff --git a/aat-android/src/main/kotlin/ch/bailu/aat/activities/AbsOsmApiActivity.kt b/aat-android/src/main/kotlin/ch/bailu/aat/activities/AbsOsmApiActivity.kt index 80687ad44..e0428ea53 100644 --- a/aat-android/src/main/kotlin/ch/bailu/aat/activities/AbsOsmApiActivity.kt +++ b/aat-android/src/main/kotlin/ch/bailu/aat/activities/AbsOsmApiActivity.kt @@ -46,8 +46,8 @@ abstract class AbsOsmApiActivity : ActivityContext(), View.OnClickListener { addTarget(list!!, InfoID.FILE_VIEW) appContext.broadcaster.register( - onFileTaskChanged, - AppBroadcaster.FILE_BACKGROUND_TASK_CHANGED + AppBroadcaster.FILE_BACKGROUND_TASK_CHANGED, + onFileTaskChanged ) } diff --git a/aat-android/src/main/kotlin/ch/bailu/aat/dispatcher/AndroidBroadcaster.kt b/aat-android/src/main/kotlin/ch/bailu/aat/dispatcher/AndroidBroadcaster.kt index 866b98a72..45c3e2dd7 100644 --- a/aat-android/src/main/kotlin/ch/bailu/aat/dispatcher/AndroidBroadcaster.kt +++ b/aat-android/src/main/kotlin/ch/bailu/aat/dispatcher/AndroidBroadcaster.kt @@ -17,7 +17,7 @@ class AndroidBroadcaster(private val context: Context) : Broadcaster { context.sendBroadcast(AppIntent.toIntent(action, *args)) } - override fun register(broadcastReceiver: BroadcastReceiver, action: String) { + override fun register(action: String, broadcastReceiver: BroadcastReceiver) { if (!observers.containsKey(broadcastReceiver)) { val receiver = object : android.content.BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { diff --git a/aat-android/src/main/kotlin/ch/bailu/aat/dispatcher/SensorSource.kt b/aat-android/src/main/kotlin/ch/bailu/aat/dispatcher/SensorSource.kt index d2d978c98..fb0c31166 100644 --- a/aat-android/src/main/kotlin/ch/bailu/aat/dispatcher/SensorSource.kt +++ b/aat-android/src/main/kotlin/ch/bailu/aat/dispatcher/SensorSource.kt @@ -21,7 +21,7 @@ class SensorSource(private val services: ServicesInterface, private val broadcas } override fun onResume() { - broadcaster.register(onSensorUpdated, changedAction) + broadcaster.register(changedAction, onSensorUpdated) } override fun getIID(): Int { diff --git a/aat-android/src/main/kotlin/ch/bailu/aat/services/sensor/SensorService.kt b/aat-android/src/main/kotlin/ch/bailu/aat/services/sensor/SensorService.kt index 22439d7eb..aa7658e31 100644 --- a/aat-android/src/main/kotlin/ch/bailu/aat/services/sensor/SensorService.kt +++ b/aat-android/src/main/kotlin/ch/bailu/aat/services/sensor/SensorService.kt @@ -49,10 +49,10 @@ class SensorService(sc: ServiceContext) : VirtualService(), WithStatusText, Sens BluetoothAdapter.ACTION_STATE_CHANGED ) broadcaster.register( - onSensorDisconnected, - AppBroadcaster.SENSOR_DISCONNECTED + InfoID.SENSORS + AppBroadcaster.SENSOR_DISCONNECTED + InfoID.SENSORS, + onSensorDisconnected ) - broadcaster.register(onSensorReconnect, AppBroadcaster.SENSOR_RECONNECT + InfoID.SENSORS) + broadcaster.register(AppBroadcaster.SENSOR_RECONNECT + InfoID.SENSORS, onSensorReconnect) updateConnections() } diff --git a/aat-android/src/main/kotlin/ch/bailu/aat/services/tileremover/TileRemoverService.kt b/aat-android/src/main/kotlin/ch/bailu/aat/services/tileremover/TileRemoverService.kt index 19bcc6413..cf37bf574 100644 --- a/aat-android/src/main/kotlin/ch/bailu/aat/services/tileremover/TileRemoverService.kt +++ b/aat-android/src/main/kotlin/ch/bailu/aat/services/tileremover/TileRemoverService.kt @@ -22,8 +22,8 @@ class TileRemoverService(val appContext: AppContext) : VirtualService() { private val onStopped: BroadcastReceiver = BroadcastReceiver {free() } init { - appContext.broadcaster.register(onStopped, AppBroadcaster.TILE_REMOVER_STOPPED) - appContext.broadcaster.register(onRemove, AppBroadcaster.TILE_REMOVER_REMOVE) + appContext.broadcaster.register(AppBroadcaster.TILE_REMOVER_STOPPED, onStopped) + appContext.broadcaster.register(AppBroadcaster.TILE_REMOVER_REMOVE, onRemove) state = StateMachine(appContext) } diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/dispatcher/GtkBroadcaster.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/dispatcher/GtkBroadcaster.kt index 627486223..952f8998f 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/dispatcher/GtkBroadcaster.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/dispatcher/GtkBroadcaster.kt @@ -36,7 +36,7 @@ class GtkBroadcaster : Broadcaster { } @Synchronized - override fun register(broadcastReceiver: BroadcastReceiver, action: String) { + override fun register(action: String, broadcastReceiver: BroadcastReceiver) { unregister(broadcastReceiver) signals.putIfAbsent(action, ArrayList()) signals[action]?.add(broadcastReceiver) diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt index 39fae4db6..05580b414 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt @@ -15,6 +15,7 @@ import ch.bailu.aat_lib.description.AverageSpeedDescription import ch.bailu.aat_lib.description.DateDescription import ch.bailu.aat_lib.description.DistanceDescription import ch.bailu.aat_lib.description.TimeDescription +import ch.bailu.aat_lib.dispatcher.AppBroadcaster import ch.bailu.aat_lib.gpx.InfoID import ch.bailu.aat_lib.logger.AppLog import ch.bailu.aat_lib.preferences.SolidDirectoryQuery @@ -33,6 +34,7 @@ import ch.bailu.gtk.gtk.PopoverMenu import ch.bailu.gtk.gtk.ScrolledWindow import ch.bailu.gtk.gtk.Separator import ch.bailu.gtk.gtk.SignalListItemFactory +import ch.bailu.gtk.gtk.Spinner import ch.bailu.gtk.lib.bridge.ListIndex import ch.bailu.gtk.lib.util.SizeLog import ch.bailu.gtk.type.Str @@ -164,7 +166,6 @@ class FileList(app: Application, addCssClass(Strings.linked) append( SolidDirectoryQueryComboView(appContext).combo.apply { - addCssClass(Strings.linked) hexpand = true }) append(Button().apply { @@ -175,6 +176,11 @@ class FileList(app: Application, } }) }) + append(Spinner().apply { + appContext.broadcaster.register(AppBroadcaster.DBSYNC_DONE) { stop() } + appContext.broadcaster.register(AppBroadcaster.DB_SYNC_CHANGED) { start() } + appContext.broadcaster.register(AppBroadcaster.DBSYNC_START) { start() } + }) }) vbox.append(Box(Orientation.HORIZONTAL, Layout.margin).apply { diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/messages/MessageBar.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/messages/MessageBar.kt index 9108c794a..001e26def 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/messages/MessageBar.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/messages/MessageBar.kt @@ -14,13 +14,13 @@ class MessageBar(messageType: String, cssClass: String) { } init { - GtkAppContext.broadcaster.register({ + GtkAppContext.broadcaster.register(messageType) { if (it.size > 1) { label.setText(it[1]) label.show() timer.cancel() timer.kick(5000) { label.hide() } } - }, messageType) + } } } diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/description/EditorSource.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/description/EditorSource.kt index 19daa697c..db78fe9e3 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/description/EditorSource.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/description/EditorSource.kt @@ -31,7 +31,7 @@ class EditorSource(private val appContext: AppContext) : ContentSource(), Editor } override fun onResume() { - appContext.broadcaster.register(onFileEdited, AppBroadcaster.FILE_CHANGED_INCACHE) + appContext.broadcaster.register(AppBroadcaster.FILE_CHANGED_INCACHE, onFileEdited) edit.onResume() } diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/Broadcaster.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/Broadcaster.kt index bbe64e415..7c8529cea 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/Broadcaster.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/Broadcaster.kt @@ -2,6 +2,6 @@ package ch.bailu.aat_lib.dispatcher interface Broadcaster { fun broadcast(action: String, vararg args: String) - fun register(broadcastReceiver: BroadcastReceiver, action: String) + fun register(action: String, broadcastReceiver: BroadcastReceiver) fun unregister(broadcastReceiver: BroadcastReceiver) } diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/CurrentLocationSource.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/CurrentLocationSource.kt index ced4efb7f..a8353b223 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/CurrentLocationSource.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/CurrentLocationSource.kt @@ -24,7 +24,7 @@ class CurrentLocationSource( } override fun onResume() { - broadcaster.register(onLocationChange, AppBroadcaster.LOCATION_CHANGED) + broadcaster.register(AppBroadcaster.LOCATION_CHANGED, onLocationChange) } override fun getIID(): Int { diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/FileSource.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/FileSource.kt index a090a10f4..87caa29dd 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/FileSource.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/FileSource.kt @@ -25,7 +25,7 @@ open class FileSource(private val context: AppContext, private val iid: Int) : C override fun onResume() { lifeCycleEnabled = true - context.broadcaster.register(onChangedInCache, AppBroadcaster.FILE_CHANGED_INCACHE) + context.broadcaster.register(AppBroadcaster.FILE_CHANGED_INCACHE, onChangedInCache) if (trackEnabled) { gpxHandler.enable(context.services) } diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/IteratorSource.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/IteratorSource.kt index ee93bb24d..cebb35085 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/IteratorSource.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/IteratorSource.kt @@ -78,7 +78,7 @@ abstract class IteratorSource(private val appContext: AppContext) : ContentSourc } override fun onResume() { - appContext.broadcaster.register(onChangedInCache, AppBroadcaster.FILE_CHANGED_INCACHE) + appContext.broadcaster.register(AppBroadcaster.FILE_CHANGED_INCACHE, onChangedInCache) super.onResume() } diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/TrackerSource.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/TrackerSource.kt index ffdd3176e..e47f1ca9a 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/TrackerSource.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/dispatcher/TrackerSource.kt @@ -18,7 +18,7 @@ class TrackerSource(private val services: ServicesInterface, private val broadca } override fun onResume() { - broadcaster.register(onTrackChanged, AppBroadcaster.TRACKER) + broadcaster.register(AppBroadcaster.TRACKER, onTrackChanged) } override fun getIID(): Int { diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/map/tile/TileProvider.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/map/tile/TileProvider.kt index 411c1eaba..e85bfc34e 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/map/tile/TileProvider.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/map/tile/TileProvider.kt @@ -87,7 +87,7 @@ class TileProvider(private val appContext: AppContext, val source: Source) : Att if (!isAttached) { cache.reset() cache = TileObjectCache() - appContext.broadcaster.register(onFileChanged, AppBroadcaster.FILE_CHANGED_INCACHE) + appContext.broadcaster.register(AppBroadcaster.FILE_CHANGED_INCACHE, onFileChanged) isAttached = true } } diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/service/cache/CacheService.java b/aat-lib/src/main/java/ch/bailu/aat_lib/service/cache/CacheService.java index fe8316206..d62cd094c 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/service/cache/CacheService.java +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/service/cache/CacheService.java @@ -28,7 +28,7 @@ public CacheService(AppContext sc) { table.limit(this, slimit.getValueAsLong()); - sc.getBroadcaster().register(onFileProcessed, AppBroadcaster.FILE_CHANGED_INCACHE); + sc.getBroadcaster().register(AppBroadcaster.FILE_CHANGED_INCACHE, onFileProcessed); } public void onLowMemory() { diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/service/cache/ObjectBroadcaster.java b/aat-lib/src/main/java/ch/bailu/aat_lib/service/cache/ObjectBroadcaster.java index 594bd3854..7f6bd6ba2 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/service/cache/ObjectBroadcaster.java +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/service/cache/ObjectBroadcaster.java @@ -21,8 +21,8 @@ public final class ObjectBroadcaster implements Closeable { public ObjectBroadcaster(AppContext sc) { appContext = sc; - appContext.getBroadcaster().register(onFileChanged, AppBroadcaster.FILE_CHANGED_INCACHE); - appContext.getBroadcaster().register(onFileDownloaded, AppBroadcaster.FILE_CHANGED_ONDISK); + appContext.getBroadcaster().register(AppBroadcaster.FILE_CHANGED_INCACHE, onFileChanged); + appContext.getBroadcaster().register(AppBroadcaster.FILE_CHANGED_ONDISK, onFileDownloaded); } public synchronized void put(ObjBroadcastReceiver b) { diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/DirectorySynchronizer.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/DirectorySynchronizer.kt index 9c56d905b..f915f96ec 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/DirectorySynchronizer.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/DirectorySynchronizer.kt @@ -73,7 +73,7 @@ class DirectorySynchronizer(private val appContext: AppContext, private val dire * TODO: move db open into background */ override fun start() { - appContext.broadcaster.register(onFileChanged, AppBroadcaster.FILE_CHANGED_INCACHE) + appContext.broadcaster.register(AppBroadcaster.FILE_CHANGED_INCACHE, onFileChanged) try { database = openDatabase() setState(StatePrepareSync()) diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/IteratorAbstract.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/IteratorAbstract.kt index fe15093c4..9af687760 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/IteratorAbstract.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/IteratorAbstract.kt @@ -22,7 +22,7 @@ abstract class IteratorAbstract(private val appContext: AppContext) : Iterator() init { sdirectory.register(this) - appContext.broadcaster.register(onSyncChanged, AppBroadcaster.DB_SYNC_CHANGED) + appContext.broadcaster.register(AppBroadcaster.DB_SYNC_CHANGED, onSyncChanged) openAndQuery() } diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/service/elevation/loader/Dem3TileLoader.java b/aat-lib/src/main/java/ch/bailu/aat_lib/service/elevation/loader/Dem3TileLoader.java index 7fa2a6b78..7ea0ebfa4 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/service/elevation/loader/Dem3TileLoader.java +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/service/elevation/loader/Dem3TileLoader.java @@ -36,7 +36,7 @@ public Dem3TileLoader(AppContext appContext, Timer timer, Dem3Tiles tiles) { this.timer = timer; this.tiles = tiles; this.appContext = appContext; - this.appContext.getBroadcaster().register(onFileDownloaded, AppBroadcaster.FILE_CHANGED_ONDISK); + this.appContext.getBroadcaster().register(AppBroadcaster.FILE_CHANGED_ONDISK, onFileDownloaded); this.sdownload = new SolidDem3EnableDownload(appContext.getStorage()); this.sdownload.register(onPreferencesChanged); diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/service/elevation/updater/ElevationUpdater.java b/aat-lib/src/main/java/ch/bailu/aat_lib/service/elevation/updater/ElevationUpdater.java index 84ccffe40..d6527e188 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/service/elevation/updater/ElevationUpdater.java +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/service/elevation/updater/ElevationUpdater.java @@ -31,10 +31,9 @@ public ElevationUpdater(AppContext appContext, Dem3Loader d, Dem3Tiles t) { tiles = t; loader = d; - this.appContext.getBroadcaster().register(onFileChanged, AppBroadcaster.FILE_CHANGED_INCACHE); + this.appContext.getBroadcaster().register(AppBroadcaster.FILE_CHANGED_INCACHE, onFileChanged); } - private final BroadcastReceiver onFileChanged = new BroadcastReceiver() { @Override public void onReceive(@NotNull String... args) { diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/service/tracker/TrackerService.java b/aat-lib/src/main/java/ch/bailu/aat_lib/service/tracker/TrackerService.java index e00e82a6d..e0ea497f0 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/service/tracker/TrackerService.java +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/service/tracker/TrackerService.java @@ -20,7 +20,7 @@ public final class TrackerService extends VirtualService implements WithStatusTe public TrackerService(SolidDataDirectory sdirectory, StatusIconInterface statusIconInterface, Broadcaster broadcaster, ServicesInterface servicesInterface) { this.internal = new TrackerInternals(sdirectory,statusIconInterface, broadcaster, servicesInterface); this.broadcaster = broadcaster; - this.broadcaster.register(onLocation, AppBroadcaster.LOCATION_CHANGED); + this.broadcaster.register(AppBroadcaster.LOCATION_CHANGED, onLocation); } From 03c9d624b2d3ac2942cc88537dce5252d1150e98 Mon Sep 17 00:00:00 2001 From: bailuk Date: Tue, 9 Apr 2024 20:40:34 +0200 Subject: [PATCH 04/10] Add file count, file index and missing attributes to file list --- .../ch/bailu/aat_gtk/view/list/FileList.kt | 24 ++++++++++++------- .../bailu/aat_gtk/view/list/FileListItem.kt | 6 ++--- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt index 05580b414..d3d147acc 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt @@ -49,11 +49,11 @@ class FileList(app: Application, AverageSpeedDescription(appContext.storage), TimeDescription()) - val vbox = Box(Orientation.VERTICAL, Layout.margin).apply { margin(Layout.margin) } + private val fileCountLabel = Label(Str.NULL) private val fileNameLabel = Label(Str.NULL) private val trackFrameButton = Button().apply { iconName = Icons.zoomFitBestSymbolic @@ -77,17 +77,22 @@ class FileList(app: Application, private val iteratorSimple = IteratorSimple(appContext).apply { setOnCursorChangedListener { - if (listIndex.size != count) { - if (!listIsDirty) { - listIsDirty = true - updateLater() - } + updateList() + } + } + + private fun updateList() { + fileCountLabel.setLabel(iteratorSimple.count.toString()) + if (listIndex.size != iteratorSimple.count) { + if (!listIsDirty) { + listIsDirty = true + updateLater() } } } private fun updateLater() { - updateTimer.kick(1000) { + updateTimer.kick(500) { if (listIsDirty) { listIsDirty = false val count = iteratorSimple.count @@ -131,9 +136,9 @@ class FileList(app: Application, } init { - select(-1) try { - listIndex.size = iteratorSimple.count + select(-1) + updateList() val factory = SignalListItemFactory().apply { onSetup { @@ -181,6 +186,7 @@ class FileList(app: Application, appContext.broadcaster.register(AppBroadcaster.DB_SYNC_CHANGED) { start() } appContext.broadcaster.register(AppBroadcaster.DBSYNC_START) { start() } }) + append(fileCountLabel) }) vbox.append(Box(Orientation.HORIZONTAL, Layout.margin).apply { diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileListItem.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileListItem.kt index 394276dbb..a1092e1c0 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileListItem.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileListItem.kt @@ -44,14 +44,14 @@ class FileListItem(listItem: ListItem, private val descriptions: Array d.onContentUpdated(InfoID.ALL, info) if (i == 0) { title = "${d.getValueAsString()}" - } else { - infoText = d.getValueAsString() + } else { + infoText = "$infoText - ${d.getValueAsString()}" } } From 0fc879d47aa6338f9f33ecf82b1024af42089d29 Mon Sep 17 00:00:00 2001 From: bailuk Date: Wed, 10 Apr 2024 09:55:34 +0200 Subject: [PATCH 05/10] Rename .java to .kt --- .../{MapPreviewInterface.java => MapPreviewInterface.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/{MapPreviewInterface.java => MapPreviewInterface.kt} (100%) diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/MapPreviewInterface.java b/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/MapPreviewInterface.kt similarity index 100% rename from aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/MapPreviewInterface.java rename to aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/MapPreviewInterface.kt From 24529d0baf7e8fc89b66e0a0504abc16572def11 Mon Sep 17 00:00:00 2001 From: bailuk Date: Wed, 10 Apr 2024 09:55:34 +0200 Subject: [PATCH 06/10] GTK: Port preview generator --- .../aat/map/mapsforge/MapsForgePreview.kt | 38 ++-- .../bailu/aat/map/mapsforge/MapsForgeView.kt | 2 +- .../aat/map/mapsforge/MapsForgeViewBase.kt | 25 +-- .../aat/map/mapsforge/MapsForgeViewStatic.kt | 2 +- .../ch/bailu/aat_gtk/app/GtkAppContext.kt | 3 +- .../preferences/PreferencesLoadDefaults.kt | 2 +- .../aat_gtk/view/map/GtkCustomMapView.kt | 28 ++- .../view/map/preview/MapsForgePreview.kt | 163 ++++++++++++++++++ .../aat_gtk/view/toplevel/CockpitPage.kt | 2 +- .../java/ch/bailu/aat_lib/map/NodeBitmap.kt | 2 +- .../directory/DirectorySynchronizer.kt | 2 +- .../service/directory/MapPreviewInterface.kt | 12 +- 12 files changed, 228 insertions(+), 53 deletions(-) create mode 100644 aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/map/preview/MapsForgePreview.kt diff --git a/aat-android/src/main/kotlin/ch/bailu/aat/map/mapsforge/MapsForgePreview.kt b/aat-android/src/main/kotlin/ch/bailu/aat/map/mapsforge/MapsForgePreview.kt index 740397301..27a092481 100644 --- a/aat-android/src/main/kotlin/ch/bailu/aat/map/mapsforge/MapsForgePreview.kt +++ b/aat-android/src/main/kotlin/ch/bailu/aat/map/mapsforge/MapsForgePreview.kt @@ -1,18 +1,16 @@ package ch.bailu.aat.map.mapsforge -import android.annotation.SuppressLint import android.content.Context -import android.graphics.Color -import ch.bailu.aat.dispatcher.AndroidBroadcaster import ch.bailu.aat.map.MapDensity -import ch.bailu.aat.preferences.Storage -import ch.bailu.aat.util.graphic.AndroidSyncTileBitmap import ch.bailu.aat_lib.app.AppContext +import ch.bailu.aat_lib.app.AppGraphicFactory import ch.bailu.aat_lib.dispatcher.AppBroadcaster import ch.bailu.aat_lib.gpx.GpxInformation import ch.bailu.aat_lib.gpx.InfoID +import ch.bailu.aat_lib.lib.color.ColorInterface import ch.bailu.aat_lib.logger.AppLog import ch.bailu.aat_lib.map.layer.gpx.GpxDynLayer +import ch.bailu.aat_lib.map.tile.MapTileInterface import ch.bailu.aat_lib.map.tile.MapsForgeTileLayer import ch.bailu.aat_lib.map.tile.TileProvider import ch.bailu.aat_lib.map.tile.source.CacheOnlySource @@ -28,13 +26,12 @@ import org.mapsforge.core.model.BoundingBox import org.mapsforge.core.model.Dimension import org.mapsforge.core.model.MapPosition import org.mapsforge.core.model.Point -import org.mapsforge.map.android.graphics.AndroidGraphicFactory import org.mapsforge.map.util.LayerUtil import org.mapsforge.map.util.MapPositionUtil import org.mapsforge.map.view.FrameBuffer import org.mapsforge.map.view.FrameBufferHA3 -class MapsForgePreview(context: Context, appContext: AppContext, info: GpxInformation, out: Foc): +class MapsForgePreview(context: Context, private val appContext: AppContext, info: GpxInformation, out: Foc): MapsForgeViewBase(appContext, context, MapsForgePreview::class.java.simpleName, MapDensity()), MapPreviewInterface { @@ -51,9 +48,9 @@ class MapsForgePreview(context: Context, appContext: AppContext, info: GpxInform provider = TileProvider(appContext, getSource(SolidRenderTheme(appContext.mapDirectory, appContext))) val tileLayer = MapsForgeTileLayer(appContext.services, provider, appContext.tilePainter) - add(tileLayer, tileLayer) + add(tileLayer) - val gpxLayer = GpxDynLayer(Storage(getContext()), getMContext(), appContext.services) + val gpxLayer = GpxDynLayer(appContext.storage, getMContext(), appContext.services) add(gpxLayer) attachLayers() gpxLayer.onContentUpdated(InfoID.FILE_VIEW, info) @@ -88,7 +85,7 @@ class MapsForgePreview(context: Context, appContext: AppContext, info: GpxInform return object : FrameBufferHA3( model.frameBufferModel, model.displayModel, - AndroidGraphicFactory.INSTANCE + AppGraphicFactory.instance() ) { override fun getDrawingBitmap(): Bitmap? { return null @@ -103,14 +100,13 @@ class MapsForgePreview(context: Context, appContext: AppContext, info: GpxInform * End of "prevent MapView from drawing" hack */ - private fun generateBitmap(): AndroidSyncTileBitmap { - val bitmap = AndroidSyncTileBitmap() + private fun generateBitmap(): MapTileInterface { + val bitmap = appContext.createMapTile() bitmap.set(BITMAP_SIZE, false) - if (bitmap.androidBitmap != null) { - val c = bitmap.androidCanvas - val canvas = AndroidGraphicFactory.createGraphicContext(c) - bitmap.androidBitmap?.eraseColor(Color.BLACK) + if (bitmap.isLoaded()) { + val canvas = bitmap.getCanvas() + bitmap.getBitmap()?.setBackgroundColor(ColorInterface.BLACK) for (layer in layerManager.layers) { layer.draw(bounding, mapPosition.zoomLevel, canvas, tlPoint) } @@ -118,21 +114,19 @@ class MapsForgePreview(context: Context, appContext: AppContext, info: GpxInform return bitmap } - @SuppressLint("WrongThread") override fun generateBitmapFile() { val bitmap = generateBitmap() try { imageFile.openW()?.use { out -> - bitmap.androidBitmap?.compress(android.graphics.Bitmap.CompressFormat.PNG, 90, out) - AndroidBroadcaster.broadcast( - context, + bitmap.getBitmap()?.compress(out) + appContext.broadcaster.broadcast( AppBroadcaster.FILE_CHANGED_ONDISK, - imageFile, + imageFile.path, javaClass.name ) } } catch (e: Exception) { - AppLog.e(context, e) + AppLog.e(this, e) } bitmap.free() } diff --git a/aat-android/src/main/kotlin/ch/bailu/aat/map/mapsforge/MapsForgeView.kt b/aat-android/src/main/kotlin/ch/bailu/aat/map/mapsforge/MapsForgeView.kt index da6d72875..093dbe652 100644 --- a/aat-android/src/main/kotlin/ch/bailu/aat/map/mapsforge/MapsForgeView.kt +++ b/aat-android/src/main/kotlin/ch/bailu/aat/map/mapsforge/MapsForgeView.kt @@ -23,7 +23,7 @@ class MapsForgeView( private val foreground = MapsForgeForeground(appContext, this, getMContext(), MapDensity(context), layers) init { - add(stack, stack) + add(stack) add(pos) isClickable = true diff --git a/aat-android/src/main/kotlin/ch/bailu/aat/map/mapsforge/MapsForgeViewBase.kt b/aat-android/src/main/kotlin/ch/bailu/aat/map/mapsforge/MapsForgeViewBase.kt index 58abea07f..7f99b28af 100644 --- a/aat-android/src/main/kotlin/ch/bailu/aat/map/mapsforge/MapsForgeViewBase.kt +++ b/aat-android/src/main/kotlin/ch/bailu/aat/map/mapsforge/MapsForgeViewBase.kt @@ -33,8 +33,8 @@ open class MapsForgeViewBase( private val mcontext: MapsForgeContext private val services: ServicesInterface private val storage: Storage - var areServicesUp = false - var isVisible = false + private var areServicesUp = false + private var isVisible = false val layers = ArrayList(10) private var areLayersAttached = false @@ -43,7 +43,7 @@ open class MapsForgeViewBase( model.displayModel.setFixedTileSize(d.tileSize) services = appContext.services mcontext = MapsForgeContext(appContext, this, key, d) - add(mcontext, mcontext) + add(mcontext) storage = Storage(context) mapScaleBar.isVisible = false setBuiltInZoomControls(false) @@ -54,8 +54,14 @@ open class MapsForgeViewBase( } override fun add(layer: MapLayerInterface) { - val wrapper = LayerWrapper(services, mcontext, layer) - add(wrapper, layer) + val wrapper: Layer = if (layer is Layer) { + layer + } else { + LayerWrapper(services, mcontext, layer) + } + addLayer(wrapper) + layers.add(layer) + if (areLayersAttached) layer.onAttached() } override fun getMContext(): MapContext { @@ -71,12 +77,6 @@ open class MapsForgeViewBase( return model.mapViewPosition } - fun add(mfLayer: Layer, layer: MapLayerInterface) { - addLayer(mfLayer) - layers.add(layer) - if (areLayersAttached) layer.onAttached() - } - override fun zoomOut() { model.mapViewPosition.zoomOut() } @@ -174,7 +174,8 @@ open class MapsForgeViewBase( /* FIXME: this is a workaround to a bug: * Sometimes the LayerManager thread is still running after calling destroyAll(). * This happens when MapView was never attached to window. - * Same problem with the Animator thread of MapViewPosition. */layerManager.finish() + * Same problem with the Animator thread of MapViewPosition. */ + layerManager.finish() getMapViewPosition().destroy() } diff --git a/aat-android/src/main/kotlin/ch/bailu/aat/map/mapsforge/MapsForgeViewStatic.kt b/aat-android/src/main/kotlin/ch/bailu/aat/map/mapsforge/MapsForgeViewStatic.kt index df39964e5..4cbc95408 100644 --- a/aat-android/src/main/kotlin/ch/bailu/aat/map/mapsforge/MapsForgeViewStatic.kt +++ b/aat-android/src/main/kotlin/ch/bailu/aat/map/mapsforge/MapsForgeViewStatic.kt @@ -12,7 +12,7 @@ class MapsForgeViewStatic(context: Context, appContext: AppContext) : MapsForgeV ) { init { val tiles: MapsForgeTileLayerStackConfigured = BackgroundOnly(this, appContext) - add(tiles, tiles) + add(tiles) isClickable = false } } diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/app/GtkAppContext.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/app/GtkAppContext.kt index 84d9e6189..f7c4cefb1 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/app/GtkAppContext.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/app/GtkAppContext.kt @@ -12,6 +12,7 @@ import ch.bailu.aat_gtk.solid.GtkStorage import ch.bailu.aat_gtk.solid.SolidGtkDefaultDirectory import ch.bailu.aat_gtk.util.GtkTimer import ch.bailu.aat_gtk.util.sql.H2DbConnection +import ch.bailu.aat_gtk.view.map.preview.MapsForgePreview import ch.bailu.aat_lib.app.AppContext import ch.bailu.aat_lib.gpx.GpxInformation import ch.bailu.aat_lib.map.tile.MapTileInterface @@ -58,7 +59,7 @@ object GtkAppContext: AppContext { } override fun createMapPreview(info: GpxInformation, previewImageFile: Foc): MapPreviewInterface { - return Preview() + return MapsForgePreview(this, info, previewImageFile) } override fun createMapTile(): MapTileInterface { diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/preferences/PreferencesLoadDefaults.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/preferences/PreferencesLoadDefaults.kt index 8998a1fef..0ac3234e6 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/preferences/PreferencesLoadDefaults.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/preferences/PreferencesLoadDefaults.kt @@ -22,6 +22,6 @@ class PreferenceLoadDefaults(context: AppContext) { val solidRenderTheme = SolidRenderTheme(context.mapDirectory, context) SolidMapTileStack(solidRenderTheme).setDefaults() SolidWeight(context.storage).setDefaults() - SolidPositionLock(context.storage, GtkCustomMapView.KEY).setDefaults() + SolidPositionLock(context.storage, GtkCustomMapView.DEFAULT_KEY).setDefaults() } } diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/map/GtkCustomMapView.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/map/GtkCustomMapView.kt index 8a59419c4..ead03f2ec 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/map/GtkCustomMapView.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/map/GtkCustomMapView.kt @@ -5,6 +5,7 @@ import ch.bailu.aat_gtk.app.GtkAppDensity import ch.bailu.aat_lib.app.AppContext import ch.bailu.aat_lib.coordinates.BoundingBoxE6 import ch.bailu.aat_lib.dispatcher.DispatcherInterface +import ch.bailu.aat_lib.dispatcher.LifeCycleInterface import ch.bailu.aat_lib.map.Attachable import ch.bailu.aat_lib.map.MapContext import ch.bailu.aat_lib.map.MapViewInterface @@ -31,19 +32,20 @@ import org.mapsforge.map.layer.Layer import org.mapsforge.map.model.IMapViewPosition import org.mapsforge.map.model.common.Observer -class GtkCustomMapView ( +open class GtkCustomMapView ( private val appContext: AppContext, - dispatcher: DispatcherInterface -) : MapView(), MapViewInterface, OnPreferencesChanged, Attachable { + dispatcher: DispatcherInterface, + key: String = DEFAULT_KEY +) : MapView(), MapViewInterface, OnPreferencesChanged, Attachable, LifeCycleInterface { companion object { - const val KEY = "MAP_VIEW" + const val DEFAULT_KEY = "MAP_VIEW" private const val SHOW_DEBUG_LAYERS = false } private val density = GtkAppDensity() - private val backgroundContext: GtkMapContext = GtkMapContext(this, KEY, NodeBitmap.get(density, appContext), density) + private val backgroundContext: GtkMapContext = GtkMapContext(this, key, NodeBitmap.get(density, appContext), density) private val foregroundContext: GtkMapContextForeground private val layers = ArrayList(10) @@ -188,4 +190,20 @@ class GtkCustomMapView ( layer.onPreferencesChanged(storage, key) } } + + override fun onResumeWithService() {} + + override fun onPauseWithService() {} + + override fun onDestroy() { + onDetached() + destroyAll() + + /* FIXME: this is a workaround to a bug: + * Sometimes the LayerManager thread is still running after calling destroyAll(). + * This happens when MapView was never attached to window. + * Same problem with the Animator thread of MapViewPosition. */ + layerManager.finish() + getMapViewPosition().destroy() + } } diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/map/preview/MapsForgePreview.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/map/preview/MapsForgePreview.kt new file mode 100644 index 000000000..03130395b --- /dev/null +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/map/preview/MapsForgePreview.kt @@ -0,0 +1,163 @@ +package ch.bailu.aat_gtk.view.map.preview + +import ch.bailu.aat_gtk.view.map.GtkCustomMapView +import ch.bailu.aat_lib.app.AppContext +import ch.bailu.aat_lib.app.AppGraphicFactory +import ch.bailu.aat_lib.dispatcher.AppBroadcaster +import ch.bailu.aat_lib.dispatcher.Dispatcher +import ch.bailu.aat_lib.gpx.GpxInformation +import ch.bailu.aat_lib.gpx.InfoID +import ch.bailu.aat_lib.lib.color.ColorInterface +import ch.bailu.aat_lib.logger.AppLog +import ch.bailu.aat_lib.map.layer.gpx.GpxDynLayer +import ch.bailu.aat_lib.map.tile.MapTileInterface +import ch.bailu.aat_lib.map.tile.MapsForgeTileLayer +import ch.bailu.aat_lib.map.tile.TileProvider +import ch.bailu.aat_lib.map.tile.source.CacheOnlySource +import ch.bailu.aat_lib.map.tile.source.MapsForgeSource +import ch.bailu.aat_lib.map.tile.source.Source +import ch.bailu.aat_lib.preferences.map.SolidMapTileStack +import ch.bailu.aat_lib.preferences.map.SolidRenderTheme +import ch.bailu.aat_lib.service.cache.DownloadSource +import ch.bailu.aat_lib.service.directory.MapPreviewInterface +import ch.bailu.foc.Foc +import org.mapsforge.core.graphics.Bitmap +import org.mapsforge.core.model.BoundingBox +import org.mapsforge.core.model.Dimension +import org.mapsforge.core.model.MapPosition +import org.mapsforge.core.model.Point +import org.mapsforge.map.util.LayerUtil +import org.mapsforge.map.util.MapPositionUtil +import org.mapsforge.map.view.FrameBuffer +import org.mapsforge.map.view.FrameBufferHA3 + +class MapsForgePreview(private val appContext: AppContext, + info: GpxInformation, + out: Foc +) : GtkCustomMapView(appContext, Dispatcher(), MapsForgePreview::class.java.simpleName), MapPreviewInterface { + private val imageFile: Foc + private val provider: TileProvider + private val mapPosition: MapPosition + private val bounding: BoundingBox + private val tlPoint: Point + + init { + + // Interface: Resize models + onResize(BITMAP_SIZE, BITMAP_SIZE) + + model.mapViewDimension.dimension = DIM + imageFile = out + provider = TileProvider(appContext, getSource(SolidRenderTheme(appContext.mapDirectory, appContext))) + + val tileLayer = MapsForgeTileLayer(appContext.services, provider, appContext.tilePainter) + add(tileLayer) + + val gpxLayer = GpxDynLayer(appContext.storage, getMContext(), appContext.services) + add(gpxLayer) + // Interface + // attachLayers() + gpxLayer.onContentUpdated(InfoID.FILE_VIEW, info) + frameBounding(info.gpxList.getDelta().getBoundingBox()) + mapPosition = model.mapViewPosition.mapPosition + + val tileSize = model.displayModel.tileSize + bounding = MapPositionUtil.getBoundingBox(mapPosition, DIM, tileSize) + tlPoint = MapPositionUtil.getTopLeftPoint(mapPosition, DIM, tileSize) + preLoadTiles() + } + + private fun preLoadTiles() { + val tilePositions = LayerUtil.getTilePositions( + bounding, + mapPosition.zoomLevel, tlPoint, + model.displayModel.tileSize + ) + provider.onAttached() + provider.preload(tilePositions) + } + + /** + * + * Begin of "prevent MapView from drawing" hack + * FIXME: + * This hack prevents the map view from calling the layers draw() function. + * The correct implementation would be to port the preview generator away from the MapView and + * just use the MapViews model. + */ + override fun getFrameBuffer(): FrameBuffer { + return object : FrameBufferHA3( + model.frameBufferModel, + model.displayModel, + AppGraphicFactory.instance() + ) { + override fun getDrawingBitmap(): Bitmap? { + return null + } + } + } + + override fun repaint() {} + override fun requestRedraw() {} + + /** + * End of "prevent MapView from drawing" hack + */ + + private fun generateBitmap(): MapTileInterface { + val bitmap = appContext.createMapTile() + + bitmap.set(BITMAP_SIZE, false) + if (bitmap.isLoaded()) { + val canvas = bitmap.getCanvas() + bitmap.getBitmap()?.setBackgroundColor(ColorInterface.BLACK) + for (layer in layerManager.layers) { + layer.draw(bounding, mapPosition.zoomLevel, canvas, tlPoint) + } + } + return bitmap + } + + override fun generateBitmapFile() { + val bitmap = generateBitmap() + try { + imageFile.openW()?.use { out -> + bitmap.getBitmap()?.compress(out) + appContext.broadcaster.broadcast( + AppBroadcaster.FILE_CHANGED_ONDISK, + imageFile.path, + javaClass.name + ) + } + } catch (e: Exception) { + AppLog.e(this, e) + } + bitmap.free() + } + + override fun isReady(): Boolean { + return provider.isReadyAndLoaded + } + + override fun onDestroy() { + provider.onDetached() + super.onDestroy() + } + + companion object { + private const val BITMAP_SIZE = 128 + private val DIM = Dimension(BITMAP_SIZE, BITMAP_SIZE) + private val MAPNIK: Source = CacheOnlySource(DownloadSource.MAPNIK) + + private fun getSource(stheme: SolidRenderTheme): Source { + val tiles = SolidMapTileStack(stheme) + val enabled = tiles.getEnabledArray() + if (enabled[0]) { + val theme = stheme.getValueAsString() + val mfs = MapsForgeSource(theme) + return CacheOnlySource(mfs) + } + return MAPNIK + } + } +} diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/toplevel/CockpitPage.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/toplevel/CockpitPage.kt index ea5643be7..38b03ec8c 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/toplevel/CockpitPage.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/toplevel/CockpitPage.kt @@ -44,7 +44,7 @@ class CockpitPage(appContext: AppContext, uiController: UiController, dispatcher iconName = Icons.zoomFitBestSymbolic onClicked { uiController.showMap() - SolidPositionLock(appContext.storage, GtkCustomMapView.KEY).value = true + SolidPositionLock(appContext.storage, GtkCustomMapView.DEFAULT_KEY).value = true } }) }) diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/map/NodeBitmap.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/map/NodeBitmap.kt index 134a1aeaa..b1bb50e63 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/map/NodeBitmap.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/map/NodeBitmap.kt @@ -29,7 +29,7 @@ class NodeBitmap private constructor(radius: Int, res: AppDensity, context: AppC private const val STROKE_WIDTH = MapPaint.EDGE_WIDTH_LINE private const val RADIUS = 6 private val nodes = HashMap(10) - operator fun get(res: AppDensity, context: AppContext): NodeBitmap { + fun get(res: AppDensity, context: AppContext): NodeBitmap { val radius = res.toPixelInt(RADIUS.toFloat()) var node = nodes[radius] if (node == null) { diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/DirectorySynchronizer.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/DirectorySynchronizer.kt index f915f96ec..d059dc7e5 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/DirectorySynchronizer.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/DirectorySynchronizer.kt @@ -286,7 +286,7 @@ class DirectorySynchronizer(private val appContext: AppContext, private val dire if (!canContinue || previewGenerator !is MapPreviewInterface) { terminate() - } else if (previewGenerator.isReady) { + } else if (previewGenerator.isReady()) { previewGenerator.generateBitmapFile() appContext.broadcaster.broadcast(AppBroadcaster.DB_SYNC_CHANGED) setState(StateLoadNextGpx()) diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/MapPreviewInterface.kt b/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/MapPreviewInterface.kt index cbc6b8700..ad4a691f1 100644 --- a/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/MapPreviewInterface.kt +++ b/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/MapPreviewInterface.kt @@ -1,9 +1,7 @@ -package ch.bailu.aat_lib.service.directory; +package ch.bailu.aat_lib.service.directory -public interface MapPreviewInterface { - boolean isReady(); - - void generateBitmapFile(); - - void onDestroy(); +interface MapPreviewInterface { + fun isReady(): Boolean + fun generateBitmapFile() + fun onDestroy() } From fb3d3ea5f79995ff86c7f3cc15b2697d4fba6eca Mon Sep 17 00:00:00 2001 From: bailuk Date: Wed, 10 Apr 2024 10:05:05 +0200 Subject: [PATCH 07/10] GTK: Add reload preview menu item to track list view --- .../src/main/kotlin/ch/bailu/aat_gtk/config/Strings.kt | 1 + .../main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt | 1 + .../bailu/aat_gtk/view/menu/provider/FileContextMenu.kt | 8 +++++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/config/Strings.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/config/Strings.kt index 4d6527186..d087c7818 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/config/Strings.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/config/Strings.kt @@ -20,6 +20,7 @@ object Strings { const val actionFileMock = "app.fileMock" const val actionFileRename = "app.fileRename" const val actionFileDelete = "app.fileDelete" + const val actionFileReload = "app.fileReload" // Ids diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt index d3d147acc..656f16335 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt @@ -109,6 +109,7 @@ class FileList(app: Application, private val items = HashMap() private val overlayMenu = FileContextMenu( + appContext, SolidCustomOverlayList( appContext.storage, appContext diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/menu/provider/FileContextMenu.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/menu/provider/FileContextMenu.kt index 93a74c822..d1e1aecd7 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/menu/provider/FileContextMenu.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/menu/provider/FileContextMenu.kt @@ -4,6 +4,7 @@ import ch.bailu.aat_gtk.app.GtkAppContext import ch.bailu.aat_gtk.config.Strings import ch.bailu.aat_gtk.lib.extensions.ellipsizeStart import ch.bailu.aat_gtk.view.menu.MenuHelper +import ch.bailu.aat_lib.app.AppContext import ch.bailu.aat_lib.preferences.location.SolidMockLocationFile import ch.bailu.aat_lib.preferences.map.SolidCustomOverlayList import ch.bailu.aat_lib.resources.Res @@ -22,7 +23,7 @@ import ch.bailu.gtk.gtk.ListBox import ch.bailu.gtk.gtk.Orientation import ch.bailu.gtk.type.Str -class FileContextMenu(private val solid: SolidCustomOverlayList, private val solidMock: SolidMockLocationFile): MenuProvider { +class FileContextMenu(private val appContext: AppContext, private val solid: SolidCustomOverlayList, private val solidMock: SolidMockLocationFile): MenuProvider { override fun createMenu(): Menu { return Menu().apply { @@ -35,6 +36,7 @@ class FileContextMenu(private val solid: SolidCustomOverlayList, private val sol append(Res.str().file_mock(), Strings.actionFileMock) append(Res.str().file_rename(), Strings.actionFileRename) append(Res.str().file_delete(), Strings.actionFileDelete) + append(Res.str().file_reload(), Strings.actionFileReload) }) } } @@ -59,6 +61,10 @@ class FileContextMenu(private val solid: SolidCustomOverlayList, private val sol MenuHelper.setAction(app, Strings.actionFileDelete) { delete(app) } + + MenuHelper.setAction(app, Strings.actionFileReload) { + FileAction.reloadPreview(appContext, file) + } } private fun delete(app: Application) { From dd6b7d5fd36c1b451322ee222b55c35524c23ccb Mon Sep 17 00:00:00 2001 From: bailuk Date: Wed, 10 Apr 2024 12:28:36 +0200 Subject: [PATCH 08/10] Rename .java to .kt --- .../cache/icons/{ObjImageAbstract.java => ObjImageAbstract.kt} | 0 .../service/directory/{SummaryConfig.java => SummaryConfig.kt} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename aat-lib/src/main/java/ch/bailu/aat_lib/service/cache/icons/{ObjImageAbstract.java => ObjImageAbstract.kt} (100%) rename aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/{SummaryConfig.java => SummaryConfig.kt} (100%) diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/service/cache/icons/ObjImageAbstract.java b/aat-lib/src/main/java/ch/bailu/aat_lib/service/cache/icons/ObjImageAbstract.kt similarity index 100% rename from aat-lib/src/main/java/ch/bailu/aat_lib/service/cache/icons/ObjImageAbstract.java rename to aat-lib/src/main/java/ch/bailu/aat_lib/service/cache/icons/ObjImageAbstract.kt diff --git a/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/SummaryConfig.java b/aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/SummaryConfig.kt similarity index 100% rename from aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/SummaryConfig.java rename to aat-lib/src/main/java/ch/bailu/aat_lib/service/directory/SummaryConfig.kt From cf9db2182a9b8725ba93bae3167711d4311b0f0c Mon Sep 17 00:00:00 2001 From: bailuk Date: Wed, 10 Apr 2024 12:28:36 +0200 Subject: [PATCH 09/10] GTK: Show preview images in file list view --- .../aat/map/layer/FileControlBarLayer.kt | 7 +- .../ch/bailu/aat/util/graphic/SyncBitmap.kt | 78 ------------ .../bailu/aat/views/image/ImageObjectView.kt | 22 ++-- .../ch/bailu/aat/views/image/PreviewView.kt | 4 +- .../ch/bailu/aat_gtk/view/list/FileList.kt | 2 +- .../bailu/aat_gtk/view/list/FileListItem.kt | 10 +- .../aat_gtk/view/list/PreviewImageView.kt | 119 ++++++++++++++++++ .../view/map/preview/MapsForgePreview.kt | 2 +- .../bailu/aat_lib/service}/cache/ObjBitmap.kt | 29 ++--- .../service/cache/icons/ObjImageAbstract.kt | 13 +- .../service/directory/SummaryConfig.kt | 26 ++-- 11 files changed, 173 insertions(+), 139 deletions(-) delete mode 100644 aat-android/src/main/kotlin/ch/bailu/aat/util/graphic/SyncBitmap.kt create mode 100644 aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/PreviewImageView.kt rename {aat-android/src/main/kotlin/ch/bailu/aat/services => aat-lib/src/main/java/ch/bailu/aat_lib/service}/cache/ObjBitmap.kt (70%) diff --git a/aat-android/src/main/kotlin/ch/bailu/aat/map/layer/FileControlBarLayer.kt b/aat-android/src/main/kotlin/ch/bailu/aat/map/layer/FileControlBarLayer.kt index 9505d0ceb..7f4c94dc5 100644 --- a/aat-android/src/main/kotlin/ch/bailu/aat/map/layer/FileControlBarLayer.kt +++ b/aat-android/src/main/kotlin/ch/bailu/aat/map/layer/FileControlBarLayer.kt @@ -9,8 +9,8 @@ import ch.bailu.aat.preferences.Storage import ch.bailu.aat.util.fs.AndroidFileAction import ch.bailu.aat.util.ui.theme.AppTheme import ch.bailu.aat.util.ui.tooltip.ToolTip -import ch.bailu.aat.views.image.PreviewView import ch.bailu.aat.views.bar.ControlBar +import ch.bailu.aat.views.image.PreviewView import ch.bailu.aat_lib.app.AppContext import ch.bailu.aat_lib.description.AverageSpeedDescription import ch.bailu.aat_lib.description.CaloriesDescription @@ -132,7 +132,10 @@ class FileControlBarLayer( SolidDirectoryQuery(Storage(acontext), FocAndroidFactory(acontext)).position.setValue(index) iterator.moveToPosition(index) selectedFile = iterator.info.file - preview.setFilePath(selectedFile) + val file = selectedFile + if (file is Foc) { + preview.setFilePath(file) + } markupBuilder.appendHeader(iterator.info.file.name) for (d in summaryData) { d.onContentUpdated(iterator.infoID, iterator.info) diff --git a/aat-android/src/main/kotlin/ch/bailu/aat/util/graphic/SyncBitmap.kt b/aat-android/src/main/kotlin/ch/bailu/aat/util/graphic/SyncBitmap.kt deleted file mode 100644 index 0655c17d9..000000000 --- a/aat-android/src/main/kotlin/ch/bailu/aat/util/graphic/SyncBitmap.kt +++ /dev/null @@ -1,78 +0,0 @@ -package ch.bailu.aat.util.graphic - -import android.graphics.BitmapFactory -import ch.bailu.aat_lib.service.cache.Obj -import ch.bailu.foc.Foc -import com.caverock.androidsvg.SVG -import org.mapsforge.core.graphics.Bitmap -import org.mapsforge.map.android.graphics.AndroidBitmap -import org.mapsforge.map.android.graphics.AndroidGraphicFactory -import java.io.BufferedInputStream -import java.io.IOException -import java.io.InputStream - -class SyncBitmap { - var bitmap: Bitmap? = null - private set - - var size = Obj.MIN_SIZE - private set - - @Synchronized - @Throws(IOException::class) - fun set(file: Foc) { - set(load(file)) - } - - @Synchronized - fun set(b: Bitmap?) { - if (bitmap === b) return - free() - bitmap = b - - val bitmap = this.bitmap - size = if (bitmap != null) { - bitmap.width * bitmap.height + 4 - } else { - Obj.MIN_SIZE - } - } - - @Synchronized - fun set(size: Int, transparent: Boolean) { - set(AndroidGraphicFactory.INSTANCE.createTileBitmap(size, transparent)) - } - - @Synchronized - fun set(svg: SVG?, size: Int) { - if (svg is SVG) { - val b = AndroidSyncTileBitmap() - b.set(svg, size) - set(b.getTileBitmap()) - } - } - - @Synchronized - fun free() { - bitmap?.decrementRefCount() - bitmap = null - size = Obj.MIN_SIZE - } - - companion object { - @Throws(IOException::class) - private fun load(file: Foc): Bitmap { - val bitmap: android.graphics.Bitmap? - - var inputStream: InputStream? = null - try { - inputStream = BufferedInputStream(file.openR()) - bitmap = BitmapFactory.decodeStream(inputStream) - } finally { - Foc.close(inputStream) - } - if (bitmap == null) throw IOException(inputStream.toString()) - return AndroidBitmap(bitmap) - } - } -} diff --git a/aat-android/src/main/kotlin/ch/bailu/aat/views/image/ImageObjectView.kt b/aat-android/src/main/kotlin/ch/bailu/aat/views/image/ImageObjectView.kt index 188348bdc..041e680b3 100644 --- a/aat-android/src/main/kotlin/ch/bailu/aat/views/image/ImageObjectView.kt +++ b/aat-android/src/main/kotlin/ch/bailu/aat/views/image/ImageObjectView.kt @@ -7,10 +7,10 @@ import android.widget.ImageView import ch.bailu.aat.dispatcher.AndroidBroadcaster import ch.bailu.aat.map.To.androidBitmap import ch.bailu.aat.services.ServiceContext -import ch.bailu.aat.services.cache.ObjBitmap import ch.bailu.aat.util.AppIntent import ch.bailu.aat_lib.dispatcher.AppBroadcaster import ch.bailu.aat_lib.service.cache.Obj +import ch.bailu.aat_lib.service.cache.ObjNull import ch.bailu.aat_lib.service.cache.icons.ObjImageAbstract open class ImageObjectView( @@ -20,7 +20,7 @@ open class ImageObjectView( scontext.getContext() ) { private var isAttached = false - private var imageHandle: ObjImageAbstract = ObjBitmap.NULL + private var handle = ObjNull.NULL private var idToLoad: String? = null private var factoryToLoad: Obj.Factory? = null fun setImageObject() { @@ -55,22 +55,22 @@ open class ImageObjectView( } private fun loadImage(id: String, factory: Obj.Factory?): Boolean { - val r = booleanArrayOf(false) + var result = false scontext.insideContext { val h = scontext.cacheService.getObject(id, factory) if (h is ObjImageAbstract) { - imageHandle = h - r[0] = true + handle = h + result = true } else { h.free() } } - return r[0] + return result } private fun freeImageHandle() { - imageHandle.free() - imageHandle = ObjBitmap.NULL + handle.free() + handle = ObjNull.NULL } public override fun onAttachedToWindow() { @@ -92,16 +92,18 @@ open class ImageObjectView( } private fun displayImage() { + val imageHandle = handle + if (imageHandle.hasException()) { resetImage() - } else if (imageHandle.isReadyAndLoaded) { + } else if (imageHandle is ObjImageAbstract && imageHandle.isReadyAndLoaded) { setImageBitmap(androidBitmap(imageHandle.bitmap)) } } private val onFileChanged: BroadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { - val file = imageHandle.toString() + val file = handle.toString() if (AppIntent.hasFile(intent, file)) { displayImage() } diff --git a/aat-android/src/main/kotlin/ch/bailu/aat/views/image/PreviewView.kt b/aat-android/src/main/kotlin/ch/bailu/aat/views/image/PreviewView.kt index c0032b5a9..86927d959 100644 --- a/aat-android/src/main/kotlin/ch/bailu/aat/views/image/PreviewView.kt +++ b/aat-android/src/main/kotlin/ch/bailu/aat/views/image/PreviewView.kt @@ -2,10 +2,10 @@ package ch.bailu.aat.views.image import ch.bailu.aat.R import ch.bailu.aat.services.ServiceContext -import ch.bailu.aat.services.cache.ObjBitmap import ch.bailu.aat.util.ui.tooltip.ToolTip.set import ch.bailu.aat_lib.dispatcher.OnContentUpdatedInterface import ch.bailu.aat_lib.gpx.GpxInformation +import ch.bailu.aat_lib.service.cache.ObjBitmap import ch.bailu.aat_lib.service.directory.SummaryConfig import ch.bailu.foc.Foc @@ -14,7 +14,7 @@ class PreviewView(sc: ServiceContext, private val summaryConfig: SummaryConfig) set(this, R.string.tt_menu_file) } - fun setFilePath(fileID: Foc?) { + fun setFilePath(fileID: Foc) { val file = summaryConfig.getPreviewFile(fileID) setPreviewPath(file) } diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt index 656f16335..c5af37b06 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileList.kt @@ -145,7 +145,7 @@ class FileList(app: Application, onSetup { val item = ListItem(it.cast()) - items[item] = FileListItem(item, descriptions) + items[item] = FileListItem(appContext, item, descriptions) logItems.log(items.size.toLong()) } diff --git a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileListItem.kt b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileListItem.kt index a1092e1c0..7b9ee7a1b 100644 --- a/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileListItem.kt +++ b/aat-gtk/src/main/kotlin/ch/bailu/aat_gtk/view/list/FileListItem.kt @@ -1,6 +1,7 @@ package ch.bailu.aat_gtk.view.list import ch.bailu.aat_gtk.lib.extensions.margin +import ch.bailu.aat_lib.app.AppContext import ch.bailu.aat_lib.description.ContentDescription import ch.bailu.aat_lib.gpx.GpxInformation import ch.bailu.aat_lib.gpx.InfoID @@ -10,8 +11,9 @@ import ch.bailu.gtk.gtk.ListItem import ch.bailu.gtk.gtk.Orientation import ch.bailu.gtk.type.Str -class FileListItem(listItem: ListItem, private val descriptions: Array) { +class FileListItem(appContext: AppContext, listItem: ListItem, private val descriptions: Array) { private val labels = ArrayList