diff --git a/res/menu/context_call.xml b/res/menu/context_call.xml index 59f29a0..a8e05f9 100644 --- a/res/menu/context_call.xml +++ b/res/menu/context_call.xml @@ -1,4 +1,5 @@ + + diff --git a/res/menu/options.xml b/res/menu/options.xml index e8741c6..b24eb55 100644 --- a/res/menu/options.xml +++ b/res/menu/options.xml @@ -1,4 +1,5 @@ + + diff --git a/res/menu/options_activities.xml b/res/menu/options_activities.xml index 86fd4e4..7c243af 100644 --- a/res/menu/options_activities.xml +++ b/res/menu/options_activities.xml @@ -1,4 +1,5 @@ + + diff --git a/res/menu/options_map.xml b/res/menu/options_map.xml index 6d07a98..f6b58af 100644 --- a/res/menu/options_map.xml +++ b/res/menu/options_map.xml @@ -13,8 +13,14 @@ + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index f4c5c57..d811a76 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -109,7 +109,11 @@ Overlays -Satellite +Google: Map +Google: Satellite +OpenStreetMap.org + + %s (Offline) APRS Objects diff --git a/src/GoogleMapAct.scala b/src/GoogleMapAct.scala index 9504587..f1b61ad 100644 --- a/src/GoogleMapAct.scala +++ b/src/GoogleMapAct.scala @@ -6,7 +6,7 @@ import android.app.Activity import android.os.Bundle import android.util.Log import android.view.View -import com.google.android.gms.maps.GoogleMap.{OnCameraMoveListener, OnInfoWindowClickListener} +import com.google.android.gms.maps.GoogleMap.{OnCameraMoveListener, OnInfoWindowClickListener, OnMarkerClickListener} import com.google.android.gms.maps.model.{BitmapDescriptor, BitmapDescriptorFactory, LatLng, Marker, MarkerOptions} import com.google.android.gms.maps.{CameraUpdateFactory, GoogleMap, MapView, OnMapReadyCallback} import com.google.maps.android.ui.IconGenerator @@ -18,6 +18,7 @@ import scala.collection.mutable.ArrayBuffer import scala.collection.JavaConversions._ class GoogleMapAct extends Activity with MapLoaderBase + with OnMarkerClickListener with OnInfoWindowClickListener with OnCameraMoveListener { lazy val loading = findViewById(R.id.loading).asInstanceOf[View] lazy val mapview = findViewById(R.id.mapview).asInstanceOf[MapView] @@ -35,6 +36,10 @@ class GoogleMapAct extends Activity with MapLoaderBase override def onMapReady(googleMap: GoogleMap): Unit = { Log.d(TAG, "Got map!") map = googleMap + setMapMode(MapModes.defaultMapMode(GoogleMapAct.this, prefs)) + //not helpful, off at the top: + //map.setMyLocationEnabled(true) + map.setOnMarkerClickListener(GoogleMapAct.this) map.setOnInfoWindowClickListener(GoogleMapAct.this) map.setOnCameraMoveListener(GoogleMapAct.this) map.getUiSettings().setCompassEnabled(true) @@ -62,6 +67,8 @@ class GoogleMapAct extends Activity with MapLoaderBase setKeepScreenOn() setVolumeControls() mapview.onResume() + if (targetcall != "") + startFollowStation(targetcall) } override def onSaveInstanceState(outState: Bundle): Unit = { @@ -84,6 +91,15 @@ class GoogleMapAct extends Activity with MapLoaderBase mapview.onDestroy() } + override def setMapMode(mm : MapMode) = { + mm match { + case gmm : GoogleMapMode => + map.setMapType(gmm.mapType) + case _ => + super.setMapMode(mm) + } + } + override def onStartLoading() { loading.setVisibility(View.VISIBLE) } @@ -151,12 +167,21 @@ class GoogleMapAct extends Activity with MapLoaderBase .visible(visible_callsigns) .anchor(0.0f, -0.2f) // center text below the icon ) + icon.setTag(sta.call) + label.setTag(sta.call) markers(sta.call) = new MarkerInfo(icon, label, 0) } } } + // OnMarkerClickListener + override def onMarkerClick(marker : Marker): Boolean = { + Log.d(TAG, "marker click: " + marker.getTitle() + " / " + marker.getTag()) + startFollowStation(marker.getTag().toString()) + false + } + // OnInfoWindowClickListener override def onInfoWindowClick(marker: Marker): Unit = { openDetails(marker.getTitle()) diff --git a/src/MapAct.scala b/src/MapAct.scala index fb4df11..2afbe3c 100644 --- a/src/MapAct.scala +++ b/src/MapAct.scala @@ -25,19 +25,16 @@ import org.mapsforge.android.maps.mapgenerator.{MapGeneratorFactory, MapGenerato // to make scala-style iterating over arraylist possible import scala.collection.JavaConversions._ -class MapAct extends MapActivity with UIHelper { - val TAG = "APRSdroid.Map" +class MapAct extends MapActivity with MapMenuHelper { + override val TAG = "APRSdroid.Map" menu_id = R.id.map + lazy val mapview = findViewById(R.id.mapview).asInstanceOf[MapView] lazy val allicons = this.getResources().getDrawable(R.drawable.allicons) lazy val db = StorageDatabase.open(this) lazy val staoverlay = new StationOverlay(allicons, this, db) lazy val loading = findViewById(R.id.loading).asInstanceOf[View] - lazy val targetcall = getTargetCall() - - var showObjects = false - lazy val locReceiver = new LocationReceiver2[ArrayList[Station]](staoverlay.load_stations, staoverlay.replace_stations, staoverlay.cancel_stations) @@ -45,16 +42,11 @@ class MapAct extends MapActivity with UIHelper { super.onCreate(savedInstanceState) setContentView(R.layout.mapview) mapview.setBuiltInZoomControls(true) - - locReceiver.startTask(null) - showObjects = prefs.getShowObjects() - //mapview.setSatellite(prefs.getShowSatellite()) mapview.getOverlays().add(staoverlay) - // listen for new positions - registerReceiver(locReceiver, new IntentFilter(AprsService.UPDATE)) - + startLoading() } + override def onResume() { super.onResume() // only make it default if not tracking @@ -77,7 +69,11 @@ class MapAct extends MapActivity with UIHelper { super.onDestroy() unregisterReceiver(locReceiver) } - //override def isRouteDisplayed() = false + + def startLoading() { + registerReceiver(locReceiver, new IntentFilter(AprsService.UPDATE)) + locReceiver.startTask(null) + } def checkPermissions(): Boolean = { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { @@ -102,7 +98,7 @@ class MapAct extends MapActivity with UIHelper { case _ => super.getActionName(action) } } - override def onAllPermissionsGranted(action: Int): Unit = { + override def onAllPermissionsGranted(action: Int): Unit = { action match { case RELOAD_MAP => reloadMapAndTheme() case _ => super.onAllPermissionsGranted(action) @@ -142,51 +138,6 @@ class MapAct extends MapActivity with UIHelper { mapview.setRenderTheme(themefile) } - override def onCreateOptionsMenu(menu : Menu) : Boolean = { - getMenuInflater().inflate(R.menu.options_map, menu); - if (targetcall != "") - getMenuInflater().inflate(R.menu.context_call, menu); - else { - getMenuInflater().inflate(R.menu.options_activities, menu); - getMenuInflater().inflate(R.menu.options, menu); - } - menu.findItem(R.id.map).setVisible(false) - true - } - - // override this to only call UIHelper on "bare" map - override def onPrepareOptionsMenu(menu : Menu) : Boolean = { - if (targetcall == "") - super.onPrepareOptionsMenu(menu) - else { - menu.findItem(R.id.objects).setChecked(prefs.getShowObjects()) - menu.findItem(R.id.satellite).setChecked(prefs.getShowSatellite()) - true - } - } - - override def onOptionsItemSelected(mi : MenuItem) : Boolean = { - mi.getItemId match { - case R.id.objects => - val newState = prefs.toggleBoolean("show_objects", true) - mi.setChecked(newState) - showObjects = newState - onStartLoading() - locReceiver.startTask(null) - true - case R.id.satellite => - val newState = prefs.toggleBoolean("show_satellite", false) - mi.setChecked(newState) - //mapview.setSatellite(newState) - true - case _ => - if (targetcall != "" && callsignAction(mi.getItemId, targetcall)) - true - else - super.onOptionsItemSelected(mi) - } - } - override def onKeyDown(keyCode : Int, event : KeyEvent) : Boolean = { keyCode match { case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD | @@ -201,13 +152,6 @@ class MapAct extends MapActivity with UIHelper { } } - def getTargetCall() : String = { - val i = getIntent() - if (i != null && i.getDataString() != null) { - i.getDataString() - } else "" - } - def changeZoom(delta : Int) { mapview.getController().setZoom(mapview.getMapPosition().getZoomLevel() + delta) } @@ -226,6 +170,11 @@ class MapAct extends MapActivity with UIHelper { animateToCall() } + override def reloadMap() { + onStartLoading() + locReceiver.startTask(null) + } + override def onStartLoading() { loading.setVisibility(View.VISIBLE) } diff --git a/src/MapLoaderBase.scala b/src/MapLoaderBase.scala index c5227ae..016c726 100644 --- a/src/MapLoaderBase.scala +++ b/src/MapLoaderBase.scala @@ -10,11 +10,8 @@ import android.text.TextUtils import scala.collection.mutable.ArrayBuffer -trait MapLoaderBase extends UIHelper { - val TAG = "APRSdroid.MapBase" - - var showObjects = false - lazy val targetcall = getTargetCall() +trait MapLoaderBase extends MapMenuHelper { + menu_id = R.id.map lazy val db = StorageDatabase.open(this) lazy val locReceiver = new LocationReceiver2[ArrayList[Station]](load_stations, @@ -27,13 +24,6 @@ trait MapLoaderBase extends UIHelper { def onStationUpdate(sl : ArrayList[Station]) - def getTargetCall() : String = { - val i = getIntent() - if (i != null && i.getDataString() != null) { - i.getDataString() - } else "" - } - def startLoading() { locReceiver.startTask(null) registerReceiver(locReceiver, new IntentFilter(AprsService.UPDATE)) @@ -68,6 +58,11 @@ trait MapLoaderBase extends UIHelper { s } + override def reloadMap() { + onStartLoading() + locReceiver.startTask(null) + } + def load_finished(sl: ArrayList[Station]) : Unit = { onStationUpdate(sl) onStopLoading() diff --git a/src/MapMenuHelper.scala b/src/MapMenuHelper.scala new file mode 100644 index 0000000..c37d4b1 --- /dev/null +++ b/src/MapMenuHelper.scala @@ -0,0 +1,109 @@ +package org.aprsdroid.app + +import android.os.Bundle +import android.util.Log +import android.view.{Menu, MenuItem} + +trait MapMenuHelper extends UIHelper { + val TAG = "APRSdroid.MapMenu" + + var targetcall = "" + var showObjects = false + + override def onCreate(savedInstanceState: Bundle) { + super.onCreate(savedInstanceState) + targetcall = getTargetCall() + showObjects = prefs.getShowObjects() + } + + + abstract override def onCreateOptionsMenu(menu : Menu) : Boolean = { + getMenuInflater().inflate(R.menu.options_map, menu); + getMenuInflater().inflate(R.menu.context_call, menu); + getMenuInflater().inflate(R.menu.options_activities, menu); + getMenuInflater().inflate(R.menu.options, menu); + menu.findItem(R.id.map).setVisible(false) + true + } + abstract override def onPrepareOptionsMenu(menu : Menu) : Boolean = { + super.onPrepareOptionsMenu(menu) + val tracking = (targetcall != "") + Log.d(TAG, "preparing menu for " + targetcall) + menu.findItem(R.id.objects).setChecked(prefs.getShowObjects()) + menu.setGroupVisible(R.id.menu_context_call, tracking) + menu.setGroupVisible(R.id.menu_options_activities, !tracking) + menu.setGroupVisible(R.id.menu_options, !tracking) + val modesmenu = menu.findItem(R.id.overlays).getSubMenu() + val defaultMapMode = MapModes.defaultMapMode(this, prefs) + Log.d(TAG, "default " + defaultMapMode.tag) + for (mode <- MapModes.all_mapmodes) { + val item_found = modesmenu.findItem(mode.menu_id) + val item = if (item_found != null) item_found else + modesmenu.add(R.id.mapmodes, mode.menu_id, 0, mode.title) + Log.d(TAG, "menu item " + item.getTitle + " for " + mode.tag) + item.setCheckable(true) + if (mode == defaultMapMode) + item.setChecked(true) + item.setEnabled(mode.isAvailable(this)) + } + true + } + + def getTargetCall() : String = { + val i = getIntent() + if (i != null && i.getDataString() != null) { + i.getDataString() + } else "" + } + + def startFollowStation(call : String) = { + targetcall = call + setLongTitle(R.string.app_map, targetcall) + invalidateOptionsMenu() + } + + def stopFollowStation() = { + targetcall = "" + setLongTitle(R.string.app_map, null) + invalidateOptionsMenu() + } + + def switchMapActivity(cls : Class[_]) = { + MapModes.startMap(this, prefs, targetcall) + finish() + } + + def setMapMode(mm : MapMode) = { + switchMapActivity(mm.viewClass) + } + + def onMapModeItem(mi : MenuItem, mm : MapMode): Boolean = { + MapModes.setDefault(prefs, mm.tag) + setMapMode(mm) + mi.setChecked(true) + true + } + + abstract override def onOptionsItemSelected(mi : MenuItem) : Boolean = { + val mapmode = MapModes.fromMenuItem(mi) + if (mapmode != null) + return onMapModeItem(mi, mapmode) + mi.getItemId match { + //case R.id.normal | R.id.hybrid | R.id.satellite | R.id.mapsforge => + // onMapModeItem(mi) + case R.id.objects => + val newState = prefs.toggleBoolean("show_objects", true) + mi.setChecked(newState) + showObjects = newState + reloadMap() + true + case _ => + if (targetcall != "" && callsignAction(mi.getItemId, targetcall)) + true + else + super.onOptionsItemSelected(mi) + } + } + + def reloadMap() +}