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": {},
"mapPageTitle": "Map",
"@mapPageTitle": {},
"statsPageTitle": "Stats",
"@statsPageTitle": {},
"statsImage": "{count, plural, =1{image} other{images}}",
@ -858,14 +855,16 @@
"viewerInfoLabelAddress": "Address",
"@viewerInfoLabelAddress": {},
"viewerInfoMapStyleTitle": "Map Style",
"@viewerInfoMapStyleTitle": {},
"viewerInfoMapStyleTooltip": "Select map style",
"@viewerInfoMapStyleTooltip": {},
"viewerInfoMapZoomInTooltip": "Zoom in",
"@viewerInfoMapZoomInTooltip": {},
"viewerInfoMapZoomOutTooltip": "Zoom out",
"@viewerInfoMapZoomOutTooltip": {},
"mapStyleTitle": "Map Style",
"@mapStyleTitle": {},
"mapStyleTooltip": "Select map style",
"@mapStyleTooltip": {},
"mapZoomInTooltip": "Zoom in",
"@mapZoomInTooltip": {},
"mapZoomOutTooltip": "Zoom out",
"@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": {},
"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": "좌표 표현",
"settingsCoordinateFormatTitle": "좌표 표현",
"mapPageTitle": "지도",
"statsPageTitle": "통계",
"statsImage": "{count, plural, other{사진}}",
"statsVideo": "{count, plural, other{동영상}}",
@ -419,10 +417,11 @@
"viewerInfoLabelCoordinates": "좌표",
"viewerInfoLabelAddress": "주소",
"viewerInfoMapStyleTitle": "지도 유형",
"viewerInfoMapStyleTooltip": "지도 유형 선택",
"viewerInfoMapZoomInTooltip": "확대",
"viewerInfoMapZoomOutTooltip": "축소",
"mapStyleTitle": "지도 유형",
"mapStyleTooltip": "지도 유형 선택",
"mapZoomInTooltip": "확대",
"mapZoomOutTooltip": "축소",
"mapPointNorthUpTooltip": "북쪽을 위로 가리키기",
"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)",

View file

@ -18,6 +18,7 @@ import 'package:flutter/scheduler.dart';
import 'package:latlong2/latlong.dart';
class MapButtonPanel extends StatelessWidget {
final bool showBackButton;
final ValueNotifier<ZoomedBounds> boundsNotifier;
final Future<void> Function(double amount)? zoomBy;
final VoidCallback? resetRotation;
@ -26,6 +27,7 @@ class MapButtonPanel extends StatelessWidget {
const MapButtonPanel({
Key? key,
required this.showBackButton,
required this.boundsNotifier,
this.zoomBy,
this.resetRotation,
@ -46,34 +48,51 @@ class MapButtonPanel extends StatelessWidget {
),
child: Stack(
children: [
if (resetRotation != null)
Positioned(
left: 0,
child: ValueListenableBuilder<ZoomedBounds>(
valueListenable: boundsNotifier,
builder: (context, bounds, child) {
final degrees = bounds.rotation;
return AnimatedOpacity(
opacity: degrees == 0 ? 0 : 1,
duration: Durations.viewerOverlayAnimation,
child: MapOverlayButton(
icon: Transform(
origin: iconSize.center(Offset.zero),
transform: Matrix4.rotationZ(degToRadian(degrees)),
child: CustomPaint(
painter: CompassPainter(
color: iconTheme.color!,
Positioned(
left: 0,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (showBackButton)
MapOverlayButton(
icon: const BackButtonIcon(),
onPressed: () => Navigator.pop(context),
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
),
if (resetRotation != null) ...[
const SizedBox(height: padding),
ValueListenableBuilder<ZoomedBounds>(
valueListenable: boundsNotifier,
builder: (context, bounds, child) {
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(
right: 0,
child: Column(
@ -100,7 +119,7 @@ class MapButtonPanel extends StatelessWidget {
return AvesSelectionDialog<EntryMapStyle>(
initialValue: initialStyle,
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;
}
},
tooltip: context.l10n.viewerInfoMapStyleTooltip,
tooltip: context.l10n.mapStyleTooltip,
),
],
),
@ -124,13 +143,13 @@ class MapButtonPanel extends StatelessWidget {
MapOverlayButton(
icon: const Icon(AIcons.zoomIn),
onPressed: zoomBy != null ? () => zoomBy?.call(1) : null,
tooltip: context.l10n.viewerInfoMapZoomInTooltip,
tooltip: context.l10n.mapZoomInTooltip,
),
const SizedBox(height: padding),
MapOverlayButton(
icon: const Icon(AIcons.zoomOut),
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 {
final AvesMapController? controller;
final List<AvesEntry> entries;
final bool interactive;
final bool interactive, showBackButton;
final double? mapHeight;
final ValueNotifier<bool> isAnimatingNotifier;
final UserZoomChangeCallback? onUserZoomChange;
@ -41,6 +41,7 @@ class GeoMap extends StatefulWidget {
this.controller,
required this.entries,
required this.interactive,
required this.showBackButton,
this.mapHeight,
required this.isAnimatingNotifier,
this.onUserZoomChange,
@ -65,6 +66,8 @@ class _GeoMapState extends State<GeoMap> {
bool get interactive => widget.interactive;
bool get showBackButton => widget.showBackButton;
double? get mapHeight => widget.mapHeight;
@override
@ -137,6 +140,7 @@ class _GeoMapState extends State<GeoMap> {
controller: widget.controller,
boundsNotifier: _boundsNotifier,
interactive: interactive,
showBackButton: showBackButton,
minZoom: 0,
maxZoom: 20,
style: mapStyle,
@ -149,6 +153,7 @@ class _GeoMapState extends State<GeoMap> {
controller: widget.controller,
boundsNotifier: _boundsNotifier,
interactive: interactive,
showBackButton: showBackButton,
minZoom: 2,
maxZoom: 16,
style: mapStyle,
@ -191,6 +196,7 @@ class _GeoMapState extends State<GeoMap> {
interactive: interactive,
),
MapButtonPanel(
showBackButton: showBackButton,
boundsNotifier: _boundsNotifier,
),
],

View file

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

View file

@ -19,7 +19,7 @@ import 'package:latlong2/latlong.dart';
class EntryLeafletMap extends StatefulWidget {
final AvesMapController? controller;
final ValueNotifier<ZoomedBounds> boundsNotifier;
final bool interactive;
final bool interactive, showBackButton;
final double minZoom, maxZoom;
final EntryMapStyle style;
final MarkerClusterBuilder markerClusterBuilder;
@ -33,6 +33,7 @@ class EntryLeafletMap extends StatefulWidget {
this.controller,
required this.boundsNotifier,
required this.interactive,
required this.showBackButton,
this.minZoom = 0,
this.maxZoom = 22,
required this.style,
@ -107,6 +108,7 @@ class _EntryLeafletMapState extends State<EntryLeafletMap> with TickerProviderSt
child: _buildMap(),
),
MapButtonPanel(
showBackButton: widget.showBackButton,
boundsNotifier: boundsNotifier,
zoomBy: _zoomBy,
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/theme/durations.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/geo_map.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) {
return MediaQueryDataProvider(
child: Scaffold(
appBar: AppBar(
title: Text(context.l10n.mapPageTitle),
),
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -73,6 +69,7 @@ class _MapPageState extends State<MapPage> {
controller: _mapController,
entries: entries,
interactive: true,
showBackButton: true,
isAnimatingNotifier: _isAnimatingNotifier,
onMarkerTap: (markerEntry, getClusterEntries) {
final index = entries.indexOf(markerEntry);

View file

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