desktop file transfer shift + click multi selection
This commit is contained in:
parent
7e7214bd07
commit
b265d25dcb
@ -6,7 +6,6 @@ import 'package:desktop_drop/desktop_drop.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_breadcrumb/flutter_breadcrumb.dart';
|
import 'package:flutter_breadcrumb/flutter_breadcrumb.dart';
|
||||||
import 'package:flutter_hbb/mobile/pages/file_manager_page.dart';
|
|
||||||
import 'package:flutter_hbb/models/file_model.dart';
|
import 'package:flutter_hbb/models/file_model.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
@ -273,21 +272,8 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
return DataRow(
|
return DataRow(
|
||||||
key: ValueKey(entry.name),
|
key: ValueKey(entry.name),
|
||||||
onSelectChanged: (s) {
|
onSelectChanged: (s) {
|
||||||
final isCtrlDown = RawKeyboard.instance.keysPressed
|
_onSelectedChanged(getSelectedItem(isLocal), filteredEntries,
|
||||||
.contains(LogicalKeyboardKey.controlLeft);
|
entry, isLocal);
|
||||||
final items = getSelectedItem(isLocal);
|
|
||||||
if (isCtrlDown) {
|
|
||||||
if (s != null) {
|
|
||||||
if (s) {
|
|
||||||
items.add(isLocal, entry);
|
|
||||||
} else {
|
|
||||||
items.remove(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
items.clear();
|
|
||||||
items.add(isLocal, entry);
|
|
||||||
}
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
selected: getSelectedItem(isLocal).contains(entry),
|
selected: getSelectedItem(isLocal).contains(entry),
|
||||||
@ -321,20 +307,8 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
items.clear();
|
items.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
_onSelectedChanged(
|
||||||
final isCtrlDown = RawKeyboard.instance.keysPressed
|
items, filteredEntries, entry, isLocal);
|
||||||
.contains(LogicalKeyboardKey.controlLeft);
|
|
||||||
if (isCtrlDown) {
|
|
||||||
if (items.contains(entry)) {
|
|
||||||
items.remove(entry);
|
|
||||||
} else {
|
|
||||||
items.add(isLocal, entry);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
items.clear();
|
|
||||||
items.add(isLocal, entry);
|
|
||||||
}
|
|
||||||
setState(() {});
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
DataCell(FittedBox(
|
DataCell(FittedBox(
|
||||||
@ -362,6 +336,38 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onSelectedChanged(SelectedItems selectedItems, List<Entry> entries,
|
||||||
|
Entry entry, bool isLocal) {
|
||||||
|
final isCtrlDown = RawKeyboard.instance.keysPressed
|
||||||
|
.contains(LogicalKeyboardKey.controlLeft);
|
||||||
|
final isShiftDown =
|
||||||
|
RawKeyboard.instance.keysPressed.contains(LogicalKeyboardKey.shiftLeft);
|
||||||
|
if (isCtrlDown) {
|
||||||
|
if (selectedItems.contains(entry)) {
|
||||||
|
selectedItems.remove(entry);
|
||||||
|
} else {
|
||||||
|
selectedItems.add(isLocal, entry);
|
||||||
|
}
|
||||||
|
} else if (isShiftDown) {
|
||||||
|
final List<int> indexGroup = [];
|
||||||
|
for (var selected in selectedItems.items) {
|
||||||
|
indexGroup.add(entries.indexOf(selected));
|
||||||
|
}
|
||||||
|
indexGroup.add(entries.indexOf(entry));
|
||||||
|
indexGroup.removeWhere((e) => e == -1);
|
||||||
|
final maxIndex = indexGroup.reduce(max);
|
||||||
|
final minIndex = indexGroup.reduce(min);
|
||||||
|
selectedItems.clear();
|
||||||
|
entries
|
||||||
|
.getRange(minIndex, maxIndex + 1)
|
||||||
|
.forEach((e) => selectedItems.add(isLocal, e));
|
||||||
|
} else {
|
||||||
|
selectedItems.clear();
|
||||||
|
selectedItems.add(isLocal, entry);
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
bool _checkDoubleClick(Entry entry) {
|
bool _checkDoubleClick(Entry entry) {
|
||||||
final current = DateTime.now().millisecondsSinceEpoch;
|
final current = DateTime.now().millisecondsSinceEpoch;
|
||||||
final elapsed = current - _lastClickTime;
|
final elapsed = current - _lastClickTime;
|
||||||
|
@ -555,50 +555,3 @@ class BottomSheetBody extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SelectedItems {
|
|
||||||
bool? _isLocal;
|
|
||||||
final List<Entry> _items = [];
|
|
||||||
|
|
||||||
List<Entry> get items => _items;
|
|
||||||
|
|
||||||
int get length => _items.length;
|
|
||||||
|
|
||||||
bool? get isLocal => _isLocal;
|
|
||||||
|
|
||||||
add(bool isLocal, Entry e) {
|
|
||||||
if (_isLocal == null) {
|
|
||||||
_isLocal = isLocal;
|
|
||||||
}
|
|
||||||
if (_isLocal != null && _isLocal != isLocal) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!_items.contains(e)) {
|
|
||||||
_items.add(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool contains(Entry e) {
|
|
||||||
return _items.contains(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
remove(Entry e) {
|
|
||||||
_items.remove(e);
|
|
||||||
if (_items.length == 0) {
|
|
||||||
_isLocal = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isOtherPage(bool currentIsLocal) {
|
|
||||||
if (_isLocal == null) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return _isLocal != currentIsLocal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clear() {
|
|
||||||
_items.clear();
|
|
||||||
_isLocal = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -3,7 +3,6 @@ import 'dart:convert';
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hbb/common.dart';
|
import 'package:flutter_hbb/common.dart';
|
||||||
import 'package:flutter_hbb/mobile/pages/file_manager_page.dart';
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:path/path.dart' as Path;
|
import 'package:path/path.dart' as Path;
|
||||||
|
|
||||||
@ -1123,6 +1122,51 @@ class DirectoryOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SelectedItems {
|
||||||
|
bool? _isLocal;
|
||||||
|
final List<Entry> _items = [];
|
||||||
|
|
||||||
|
List<Entry> get items => _items;
|
||||||
|
|
||||||
|
int get length => _items.length;
|
||||||
|
|
||||||
|
bool? get isLocal => _isLocal;
|
||||||
|
|
||||||
|
add(bool isLocal, Entry e) {
|
||||||
|
_isLocal ??= isLocal;
|
||||||
|
if (_isLocal != null && _isLocal != isLocal) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!_items.contains(e)) {
|
||||||
|
_items.add(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool contains(Entry e) {
|
||||||
|
return _items.contains(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(Entry e) {
|
||||||
|
_items.remove(e);
|
||||||
|
if (_items.length == 0) {
|
||||||
|
_isLocal = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isOtherPage(bool currentIsLocal) {
|
||||||
|
if (_isLocal == null) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return _isLocal != currentIsLocal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
_items.clear();
|
||||||
|
_isLocal = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// code from file_manager pkg after edit
|
// code from file_manager pkg after edit
|
||||||
List<Entry> _sortList(List<Entry> list, SortBy sortType, bool ascending) {
|
List<Entry> _sortList(List<Entry> list, SortBy sortType, bool ascending) {
|
||||||
if (sortType == SortBy.Name) {
|
if (sortType == SortBy.Name) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user