map: removed app bar, added overlay back button

This commit is contained in:
Thibault Deckers 2021-09-15 10:24:52 +09:00
parent 4c13f665df
commit 9a59bec05a
8 changed files with 78 additions and 53 deletions

View file

@ -791,9 +791,6 @@
"settingsCoordinateFormatTitle": "Coordinate Format", "settingsCoordinateFormatTitle": "Coordinate Format",
"@settingsCoordinateFormatTitle": {}, "@settingsCoordinateFormatTitle": {},
"mapPageTitle": "Map",
"@mapPageTitle": {},
"statsPageTitle": "Stats", "statsPageTitle": "Stats",
"@statsPageTitle": {}, "@statsPageTitle": {},
"statsImage": "{count, plural, =1{image} other{images}}", "statsImage": "{count, plural, =1{image} other{images}}",
@ -858,14 +855,16 @@
"viewerInfoLabelAddress": "Address", "viewerInfoLabelAddress": "Address",
"@viewerInfoLabelAddress": {}, "@viewerInfoLabelAddress": {},
"viewerInfoMapStyleTitle": "Map Style", "mapStyleTitle": "Map Style",
"@viewerInfoMapStyleTitle": {}, "@mapStyleTitle": {},
"viewerInfoMapStyleTooltip": "Select map style", "mapStyleTooltip": "Select map style",
"@viewerInfoMapStyleTooltip": {}, "@mapStyleTooltip": {},
"viewerInfoMapZoomInTooltip": "Zoom in", "mapZoomInTooltip": "Zoom in",
"@viewerInfoMapZoomInTooltip": {}, "@mapZoomInTooltip": {},
"viewerInfoMapZoomOutTooltip": "Zoom out", "mapZoomOutTooltip": "Zoom out",
"@viewerInfoMapZoomOutTooltip": {}, "@mapZoomOutTooltip": {},
"mapPointNorthUpTooltip": "Point north up",
"@mapPointNorthUpTooltip": {},
"mapAttributionOsmHot": "Map data © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors • Tiles by [HOT](https://www.hotosm.org/) • Hosted by [OSM France](https://openstreetmap.fr/)", "mapAttributionOsmHot": "Map data © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors • Tiles by [HOT](https://www.hotosm.org/) • Hosted by [OSM France](https://openstreetmap.fr/)",
"@mapAttributionOsmHot": {}, "@mapAttributionOsmHot": {},
"mapAttributionStamen": "Map data © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors • Tiles by [Stamen Design](http://stamen.com), [CC BY 3.0](http://creativecommons.org/licenses/by/3.0)", "mapAttributionStamen": "Map data © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors • Tiles by [Stamen Design](http://stamen.com), [CC BY 3.0](http://creativecommons.org/licenses/by/3.0)",

View file

@ -389,8 +389,6 @@
"settingsCoordinateFormatTile": "좌표 표현", "settingsCoordinateFormatTile": "좌표 표현",
"settingsCoordinateFormatTitle": "좌표 표현", "settingsCoordinateFormatTitle": "좌표 표현",
"mapPageTitle": "지도",
"statsPageTitle": "통계", "statsPageTitle": "통계",
"statsImage": "{count, plural, other{사진}}", "statsImage": "{count, plural, other{사진}}",
"statsVideo": "{count, plural, other{동영상}}", "statsVideo": "{count, plural, other{동영상}}",
@ -419,10 +417,11 @@
"viewerInfoLabelCoordinates": "좌표", "viewerInfoLabelCoordinates": "좌표",
"viewerInfoLabelAddress": "주소", "viewerInfoLabelAddress": "주소",
"viewerInfoMapStyleTitle": "지도 유형", "mapStyleTitle": "지도 유형",
"viewerInfoMapStyleTooltip": "지도 유형 선택", "mapStyleTooltip": "지도 유형 선택",
"viewerInfoMapZoomInTooltip": "확대", "mapZoomInTooltip": "확대",
"viewerInfoMapZoomOutTooltip": "축소", "mapZoomOutTooltip": "축소",
"mapPointNorthUpTooltip": "북쪽을 위로 가리키기",
"mapAttributionOsmHot": "지도 데이터 © [OpenStreetMap](https://www.openstreetmap.org/copyright) 기여자 • 타일 [HOT](https://www.hotosm.org/) • 호스팅 [OSM France](https://openstreetmap.fr/)", "mapAttributionOsmHot": "지도 데이터 © [OpenStreetMap](https://www.openstreetmap.org/copyright) 기여자 • 타일 [HOT](https://www.hotosm.org/) • 호스팅 [OSM France](https://openstreetmap.fr/)",
"mapAttributionStamen": "지도 데이터 © [OpenStreetMap](https://www.openstreetmap.org/copyright) 기여자 • 타일 [Stamen Design](http://stamen.com), [CC BY 3.0](http://creativecommons.org/licenses/by/3.0)", "mapAttributionStamen": "지도 데이터 © [OpenStreetMap](https://www.openstreetmap.org/copyright) 기여자 • 타일 [Stamen Design](http://stamen.com), [CC BY 3.0](http://creativecommons.org/licenses/by/3.0)",

