Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Gestures update - two finger rotation / interactions filter / map events #719

Merged
merged 44 commits into from Jan 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
3f16f70
Add two finger rotation support
maRci002 Aug 5, 2020
921f85c
Add InteractiveFlags
maRci002 Aug 5, 2020
b1b9a80
Add example page
maRci002 Aug 5, 2020
1f298ab
Emit MapEvents basic
maRci002 Aug 6, 2020
cbeff6a
Update interactive test page
maRci002 Aug 6, 2020
55930bb
update interactive page
maRci002 Aug 6, 2020
d67c0bc
Emit move / rotate events
maRci002 Aug 6, 2020
95e9afa
Emit rotation events
maRci002 Aug 6, 2020
08e22d5
Rotate only when rotationThreshold reached
maRci002 Aug 6, 2020
e32e3ce
Update examples
maRci002 Aug 6, 2020
79262fd
add some document
maRci002 Aug 6, 2020
e813762
fix some event's source
maRci002 Aug 6, 2020
d1e418c
typo fix
maRci002 Aug 6, 2020
8299d81
Call onRotationChanged correctly
maRci002 Aug 7, 2020
a6b5c6f
Fix arbitrary jumps when map is panned in rotated state
maRci002 Aug 7, 2020
f885845
tap / longPress / double tap use rotated offset / fix GestureDetector…
maRci002 Aug 17, 2020
6e05482
code refactor / organize
maRci002 Aug 17, 2020
b503315
Wip-gesture race: time to test on real device
maRci002 Aug 21, 2020
a7206b6
Fix multi finger gesture race
maRci002 Aug 21, 2020
919cce2
Reset gesture winner correctly
maRci002 Aug 23, 2020
55dd172
Use MultiFingerGesture during gesture race
maRci002 Aug 24, 2020
fe893a7
update MultiFingerGesture doc
maRci002 Aug 24, 2020
3ff9e08
add debugMultiFingerGestureWinner / enableMultiFingerGestureRace
maRci002 Aug 24, 2020
ea3d268
Do not override original start point
maRci002 Aug 24, 2020
11df8b3
mapEventStream do not rely on MapController.ready
maRci002 Aug 24, 2020
fa4c644
emit MapEventFlingAnimationStart correctly
maRci002 Aug 24, 2020
9b643aa
remove expensive _positionedTapDetectorKey
maRci002 Aug 24, 2020
40fd4c3
rebuild layers just once when Move and Rotate happens at the same time
maRci002 Aug 24, 2020
71f7112
use different eventKey in example
maRci002 Aug 25, 2020
d0d44e6
GestureDetector isn't rotated anymore
maRci002 Aug 26, 2020
709a039
Correct fling animation when map is rotated
maRci002 Aug 26, 2020
2c14e68
Make rotation operation cheaper
maRci002 Aug 26, 2020
9e550fe
add rotate flag for layers
maRci002 Aug 26, 2020
805e1e5
Revert "add rotate flag for layers"
maRci002 Aug 27, 2020
12e779d
create rotate and non rotate layers
maRci002 Aug 27, 2020
0d88682
Use Stream<Null> rebuild instead of dynamic
maRci002 Aug 27, 2020
25042f0
#736 fix - rebuild layers when size changed with new pixelOrigin
maRci002 Aug 29, 2020
a9c1a9c
#736 fix2 - do not call onMoveSink after init
maRci002 Aug 29, 2020
12ae8ce
#736 fix2 - handle rebuild layers without _updateSizeByOriginalSizeAn…
maRci002 Aug 29, 2020
075b0a7
fix emit MapEventMove while multifinger
maRci002 Sep 18, 2020
200400f
try to fix dartanalyzer for Travis
maRci002 Sep 18, 2020
239c151
try to fix dartanalyzer for Travis 2
maRci002 Sep 18, 2020
67996ff
Merge branch 'master' into feature/gesture-update
johnpryan Jan 29, 2021
711c455
Update tile_layer.dart
johnpryan Jan 29, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions example/android/app/src/main/AndroidManifest.xml
Expand Up @@ -5,6 +5,10 @@
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<application
android:name="io.flutter.app.FlutterApplication"
android:label="example"
Expand Down
2 changes: 2 additions & 0 deletions example/lib/main.dart
Expand Up @@ -21,6 +21,7 @@ import './pages/tap_to_add.dart';
import './pages/tile_loading_error_handle.dart';
import './pages/widgets.dart';
import './pages/wms_tile_layer.dart';
import 'pages/interactive_test_page.dart';

void main() => runApp(MyApp());

Expand Down Expand Up @@ -56,6 +57,7 @@ class MyApp extends StatelessWidget {
CustomCrsPage.route: (context) => CustomCrsPage(),
LiveLocationPage.route: (context) => LiveLocationPage(),
TileLoadingErrorHandle.route: (context) => TileLoadingErrorHandle(),
InteractiveTestPage.route: (context) => InteractiveTestPage(),
},
);
}
Expand Down
191 changes: 191 additions & 0 deletions example/lib/pages/interactive_test_page.dart
@@ -0,0 +1,191 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong/latlong.dart';

import '../widgets/drawer.dart';

class InteractiveTestPage extends StatefulWidget {
static const String route = 'interactive_test_page';

@override
State createState() {
return _InteractiveTestPageState();
}
}

