This commit is contained in:
toly
2023-10-21 10:10:48 +08:00
parent 689e8d9fdb
commit bcba7ebae2
268 changed files with 83 additions and 13102 deletions

View File

@@ -0,0 +1,207 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import '../../../pages/color/color_detail_page.dart';
import '../../../pages/color/color_page.dart';
import '../../../pages/empty/empty_page.dart';
import '../../../pages/settings/settings_page.dart';
import '../../../pages/counter/counter_page.dart';
import '../../../pages/sort/sort_page.dart';
import '../../../transition/fade_transition_page.dart';
import '../../../pages/color/color_add_page.dart';
const List<String> kDestinationsPaths = [
'/color',
'/counter',
'/user',
'/settings',
];
AppRouterDelegate router = AppRouterDelegate();
class AppRouterDelegate extends RouterDelegate<Object> with ChangeNotifier {
String _path = '/color';
String get path => _path;
int? get activeIndex {
if(path.startsWith('/color')) return 0;
if(path.startsWith('/counter')) return 1;
if(path.startsWith('/user')) return 2;
if(path.startsWith('/settings')) return 3;
return null;
}
final Map<String,Completer<dynamic>> _completerMap = {};
Completer<dynamic>? completer;
Future<dynamic> changePathForResult(String value) async{
Completer<dynamic> completer = Completer();
_completerMap[value] = completer;
path = value;
return completer.future;
}
set path(String value) {
if (_path == value) return;
_path = value;
notifyListeners();
}
// IRoute? parserPath(String path){
//
// List<String> parts = path.split('/');
// String lever1 = '/${parts[1]}';
// List<IRoute> iRoutes = kDestinationsIRoutes.where((e) => e.path == lever1).toList();
//
// int counter = 2;
//
// IRoute? result;
// String check = lever1;
// for(int i = 0;i<iRoutes.length;i++){
// check = check +"/" + parts[counter];
// String path = iRoutes[i].path;
// if(path == check){
// result = iRoutes[i];
// break;
// }
// // String path =
// // result.children.add(IRoute(path: parts[i]);
// }
// }
@override
Widget build(BuildContext context) {
return Navigator(
onPopPage: _onPopPage,
pages: _buildPageByPath(path),
);
}
List<Page> _buildPageByPath(String path) {
if(path.startsWith('/color')){
return buildColorPages(path);
}
Widget? child;
if (path == kDestinationsPaths[1]) {
child = const CounterPage();
}
if (path == kDestinationsPaths[2]) {
child = const SortPage();
}
if (path == kDestinationsPaths[3]) {
child = const SettingPage();
}
return [
FadeTransitionPage(
key: ValueKey(path),
child: child ?? const EmptyPage(),
)
];
}
List<Page> buildColorPages(String path){
List<Page> result = [];
Uri uri = Uri.parse(path);
for (String segment in uri.pathSegments) {
if(segment == 'color'){
result.add( const FadeTransitionPage(
key: ValueKey('/color'),
child:ColorPage(),
));
}
if(segment =='detail'){
final Map<String, String> queryParams = uri.queryParameters;
String? selectedColor = queryParams['color'];
if (selectedColor != null) {
Color color = Color(int.parse(selectedColor, radix: 16));
result.add( FadeTransitionPage(
key: const ValueKey('/color/detail'),
child:ColorDetailPage(color: color),
));
}
}
if(segment == 'add'){
result.add( const FadeTransitionPage(
key: ValueKey('/color/add'),
child:ColorAddPage(),
));
}
}
return result;
}
@override
Future<bool> popRoute() async {
print('=======popRoute=========');
return true;
}
bool _onPopPage(Route route, result) {
if(_completerMap.containsKey(path)){
_completerMap[path]?.complete(result);
_completerMap.remove(path);
}
path = backPath(path);
return route.didPop(result);
}
String backPath(String path){
Uri uri = Uri.parse(path);
if(uri.pathSegments.length==1) return path;
List<String> parts = List.of(uri.pathSegments)..removeLast();
return '/${parts.join('/')}';
}
@override
Future<void> setNewRoutePath(configuration) async {}
}
// class AppRouterDelegate extends RouterDelegate<String> with ChangeNotifier, PopNavigatorRouterDelegateMixin {
//
// List<String> _value = ['/'];
//
//
// List<String> get value => _value;
//
// set value(List<String> value){
// _value = value;
// notifyListeners();
// }
//
// @override
// Widget build(BuildContext context) {
// return Navigator(
// onPopPage: _onPopPage,
// pages: _value.map((e) => _pageMap[e]!).toList(),
// );
// }
//
// final Map<String, Page> _pageMap = const {
// '/': MaterialPage(child: HomePage()),
// 'a': MaterialPage(child: PageA()),
// 'b': MaterialPage(child: PageB()),
// 'c': MaterialPage(child: PageC()),
// };
//
// bool _onPopPage(Route route, result) {
// _value = List.of(_value)..removeLast();
// notifyListeners();
// return route.didPop(result);
// }
//
// @override
// GlobalKey<NavigatorState>? navigatorKey = GlobalKey<NavigatorState>();
//
// @override
// Future<void> setNewRoutePath(String configuration) async{
// }
// }

View File