View file

@ -18,6 +18,7 @@ import 'package:flutter/scheduler.dart';
import 'package:latlong2/latlong.dart'; import 'package:latlong2/latlong.dart';
class MapButtonPanel extends StatelessWidget { class MapButtonPanel extends StatelessWidget {
final bool showBackButton;
final ValueNotifier<ZoomedBounds> boundsNotifier; final ValueNotifier<ZoomedBounds> boundsNotifier;
final Future<void> Function(double amount)? zoomBy; final Future<void> Function(double amount)? zoomBy;
final VoidCallback? resetRotation; final VoidCallback? resetRotation;
@ -26,6 +27,7 @@ class MapButtonPanel extends StatelessWidget {
const MapButtonPanel({ const MapButtonPanel({
Key? key, Key? key,
required this.showBackButton,
required this.boundsNotifier, required this.boundsNotifier,
this.zoomBy, this.zoomBy,
this.resetRotation, this.resetRotation,
@ -46,34 +48,51 @@ class MapButtonPanel extends StatelessWidget {
), ),
child: Stack( child: Stack(
children: [ children: [
if (resetRotation != null) Positioned(
Positioned( left: 0,
left: 0, child: Column(
child: ValueListenableBuilder<ZoomedBounds>( mainAxisSize: MainAxisSize.min,
valueListenable: boundsNotifier, children: [
builder: (context, bounds, child) { if (showBackButton)
final degrees = bounds.rotation; MapOverlayButton(
return AnimatedOpacity( icon: const BackButtonIcon(),
opacity: degrees == 0 ? 0 : 1, onPressed: () => Navigator.pop(context),
duration: Durations.viewerOverlayAnimation, tooltip: MaterialLocalizations.of(context).backButtonTooltip,
child: MapOverlayButton( ),
icon: Transform( if (resetRotation != null) ...[
origin: iconSize.center(Offset.zero), const SizedBox(height: padding),
transform: Matrix4.rotationZ(degToRadian(degrees)), ValueListenableBuilder<ZoomedBounds>(
child: CustomPaint( valueListenable: boundsNotifier,
painter: CompassPainter( builder: (context, bounds, child) {
color: iconTheme.color!, final degrees = bounds.rotation;
final opacity = degrees == 0 ? .0 : 1.0;
return IgnorePointer(
ignoring: opacity == 0,
child: AnimatedOpacity(
opacity: opacity,
duration: Durations.viewerOverlayAnimation,
child: MapOverlayButton(
icon: Transform(
origin: iconSize.center(Offset.zero),
transform: Matrix4.rotationZ(degToRadian(degrees)),
child: CustomPaint(
painter: CompassPainter(
color: iconTheme.color!,
),
size: iconSize,
),
),
onPressed: () => resetRotation?.call(),
tooltip: context.l10n.mapPointNorthUpTooltip,
), ),
size: iconSize,
), ),
), );
onPressed: () => resetRotation?.call(), },
tooltip: context.l10n.viewerInfoMapZoomInTooltip, ),
), ],
); ],
},
),
), ),
),
Positioned( Positioned(
right: 0, right: 0,
child: Column( child: Column(
@ -100,7 +119,7 @@ class MapButtonPanel extends StatelessWidget {
return AvesSelectionDialog<EntryMapStyle>( return AvesSelectionDialog<EntryMapStyle>(
initialValue: initialStyle, initialValue: initialStyle,
options: Map.fromEntries(availableStyles.map((v) => MapEntry(v, v.getName(context)))), options: Map.fromEntries(availableStyles.map((v) => MapEntry(v, v.getName(context)))),
title: context.l10n.viewerInfoMapStyleTitle, title: context.l10n.mapStyleTitle,
); );
}, },
); );
@ -110,7 +129,7 @@ class MapButtonPanel extends StatelessWidget {
settings.infoMapStyle = style; settings.infoMapStyle = style;
} }
}, },
tooltip: context.l10n.viewerInfoMapStyleTooltip, tooltip: context.l10n.mapStyleTooltip,
), ),
], ],
), ),
@ -124,13 +143,13 @@ class MapButtonPanel extends StatelessWidget {
MapOverlayButton( MapOverlayButton(
icon: const Icon(AIcons.zoomIn), icon: const Icon(AIcons.zoomIn),
onPressed: zoomBy != null ? () => zoomBy?.call(1) : null, onPressed: zoomBy != null ? () => zoomBy?.call(1) : null,
tooltip: context.l10n.viewerInfoMapZoomInTooltip, tooltip: context.l10n.mapZoomInTooltip,
), ),
const SizedBox(height: padding), const SizedBox(height: padding),
MapOverlayButton( MapOverlayButton(
icon: const Icon(AIcons.zoomOut), icon: const Icon(AIcons.zoomOut),
onPressed: zoomBy != null ? () => zoomBy?.call(-1) : null, onPressed: zoomBy != null ? () => zoomBy?.call(-1) : null,
tooltip: context.l10n.viewerInfoMapZoomOutTooltip, tooltip: context.l10n.mapZoomOutTooltip,
), ),
], ],
), ),