class _InteractiveTestPageState extends State<InteractiveTestPage> {
MapController mapController;

// Enable pinchZoom and doubleTapZoomBy by default
int flags = InteractiveFlag.pinchZoom | InteractiveFlag.doubleTapZoom;

StreamSubscription<MapEvent> subscription;

@override
void initState() {
super.initState();
mapController = MapController();

subscription = mapController.mapEventStream.listen(onMapEvent);
}

@override
void dispose() {
subscription.cancel();

super.dispose();
}

void onMapEvent(MapEvent mapEvent) {
if (mapEvent is! MapEventMove && mapEvent is! MapEventRotate) {
// do not flood console with move and rotate events
print(mapEvent);
}
}

void updateFlags(int flag) {
if (InteractiveFlag.hasFlag(flags, flag)) {
// remove flag from flags
flags &= ~flag;
} else {
// add flag to flags
flags |= flag;
}
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Test out Interactive flags!')),
drawer: buildDrawer(context, InteractiveTestPage.route),
body: Padding(
padding: EdgeInsets.all(8.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
MaterialButton(
child: Text('Drag'),
color: InteractiveFlag.hasFlag(flags, InteractiveFlag.drag)
? Colors.greenAccent
: Colors.redAccent,
onPressed: () {
setState(() {
updateFlags(InteractiveFlag.drag);
});
},
),
MaterialButton(
child: Text('Fling'),
color: InteractiveFlag.hasFlag(
flags, InteractiveFlag.flingAnimation)
? Colors.greenAccent
: Colors.redAccent,
onPressed: () {
setState(() {
updateFlags(InteractiveFlag.flingAnimation);
});
},
),
MaterialButton(
child: Text('Pinch move'),
color:
InteractiveFlag.hasFlag(flags, InteractiveFlag.pinchMove)
? Colors.greenAccent
: Colors.redAccent,
onPressed: () {
setState(() {
updateFlags(InteractiveFlag.pinchMove);
});
},
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
MaterialButton(
child: Text('Double tap zoom'),
color: InteractiveFlag.hasFlag(
flags, InteractiveFlag.doubleTapZoom)
? Colors.greenAccent
: Colors.redAccent,
onPressed: () {
setState(() {
updateFlags(InteractiveFlag.doubleTapZoom);
});
},
),
MaterialButton(
child: Text('Rotate'),
color: InteractiveFlag.hasFlag(flags, InteractiveFlag.rotate)
? Colors.greenAccent
: Colors.redAccent,
onPressed: () {
setState(() {
updateFlags(InteractiveFlag.rotate);
});
},
),
MaterialButton(
child: Text('Pinch zoom'),
color:
InteractiveFlag.hasFlag(flags, InteractiveFlag.pinchZoom)
? Colors.greenAccent
: Colors.redAccent,
onPressed: () {
setState(() {
updateFlags(InteractiveFlag.pinchZoom);
});
},
),
],
),
Padding(
padding: EdgeInsets.only(top: 8.0, bottom: 8.0),
child: Center(
child: StreamBuilder<MapEvent>(
stream: mapController.mapEventStream,
builder:
(BuildContext context, AsyncSnapshot<MapEvent> snapshot) {
if (!snapshot.hasData) {
return Text(
'Current event: none\nSource: none',
textAlign: TextAlign.center,
);
}

return Text(
'Current event: ${snapshot.data.runtimeType}\nSource: ${snapshot.data.source}',
textAlign: TextAlign.center,
);
},
),
),
),
Flexible(
child: FlutterMap(
mapController: mapController,
options: MapOptions(
center: LatLng(51.5, -0.09),
zoom: 11.0,
interactiveFlags: flags,
),
layers: [
TileLayerOptions(
urlTemplate:
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
subdomains: ['a', 'b', 'c'],
),
],
),
),
],
),
),
);
}
}
37 changes: 31 additions & 6 deletions example/lib/pages/live_location.dart
Expand Up @@ -4,6 +4,8 @@ import 'package:flutter_map/flutter_map.dart';
import 'package:latlong/latlong.dart';
import 'package:location/location.dart';

import '../widgets/drawer.dart';

class LiveLocationPage extends StatefulWidget {
static const String route = '/live_location';

Expand All @@ -15,11 +17,13 @@ class _LiveLocationPageState extends State<LiveLocationPage> {
LocationData _currentLocation;
MapController _mapController;

bool _liveUpdate = true;
bool _liveUpdate = false;
bool _permission = false;

String _serviceError = '';

var interActiveFlags = InteractiveFlag.all;

final Location _locationService = Location();

@override
Expand Down Expand Up @@ -114,7 +118,7 @@ class _LiveLocationPageState extends State<LiveLocationPage> {

return Scaffold(
appBar: AppBar(title: Text('Home')),
//drawer: buildDrawer(context, route),
drawer: buildDrawer(context, LiveLocationPage.route),
body: Padding(
padding: EdgeInsets.all(8.0),
child: Column(
Expand All @@ -135,6 +139,7 @@ class _LiveLocationPageState extends State<LiveLocationPage> {
center:
LatLng(currentLatLng.latitude, currentLatLng.longitude),
zoom: 5.0,
interactiveFlags: interActiveFlags,
),
layers: [
TileLayerOptions(
Expand All @@ -153,10 +158,30 @@ class _LiveLocationPageState extends State<LiveLocationPage> {
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => _liveUpdate = !_liveUpdate,
child: _liveUpdate ? Icon(Icons.location_on) : Icon(Icons.location_off),
),
floatingActionButton: Builder(builder: (BuildContext context) {
return FloatingActionButton(
onPressed: () {
setState(() {
_liveUpdate = !_liveUpdate;

if (_liveUpdate) {
interActiveFlags = InteractiveFlag.rotate |
InteractiveFlag.pinchZoom |
InteractiveFlag.doubleTapZoom;

Scaffold.of(context).showSnackBar(SnackBar(
content: Text(
'In live update mode only zoom and rotation are enable'),
));
} else {
interActiveFlags = InteractiveFlag.all;
}
});
},
child:
_liveUpdate ? Icon(Icons.location_on) : Icon(Icons.location_off),
);
}),
);
}
}