1
1
import 'package:flutter/material.dart' ;
2
+ import 'package:flutter/services.dart' ;
2
3
import 'package:flutter_map/flutter_map.dart' ;
3
4
import 'package:flutter_map_example/widgets/drawer.dart' ;
4
5
import 'package:latlong2/latlong.dart' ;
@@ -9,128 +10,103 @@ class InteractiveTestPage extends StatefulWidget {
9
10
const InteractiveTestPage ({Key ? key}) : super (key: key);
10
11
11
12
@override
12
- State createState () {
13
- return _InteractiveTestPageState ();
14
- }
13
+ State createState () => _InteractiveTestPageState ();
15
14
}
16
15
17
16
class _InteractiveTestPageState extends State <InteractiveTestPage > {
18
- // Enable pinchZoom and doubleTapZoomBy by default
19
- int flags = InteractiveFlag .pinchZoom | InteractiveFlag .doubleTapZoom;
20
-
21
- MapEvent ? _latestEvent;
22
-
23
- @override
24
- void initState () {
25
- super .initState ();
26
- }
17
+ static const availableFlags = {
18
+ 'Movement' : {
19
+ InteractiveFlag .drag: 'Drag' ,
20
+ InteractiveFlag .flingAnimation: 'Fling' ,
21
+ InteractiveFlag .pinchMove: 'Pinch' ,
22
+ },
23
+ 'Zooming' : {
24
+ InteractiveFlag .pinchZoom: 'Pinch' ,
25
+ InteractiveFlag .scrollWheelZoom: 'Scroll' ,
26
+ InteractiveFlag .doubleTapZoom: 'Double tap' ,
27
+ InteractiveFlag .doubleTapDragZoom: '+ drag' ,
28
+ },
29
+ 'Rotation' : {
30
+ InteractiveFlag .rotate: 'Twist' ,
31
+ },
32
+ };
27
33
28
- void onMapEvent (MapEvent mapEvent) {
29
- if (mapEvent is ! MapEventMove && mapEvent is ! MapEventRotate ) {
30
- // do not flood console with move and rotate events
31
- debugPrint (_eventName (mapEvent));
32
- }
33
-
34
- setState (() {
35
- _latestEvent = mapEvent;
36
- });
37
- }
34
+ int flags = InteractiveFlag .drag | InteractiveFlag .pinchZoom;
35
+ bool keyboardCursorRotate = false ;
38
36
39
- void updateFlags (int flag) {
40
- if (InteractiveFlag .hasFlag (flags, flag)) {
41
- // remove flag from flags
42
- flags & = ~ flag;
43
- } else {
44
- // add flag to flags
45
- flags | = flag;
46
- }
47
- }
37
+ MapEvent ? _latestEvent;
48
38
49
39
@override
50
40
Widget build (BuildContext context) {
51
41
return Scaffold (
52
- appBar: AppBar (title: const Text ('Test out Interactive flags! ' )),
42
+ appBar: AppBar (title: const Text ('Interactive Flags ' )),
53
43
drawer: buildDrawer (context, InteractiveTestPage .route),
54
44
body: Padding (
55
45
padding: const EdgeInsets .all (8 ),
56
46
child: Column (
57
47
children: [
58
- Row (
59
- mainAxisAlignment: MainAxisAlignment .spaceBetween,
60
- children: < Widget > [
61
- MaterialButton (
62
- color: InteractiveFlag .hasDrag (flags)
63
- ? Colors .greenAccent
64
- : Colors .redAccent,
65
- onPressed: () {
66
- setState (() {
67
- updateFlags (InteractiveFlag .drag);
68
- });
69
- },
70
- child: const Text ('Drag' ),
71
- ),
72
- MaterialButton (
73
- color: InteractiveFlag .hasFlingAnimation (flags)
74
- ? Colors .greenAccent
75
- : Colors .redAccent,
76
- onPressed: () {
77
- setState (() {
78
- updateFlags (InteractiveFlag .flingAnimation);
79
- });
80
- },
81
- child: const Text ('Fling' ),
82
- ),
83
- MaterialButton (
84
- color: InteractiveFlag .hasPinchMove (flags)
85
- ? Colors .greenAccent
86
- : Colors .redAccent,
87
- onPressed: () {
88
- setState (() {
89
- updateFlags (InteractiveFlag .pinchMove);
90
- });
91
- },
92
- child: const Text ('Pinch move' ),
93
- ),
94
- ],
95
- ),
96
- Row (
97
- mainAxisAlignment: MainAxisAlignment .spaceBetween,
98
- children: < Widget > [
99
- MaterialButton (
100
- color: InteractiveFlag .hasDoubleTapZoom (flags)
101
- ? Colors .greenAccent
102
- : Colors .redAccent,
103
- onPressed: () {
104
- setState (() {
105
- updateFlags (InteractiveFlag .doubleTapZoom);
106
- });
107
- },
108
- child: const Text ('Double tap zoom' ),
109
- ),
110
- MaterialButton (
111
- color: InteractiveFlag .hasRotate (flags)
112
- ? Colors .greenAccent
113
- : Colors .redAccent,
114
- onPressed: () {
115
- setState (() {
116
- updateFlags (InteractiveFlag .rotate);
117
- });
118
- },
119
- child: const Text ('Rotate' ),
120
- ),
121
- MaterialButton (
122
- color: InteractiveFlag .hasPinchZoom (flags)
123
- ? Colors .greenAccent
124
- : Colors .redAccent,
125
- onPressed: () {
126
- setState (() {
127
- updateFlags (InteractiveFlag .pinchZoom);
128
- });
129
- },
130
- child: const Text ('Pinch zoom' ),
131
- ),
132
- ],
48
+ Flex (
49
+ direction: MediaQuery .of (context).size.width >= 600
50
+ ? Axis .horizontal
51
+ : Axis .vertical,
52
+ mainAxisSize: MainAxisSize .max,
53
+ mainAxisAlignment: MainAxisAlignment .spaceEvenly,
54
+ children: availableFlags.entries
55
+ .map <Widget ?>(
56
+ (category) => Column (
57
+ children: [
58
+ Text (
59
+ category.key,
60
+ style: const TextStyle (fontWeight: FontWeight .bold),
61
+ ),
62
+ Row (
63
+ mainAxisSize: MainAxisSize .min,
64
+ children: < Widget > [
65
+ ...category.value.entries.map (
66
+ (e) => Column (
67
+ children: [
68
+ Checkbox .adaptive (
69
+ value:
70
+ InteractiveFlag .hasFlag (e.key, flags),
71
+ onChanged: (enabled) {
72
+ if (! enabled! ) {
73
+ setState (() => flags & = ~ e.key);
74
+ return ;
75
+ }
76
+ setState (() => flags | = e.key);
77
+ },
78
+ ),
79
+ Text (e.value),
80
+ ],
81
+ ),
82
+ ),
83
+ if (category.key == 'Rotation' ) ...[
84
+ Column (
85
+ children: [
86
+ Checkbox .adaptive (
87
+ value: keyboardCursorRotate,
88
+ onChanged: (enabled) => setState (
89
+ () => keyboardCursorRotate = enabled! ),
90
+ ),
91
+ const Text ('Cursor & CTRL' ),
92
+ ],
93
+ ),
94
+ ]
95
+ ].interleave (const SizedBox (width: 12 )).toList ()
96
+ ..removeLast (),
97
+ )
98
+ ],
99
+ ),
100
+ )
101
+ .interleave (
102
+ MediaQuery .of (context).size.width >= 600
103
+ ? null
104
+ : const SizedBox (height: 12 ),
105
+ )
106
+ .whereType <Widget >()
107
+ .toList (),
133
108
),
109
+ const Divider (),
134
110
Padding (
135
111
padding: const EdgeInsets .only (top: 8 , bottom: 8 ),
136
112
child: Center (
@@ -140,14 +116,21 @@ class _InteractiveTestPageState extends State<InteractiveTestPage> {
140
116
),
141
117
),
142
118
),
143
- Flexible (
119
+ Expanded (
144
120
child: FlutterMap (
145
121
options: MapOptions (
146
- onMapEvent: onMapEvent ,
122
+ onMapEvent: (evt) => setState (() => _latestEvent = evt) ,
147
123
initialCenter: const LatLng (51.5 , - 0.09 ),
148
124
initialZoom: 11 ,
149
125
interactionOptions: InteractionOptions (
150
126
flags: flags,
127
+ isCursorRotationKeyboardKeyTrigger: (key) =>
128
+ keyboardCursorRotate &&
129
+ {
130
+ LogicalKeyboardKey .control,
131
+ LogicalKeyboardKey .controlLeft,
132
+ LogicalKeyboardKey .controlRight
133
+ }.contains (key),
151
134
),
152
135
),
153
136
children: [
@@ -210,3 +193,12 @@ class _InteractiveTestPageState extends State<InteractiveTestPage> {
210
193
}
211
194
}
212
195
}
196
+
197
+ extension _IterableExt <E > on Iterable <E > {
198
+ Iterable <E > interleave (E separator) sync * {
199
+ for (int i = 0 ; i < length; i++ ) {
200
+ yield elementAt (i);
201
+ if (i < length) yield separator;
202
+ }
203
+ }
204
+ }
0 commit comments