|
|
|
@ -1,9 +1,7 @@
@@ -1,9 +1,7 @@
|
|
|
|
|
import 'dart:math'; |
|
|
|
|
|
|
|
|
|
import 'package:file_picker/file_picker.dart'; |
|
|
|
|
import 'package:flutter/material.dart'; |
|
|
|
|
import 'package:provider/provider.dart'; |
|
|
|
|
import 'package:win_text_editor/framework/services/file_path_manager.dart'; |
|
|
|
|
|
|
|
|
|
import '../../framework/models/file_node.dart'; |
|
|
|
|
import '../../framework/controllers/file_provider.dart'; |
|
|
|
@ -20,32 +18,18 @@ class FileExplorer extends StatefulWidget {
@@ -20,32 +18,18 @@ class FileExplorer extends StatefulWidget {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
class _FileExplorerState extends State<FileExplorer> { |
|
|
|
|
// 移除所有 ScrollController |
|
|
|
|
final ScrollController _scrollController = ScrollController(); // 添加ScrollController |
|
|
|
|
|
|
|
|
|
Future<void> _promptForDirectory(BuildContext context) async { |
|
|
|
|
final fileProvider = Provider.of<FileProvider>(context, listen: false); |
|
|
|
|
final String? selectedDirectory = await FilePicker.platform.getDirectoryPath(); |
|
|
|
|
|
|
|
|
|
if (selectedDirectory != null) { |
|
|
|
|
await FilePathManager.saveLastOpenedFolder(selectedDirectory); |
|
|
|
|
await fileProvider.setRootPath(selectedDirectory); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Widget _buildEmptyPrompt(BuildContext context) { |
|
|
|
|
return Column( |
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center, |
|
|
|
|
children: [ |
|
|
|
|
const Text('没有文件可显示'), |
|
|
|
|
TextButton(onPressed: () => _promptForDirectory(context), child: const Text('打开目录')), |
|
|
|
|
], |
|
|
|
|
); |
|
|
|
|
@override |
|
|
|
|
void dispose() { |
|
|
|
|
_scrollController.dispose(); // 记得销毁controller |
|
|
|
|
super.dispose(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 动态计算总宽度(根据层级深度调整) |
|
|
|
|
double calculateTotalWidth(BuildContext context, FileProvider fileProvider) { |
|
|
|
|
final maxDepth = _getMaxDepth(fileProvider.fileNodes); |
|
|
|
|
return maxDepth * 200 + MediaQuery.of(context).size.width * 0.5; |
|
|
|
|
return maxDepth * 60 + MediaQuery.of(context).size.width * 0.2; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int _getMaxDepth(List<FileNode> nodes) { |
|
|
|
@ -62,18 +46,15 @@ class _FileExplorerState extends State<FileExplorer> {
@@ -62,18 +46,15 @@ class _FileExplorerState extends State<FileExplorer> {
|
|
|
|
|
Widget build(BuildContext context) { |
|
|
|
|
final fileProvider = Provider.of<FileProvider>(context); |
|
|
|
|
|
|
|
|
|
return Container( |
|
|
|
|
return Scrollbar( |
|
|
|
|
controller: _scrollController, // 指定controller |
|
|
|
|
thumbVisibility: true, |
|
|
|
|
child: SingleChildScrollView( |
|
|
|
|
controller: _scrollController, // 使用同一个controller |
|
|
|
|
scrollDirection: Axis.horizontal, |
|
|
|
|
child: Container( |
|
|
|
|
color: Colors.white, |
|
|
|
|
child: Column( |
|
|
|
|
children: [ |
|
|
|
|
Expanded( |
|
|
|
|
child: ClipRect( |
|
|
|
|
child: |
|
|
|
|
fileProvider.isLoading |
|
|
|
|
? const Center(child: CircularProgressIndicator()) |
|
|
|
|
: fileProvider.fileNodes.isEmpty |
|
|
|
|
? Center(child: _buildEmptyPrompt(context)) |
|
|
|
|
: SizedBox( |
|
|
|
|
child: SizedBox( |
|
|
|
|
width: calculateTotalWidth(context, fileProvider), |
|
|
|
|
child: TreeView( |
|
|
|
|
nodes: fileProvider.fileNodes, |
|
|
|
@ -84,8 +65,6 @@ class _FileExplorerState extends State<FileExplorer> {
@@ -84,8 +65,6 @@ class _FileExplorerState extends State<FileExplorer> {
|
|
|
|
|
), |
|
|
|
|
), |
|
|
|
|
), |
|
|
|
|
], |
|
|
|
|
), |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|