Skip to content

Commit d59f067

Browse files
authored
Implement contextual menu on secondary click (#9)
* Switch from actions buttons to action menu * Rename action and submit on enter * Dart fixes * Refactor rename and delete dialogs * Convert mixin to extension * Add auto focus to buttons in dialogs * Change primary dialog button to FIlledButton * Improve keyboard accessibility for context menu * Improve keyboard navigation in list * Update * Fixups * Make new file dialog button filled * Remove unused code * Update dependencies * Fix compile issue for now. Awaiting PR * Use flutter master * Update libraries and pigeon
1 parent 69abff8 commit d59f067

19 files changed

+406
-365
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
4848
- uses: subosito/flutter-action@v2
4949
with:
50-
channel: 'stable'
50+
channel: 'master'
5151
cache: true
5252
cache-key: 'flutter-:os:-:channel:-:version:-:arch:-:hash:' # optional, change this to force refresh cache
5353
cache-path: '${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:' # optional, change this to specify the cache path

lib/pages/adb_check.dart

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,13 @@ class _ADBDownloadDialogState extends State<ADBDownloadDialog> {
6565
return AlertDialog(
6666
title: const Text("ADB not found"),
6767
content: const Text("Do you want to download ADB?"),
68-
actions: [TextButton(onPressed: _download, child: const Text("Ok"))],
68+
actions: [
69+
FilledButton(
70+
autofocus: true,
71+
onPressed: _download,
72+
child: const Text("Ok"),
73+
)
74+
],
6975
);
7076
}
7177

@@ -81,7 +87,11 @@ class _ADBDownloadDialogState extends State<ADBDownloadDialog> {
8187
title: const Text("Suffered error downloading"),
8288
content: Text(messages),
8389
actions: [
84-
TextButton(onPressed: _continue, child: const Text("Continue anyways"))
90+
FilledButton(
91+
autofocus: true,
92+
onPressed: _continue,
93+
child: const Text("Continue anyways"),
94+
)
8595
],
8696
);
8797
}

lib/pages/browser.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ class _DeviceBrowserPageState extends State<DeviceBrowserPage> {
283283
key: ValueKey(file),
284284
onWatch: () => _watchFile(file),
285285
isCard: true,
286-
fileWrapper: file,
286+
fileData: file,
287287
));
288288
});
289289
}
@@ -692,7 +692,7 @@ class _NewFileDialogState extends State<NewFileDialog> {
692692
},
693693
);
694694

695-
var confirmButton = TextButton(
695+
var confirmButton = FilledButton(
696696
child: const Text('Ok'),
697697
onPressed: () {
698698
var path = Adb.adbPathContext

lib/pages/logger.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,14 @@ class _LogPageState extends State<LogPage> {
157157
title: const Text("Error while streaming logcat"),
158158
content: Text(error),
159159
actions: [
160-
TextButton(onPressed: _queueSave, child: const Text("Save")),
161160
TextButton(
162161
onPressed: () => Navigator.of(context).pop(),
163-
child: const Text("Back"))
162+
child: const Text("Back")),
163+
FilledButton(
164+
autofocus: true,
165+
onPressed: _queueSave,
166+
child: const Text("Save"),
167+
)
164168
],
165169
));
166170
}

lib/src/pigeon.g.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Autogenerated from Pigeon (v14.0.0), do not edit directly.
1+
// Autogenerated from Pigeon (v15.0.0), do not edit directly.
22
// See also: https://pub.dev/packages/pigeon
33
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers
44

lib/utils/adb.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import 'dart:io';
44
import 'package:archive/archive_io.dart';
55
import 'package:async/async.dart';
66
import 'package:desktop_adb_file_browser/utils/platform.dart';
7-
import 'package:desktop_adb_file_browser/widgets/browser/file_data.dart';
87
import 'package:dio/dio.dart';
98
import 'package:flutter/cupertino.dart';
109
import 'package:path/path.dart';
@@ -423,7 +422,7 @@ class Device {
423422
final String? deviceManufacturer;
424423
final String modelName;
425424

426-
Device(
425+
const Device(
427426
{required this.serialName,
428427
this.deviceManufacturer,
429428
required this.modelName});
@@ -437,7 +436,7 @@ class FileListingData {
437436
final DateTime date;
438437
final String path;
439438

440-
FileListingData(
439+
const FileListingData(
441440
{required this.permission,
442441
required this.user,
443442
required this.size,
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import 'package:flutter/foundation.dart';
2+
import 'package:flutter/material.dart';
3+
import 'package:flutter/services.dart';
4+
5+
class AdaptiveContextualMenu extends StatelessWidget {
6+
const AdaptiveContextualMenu({
7+
super.key,
8+
required this.child,
9+
required this.menuChildren,
10+
this.focusNode,
11+
this.menuController,
12+
});
13+
14+
final Widget child;
15+
final List<Widget> menuChildren;
16+
17+
final FocusNode? focusNode;
18+
final MenuController? menuController;
19+
20+
@override
21+
Widget build(BuildContext context) {
22+
return Focus(
23+
canRequestFocus: false,
24+
onKeyEvent: _onKeyEvent,
25+
child: GestureDetector(
26+
onTapDown: _handleTapDown,
27+
onSecondaryTapDown: _handleSecondaryTapDown,
28+
child: MenuAnchor(
29+
consumeOutsideTap: false,
30+
controller: menuController,
31+
menuChildren: menuChildren,
32+
childFocusNode: focusNode,
33+
child: child,
34+
),
35+
),
36+
);
37+
}
38+
39+
void _handleSecondaryTapDown(TapDownDetails details) {
40+
menuController?.open(position: details.localPosition);
41+
}
42+
43+
void _handleTapDown(TapDownDetails details) {
44+
switch (defaultTargetPlatform) {
45+
case TargetPlatform.android:
46+
case TargetPlatform.fuchsia:
47+
case TargetPlatform.linux:
48+
case TargetPlatform.windows:
49+
// Don't open the menu on these platforms with a Ctrl-tap (or a
50+
// tap).
51+
break;
52+
case TargetPlatform.iOS:
53+
case TargetPlatform.macOS:
54+
// Only open the menu on these platforms if the control button is down
55+
// when the tap occurs.
56+
if (HardwareKeyboard.instance.logicalKeysPressed
57+
.contains(LogicalKeyboardKey.controlLeft) ||
58+
HardwareKeyboard.instance.logicalKeysPressed
59+
.contains(LogicalKeyboardKey.controlRight)) {
60+
menuController?.open(position: details.localPosition);
61+
}
62+
}
63+
}
64+
65+
KeyEventResult _onKeyEvent(FocusNode node, KeyEvent event) {
66+
if (node.hasFocus) {
67+
final isCtrl = HardwareKeyboard.instance.logicalKeysPressed
68+
.contains(LogicalKeyboardKey.controlLeft) || HardwareKeyboard.instance.logicalKeysPressed
69+
.contains(LogicalKeyboardKey.controlRight);
70+
if (event.logicalKey == LogicalKeyboardKey.enter && isCtrl) {
71+
menuController?.open();
72+
}
73+
}
74+
75+
return KeyEventResult.ignored;
76+
}
77+
}

lib/widgets/better_lazy_data_table.dart.old

Lines changed: 0 additions & 64 deletions
This file was deleted.

0 commit comments

Comments
 (0)