left shift key for peer card select
Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
parent
5a0865559c
commit
f5cf291f55
@ -68,7 +68,7 @@ class _PeerCardState extends State<_PeerCard>
|
|||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (peerTabModel.multiSelectionMode) {
|
if (peerTabModel.multiSelectionMode) {
|
||||||
peerTabModel.onPeerCardTap(peer);
|
peerTabModel.togglePeerSelect(peer);
|
||||||
} else {
|
} else {
|
||||||
if (!isWebDesktop) connect(context, peer.id);
|
if (!isWebDesktop) connect(context, peer.id);
|
||||||
}
|
}
|
||||||
@ -167,7 +167,7 @@ class _PeerCardState extends State<_PeerCard>
|
|||||||
peerTabModel.togglePeerSelect(peer);
|
peerTabModel.togglePeerSelect(peer);
|
||||||
},
|
},
|
||||||
onTap: peerTabModel.multiSelectionMode
|
onTap: peerTabModel.multiSelectionMode
|
||||||
? () => peerTabModel.onPeerCardTap(peer)
|
? () => peerTabModel.togglePeerSelect(peer)
|
||||||
: null,
|
: null,
|
||||||
child: Obx(() => peerCardUiType.value == PeerUiType.grid
|
child: Obx(() => peerCardUiType.value == PeerUiType.grid
|
||||||
? _buildPeerCard(context, peer, deco)
|
? _buildPeerCard(context, peer, deco)
|
||||||
|
@ -5,6 +5,7 @@ import 'dart:io';
|
|||||||
import 'package:bot_toast/bot_toast.dart';
|
import 'package:bot_toast/bot_toast.dart';
|
||||||
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_hbb/desktop/pages/desktop_tab_page.dart';
|
import 'package:flutter_hbb/desktop/pages/desktop_tab_page.dart';
|
||||||
import 'package:flutter_hbb/desktop/pages/install_page.dart';
|
import 'package:flutter_hbb/desktop/pages/install_page.dart';
|
||||||
import 'package:flutter_hbb/desktop/pages/server_page.dart';
|
import 'package:flutter_hbb/desktop/pages/server_page.dart';
|
||||||
@ -417,6 +418,9 @@ class _AppState extends State<App> {
|
|||||||
: (context, child) {
|
: (context, child) {
|
||||||
child = _keepScaleBuilder(context, child);
|
child = _keepScaleBuilder(context, child);
|
||||||
child = botToastBuilder(context, child);
|
child = botToastBuilder(context, child);
|
||||||
|
if (desktopType == DesktopType.main) {
|
||||||
|
child = keyListenerBuilder(context, child);
|
||||||
|
}
|
||||||
return child;
|
return child;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -453,3 +457,19 @@ _registerEventHandler() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget keyListenerBuilder(BuildContext context, Widget? child) {
|
||||||
|
return RawKeyboardListener(
|
||||||
|
focusNode: FocusNode(),
|
||||||
|
child: child ?? Container(),
|
||||||
|
onKey: (RawKeyEvent event) {
|
||||||
|
if (event.logicalKey == LogicalKeyboardKey.shiftLeft) {
|
||||||
|
if (event is RawKeyDownEvent) {
|
||||||
|
gFFI.peerTabModel.isShiftDown = true;
|
||||||
|
} else if (event is RawKeyUpEvent) {
|
||||||
|
gFFI.peerTabModel.isShiftDown = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hbb/models/peer_model.dart';
|
import 'package:flutter_hbb/models/peer_model.dart';
|
||||||
import 'package:flutter_hbb/models/platform_model.dart';
|
import 'package:flutter_hbb/models/platform_model.dart';
|
||||||
@ -40,6 +42,8 @@ class PeerTabModel with ChangeNotifier {
|
|||||||
bool get multiSelectionMode => _selectedPeers.isNotEmpty;
|
bool get multiSelectionMode => _selectedPeers.isNotEmpty;
|
||||||
List<Peer> _currentTabCachedPeers = List.empty(growable: true);
|
List<Peer> _currentTabCachedPeers = List.empty(growable: true);
|
||||||
List<Peer> get currentTabCachedPeers => _currentTabCachedPeers;
|
List<Peer> get currentTabCachedPeers => _currentTabCachedPeers;
|
||||||
|
bool isShiftDown = false;
|
||||||
|
String? _shiftAnchorId;
|
||||||
|
|
||||||
PeerTabModel(this.parent) {
|
PeerTabModel(this.parent) {
|
||||||
// init currentTab
|
// init currentTab
|
||||||
@ -82,21 +86,53 @@ class PeerTabModel with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
togglePeerSelect(Peer peer) {
|
togglePeerSelect(Peer peer) {
|
||||||
if (_selectedPeers.firstWhereOrNull((p) => p.id == peer.id) != null) {
|
final cached = _currentTabCachedPeers.map((e) => e.id).toList();
|
||||||
|
int thisIndex = cached.indexOf(peer.id);
|
||||||
|
int closestIndex = -1;
|
||||||
|
String? closestId;
|
||||||
|
int smallestDiff = -1;
|
||||||
|
for (var i = 0; i < cached.length; i++) {
|
||||||
|
if (isPeerSelected(cached[i])) {
|
||||||
|
int diff = (i - thisIndex).abs();
|
||||||
|
if (smallestDiff == -1 || diff < smallestDiff) {
|
||||||
|
closestIndex = i;
|
||||||
|
closestId = cached[i];
|
||||||
|
smallestDiff = diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isShiftDown &&
|
||||||
|
thisIndex >= 0 &&
|
||||||
|
closestIndex >= 0 &&
|
||||||
|
closestId != null) {
|
||||||
|
int shiftAnchorIndex = cached.indexOf(_shiftAnchorId ?? '');
|
||||||
|
if (shiftAnchorIndex < 0) {
|
||||||
|
// use closest as shift anchor, rather than focused which we don't have
|
||||||
|
shiftAnchorIndex = closestIndex;
|
||||||
|
_shiftAnchorId = closestId;
|
||||||
|
}
|
||||||
|
int start = min(shiftAnchorIndex, thisIndex);
|
||||||
|
int end = max(shiftAnchorIndex, thisIndex);
|
||||||
|
_selectedPeers.clear();
|
||||||
|
for (var i = start; i <= end; i++) {
|
||||||
|
if (!isPeerSelected(cached[i])) {
|
||||||
|
_selectedPeers.add(_currentTabCachedPeers[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isPeerSelected(peer.id)) {
|
||||||
_selectedPeers.removeWhere((p) => p.id == peer.id);
|
_selectedPeers.removeWhere((p) => p.id == peer.id);
|
||||||
} else {
|
} else {
|
||||||
_selectedPeers.add(peer);
|
_selectedPeers.add(peer);
|
||||||
}
|
}
|
||||||
notifyListeners();
|
_shiftAnchorId = null;
|
||||||
}
|
}
|
||||||
|
notifyListeners();
|
||||||
onPeerCardTap(Peer peer) {
|
|
||||||
if (!multiSelectionMode) return;
|
|
||||||
togglePeerSelect(peer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
closeSelection() {
|
closeSelection() {
|
||||||
_selectedPeers.clear();
|
_selectedPeers.clear();
|
||||||
|
_shiftAnchorId = null;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user