@@ -0,0 +1,37 @@
class IRoute {
final String path;
final List<IRoute> children;
const IRoute({required this.path, this.children = const []});
@override
String toString() {
return 'IRoute{path: $path, children: $children}';
}
List<String> list(){
return [];
}
}
const List<IRoute> kDestinationsIRoutes = [
IRoute(
path: '/color',
children: [
IRoute(path: '/color/add'),
IRoute(path: '/color/detail'),
],
),
IRoute(
path: '/counter',
),
IRoute(
path: '/user',
),
IRoute(
path: '/settings',
),
];

View File

@@ -0,0 +1,39 @@
import 'package:flutter/material.dart';
import '../router/app_router_delegate.dart';
import 'app_navigation_rail.dart';
import 'background.dart';
import 'top_bar.dart';
class AppNavigation extends StatelessWidget {
const AppNavigation({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
// const Background(),
Row(
children: [
const AppNavigationRail(),
Expanded(
child: Column(
children: [
TopBar(),
Divider(height: 1,),
Expanded(
child: Router(
routerDelegate: router,
backButtonDispatcher: RootBackButtonDispatcher(),
),
),
],
),
),
],
),
],
),
);
}
}

View File

@@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import 'package:iroute/components/toly_ui/toly_ui.dart';
import '../router/app_router_delegate.dart';
class AppNavigationRail extends StatefulWidget {
const AppNavigationRail({super.key});
@override
State<AppNavigationRail> createState() => _AppNavigationRailState();
}
class _AppNavigationRailState extends State<AppNavigationRail> {
final List<NavigationRailDestination> destinations = const [
NavigationRailDestination(icon: Icon(Icons.color_lens_outlined), label: Text("颜色板")),
NavigationRailDestination(icon: Icon(Icons.add_chart), label: Text("计数器")),
NavigationRailDestination(icon: Icon(Icons.person), label: Text("我的")),
NavigationRailDestination(icon: Icon(Icons.settings), label: Text("设置")),
];
@override
void initState() {
super.initState();
router.addListener(_onRouterChange);
}
@override
void dispose() {
router.removeListener(_onRouterChange);
super.dispose();
}
@override
Widget build(BuildContext context) {
return TolyNavigationRail(
leading: Padding(
padding: const EdgeInsets.symmetric(vertical: 18.0),
child: FlutterLogo(),
),
backgroundColor: const Color(0xff3975c6),
onDestinationSelected: _onDestinationSelected,
selectedIndex: router.activeIndex,
);
// return NavigationRail(
// backgroundColor: Colors.transparent,
// labelType: NavigationRailLabelType.all,
// onDestinationSelected: _onDestinationSelected,
// destinations: destinations,
// selectedIndex: router.activeIndex,
// );
}
void _onDestinationSelected(int index) {
router.path = kDestinationsPaths[index];
}
void _onRouterChange() {
setState(() {});
}
}

View File

@@ -0,0 +1,19 @@
import 'dart:math';
import 'package:flutter/material.dart';
class Background extends StatelessWidget {
const Background({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
gradient:
LinearGradient(transform: GradientRotation(pi / 2), colors: [
Color(0xffF1EFF1),
Color(0xffFFFFFF),
])),
);
}
}

View File

@@ -0,0 +1,107 @@
import 'package:flutter/material.dart';
import 'package:iroute/components/components.dart';
import '../router/app_router_delegate.dart';
import 'package:window_manager/window_manager.dart';
class TopBar extends StatelessWidget {
const TopBar({super.key});
@override
Widget build(BuildContext context) {
return DragToMoveAreaNoDouble(
child: Container(
alignment: Alignment.center,
height: 46,
child: Row(
children: [
const SizedBox(
width: 16,
),
RouterIndicator(),
Spacer(),
WindowButtons()
],
),
),
);
}
}
class RouterIndicator extends StatefulWidget {
const RouterIndicator({super.key});
@override
State<RouterIndicator> createState() => _RouterIndicatorState();
}
class _RouterIndicatorState extends State<RouterIndicator> {
@override
void initState() {
super.initState();
router.addListener(_onRouterChange);
}
Map<String, String> routeLabelMap = {
'/color': '颜色板',
'/color/add': '添加颜色',
'/color/detail': '颜色详情',
'/counter': '计数器',
'/user': '我的',
'/settings': '系统设置',
};
@override
Widget build(BuildContext context) {
return TolyBreadcrumb(
items: pathToBreadcrumbItems(router.path),
onTapItem: (item){
if(item.to!=null){
router.path = item.to!;
}
},
);
}
void _onRouterChange() {
print('_onRouterChange');
setState(() {});
}
List<BreadcrumbItem> pathToBreadcrumbItems(String path) {
Uri uri = Uri.parse(path);
List<BreadcrumbItem> result = [];
String to = '';
String distPath = '';
for (String segment in uri.pathSegments) {
distPath += '/$segment';
}
for (String segment in uri.pathSegments) {
to += '/$segment';
result.add(BreadcrumbItem(to: to, label: routeLabelMap[to] ?? '未知路由',active: to==distPath));
}
return result;
}
}
class DragToMoveAreaNoDouble extends StatelessWidget {
final Widget child;
const DragToMoveAreaNoDouble({
Key? key,
required this.child,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.translucent,
onPanStart: (details) {
windowManager.startDragging();
},
child: child,
);
}
}