View file

@ -27,7 +27,7 @@ import 'package:provider/provider.dart';
class GeoMap extends StatefulWidget { class GeoMap extends StatefulWidget {
final AvesMapController? controller; final AvesMapController? controller;
final List<AvesEntry> entries; final List<AvesEntry> entries;
final bool interactive; final bool interactive, showBackButton;
final double? mapHeight; final double? mapHeight;
final ValueNotifier<bool> isAnimatingNotifier; final ValueNotifier<bool> isAnimatingNotifier;
final UserZoomChangeCallback? onUserZoomChange; final UserZoomChangeCallback? onUserZoomChange;
@ -41,6 +41,7 @@ class GeoMap extends StatefulWidget {
this.controller, this.controller,
required this.entries, required this.entries,
required this.interactive, required this.interactive,
required this.showBackButton,
this.mapHeight, this.mapHeight,
required this.isAnimatingNotifier, required this.isAnimatingNotifier,
this.onUserZoomChange, this.onUserZoomChange,
@ -65,6 +66,8 @@ class _GeoMapState extends State<GeoMap> {
bool get interactive => widget.interactive; bool get interactive => widget.interactive;
bool get showBackButton => widget.showBackButton;
double? get mapHeight => widget.mapHeight; double? get mapHeight => widget.mapHeight;
@override @override
@ -137,6 +140,7 @@ class _GeoMapState extends State<GeoMap> {
controller: widget.controller, controller: widget.controller,
boundsNotifier: _boundsNotifier, boundsNotifier: _boundsNotifier,
interactive: interactive, interactive: interactive,
showBackButton: showBackButton,
minZoom: 0, minZoom: 0,
maxZoom: 20, maxZoom: 20,
style: mapStyle, style: mapStyle,
@ -149,6 +153,7 @@ class _GeoMapState extends State<GeoMap> {
controller: widget.controller, controller: widget.controller,
boundsNotifier: _boundsNotifier, boundsNotifier: _boundsNotifier,
interactive: interactive, interactive: interactive,
showBackButton: showBackButton,
minZoom: 2, minZoom: 2,
maxZoom: 16, maxZoom: 16,
style: mapStyle, style: mapStyle,
@ -191,6 +196,7 @@ class _GeoMapState extends State<GeoMap> {
interactive: interactive, interactive: interactive,
), ),
MapButtonPanel( MapButtonPanel(
showBackButton: showBackButton,
boundsNotifier: _boundsNotifier, boundsNotifier: _boundsNotifier,
), ),
], ],

View file

@ -18,7 +18,7 @@ import 'package:latlong2/latlong.dart' as ll;
class EntryGoogleMap extends StatefulWidget { class EntryGoogleMap extends StatefulWidget {
final AvesMapController? controller; final AvesMapController? controller;
final ValueNotifier<ZoomedBounds> boundsNotifier; final ValueNotifier<ZoomedBounds> boundsNotifier;
final bool interactive; final bool interactive, showBackButton;
final double? minZoom, maxZoom; final double? minZoom, maxZoom;
final EntryMapStyle style; final EntryMapStyle style;
final MarkerClusterBuilder markerClusterBuilder; final MarkerClusterBuilder markerClusterBuilder;
@ -31,6 +31,7 @@ class EntryGoogleMap extends StatefulWidget {
this.controller, this.controller,
required this.boundsNotifier, required this.boundsNotifier,
required this.interactive, required this.interactive,
required this.showBackButton,
this.minZoom, this.minZoom,
this.maxZoom, this.maxZoom,
required this.style, required this.style,
@ -126,6 +127,7 @@ class _EntryGoogleMapState extends State<EntryGoogleMap> with WidgetsBindingObse
child: _buildMap(), child: _buildMap(),
), ),
MapButtonPanel( MapButtonPanel(
showBackButton: widget.showBackButton,
boundsNotifier: boundsNotifier, boundsNotifier: boundsNotifier,
zoomBy: _zoomBy, zoomBy: _zoomBy,
resetRotation: interactive ? _resetRotation : null, resetRotation: interactive ? _resetRotation : null,

View file

@ -19,7 +19,7 @@ import 'package:latlong2/latlong.dart';
class EntryLeafletMap extends StatefulWidget { class EntryLeafletMap extends StatefulWidget {
final AvesMapController? controller; final AvesMapController? controller;
final ValueNotifier<ZoomedBounds> boundsNotifier; final ValueNotifier<ZoomedBounds> boundsNotifier;
final bool interactive; final bool interactive, showBackButton;
final double minZoom, maxZoom; final double minZoom, maxZoom;
final EntryMapStyle style; final EntryMapStyle style;
final MarkerClusterBuilder markerClusterBuilder; final MarkerClusterBuilder markerClusterBuilder;
@ -33,6 +33,7 @@ class EntryLeafletMap extends StatefulWidget {
this.controller, this.controller,
required this.boundsNotifier, required this.boundsNotifier,
required this.interactive, required this.interactive,
required this.showBackButton,
this.minZoom = 0, this.minZoom = 0,
this.maxZoom = 22, this.maxZoom = 22,
required this.style, required this.style,
@ -107,6 +108,7 @@ class _EntryLeafletMapState extends State<EntryLeafletMap> with TickerProviderSt
child: _buildMap(), child: _buildMap(),
), ),
MapButtonPanel( MapButtonPanel(
showBackButton: widget.showBackButton,
boundsNotifier: boundsNotifier, boundsNotifier: boundsNotifier,
zoomBy: _zoomBy, zoomBy: _zoomBy,
resetRotation: interactive ? _resetRotation : null, resetRotation: interactive ? _resetRotation : null,

View file

@ -3,7 +3,6 @@ import 'package:aves/model/settings/map_style.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/utils/debouncer.dart'; import 'package:aves/utils/debouncer.dart';
import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/map/controller.dart'; import 'package:aves/widgets/common/map/controller.dart';
import 'package:aves/widgets/common/map/geo_map.dart'; import 'package:aves/widgets/common/map/geo_map.dart';
import 'package:aves/widgets/common/providers/media_query_data_provider.dart'; import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
@ -61,9 +60,6 @@ class _MapPageState extends State<MapPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MediaQueryDataProvider( return MediaQueryDataProvider(
child: Scaffold( child: Scaffold(
appBar: AppBar(
title: Text(context.l10n.mapPageTitle),
),
body: SafeArea( body: SafeArea(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -73,6 +69,7 @@ class _MapPageState extends State<MapPage> {
controller: _mapController, controller: _mapController,
entries: entries, entries: entries,
interactive: true, interactive: true,
showBackButton: true,
isAnimatingNotifier: _isAnimatingNotifier, isAnimatingNotifier: _isAnimatingNotifier,
onMarkerTap: (markerEntry, getClusterEntries) { onMarkerTap: (markerEntry, getClusterEntries) {
final index = entries.indexOf(markerEntry); final index = entries.indexOf(markerEntry);

View file

@ -85,6 +85,7 @@ class _LocationSectionState extends State<LocationSection> {
GeoMap( GeoMap(
entries: [entry], entries: [entry],
interactive: false, interactive: false,
showBackButton: false,
mapHeight: 200, mapHeight: 200,
isAnimatingNotifier: widget.isScrollingNotifier, isAnimatingNotifier: widget.isScrollingNotifier,
onUserZoomChange: (zoom) => settings.infoMapZoom = zoom, onUserZoomChange: (zoom) => settings.infoMapZoom = zoom,