v8
This commit is contained in:
@@ -7,17 +7,20 @@ class SortConfig {
|
||||
final int seed;
|
||||
final Duration duration;
|
||||
final String name;
|
||||
final int colorIndex;
|
||||
|
||||
SortConfig({
|
||||
this.count = 100,
|
||||
this.duration = const Duration(microseconds: 1500),
|
||||
this.seed = -1,
|
||||
this.colorIndex = 0,
|
||||
this.name = 'insertion',
|
||||
});
|
||||
|
||||
SortConfig copyWith({
|
||||
int? count,
|
||||
int? seed,
|
||||
int? colorIndex,
|
||||
Duration? duration,
|
||||
String? name,
|
||||
}) =>
|
||||
@@ -26,6 +29,7 @@ class SortConfig {
|
||||
seed:seed??this.seed,
|
||||
duration:duration??this.duration,
|
||||
name:name??this.name,
|
||||
colorIndex:colorIndex??this.colorIndex,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../functions.dart';
|
||||
import 'sort_config.dart';
|
||||
@@ -11,6 +11,20 @@ enum SortStatus{
|
||||
sorted, // 排序完成
|
||||
}
|
||||
|
||||
List<MaterialColor> kColorSupport = [
|
||||
Colors.blue,
|
||||
Colors.lightBlue,
|
||||
Colors.cyan,
|
||||
Colors.red,
|
||||
Colors.pink,
|
||||
Colors.orange,
|
||||
Colors.yellow,
|
||||
Colors.green,
|
||||
Colors.indigo,
|
||||
Colors.purple,
|
||||
Colors.deepPurple,
|
||||
];
|
||||
|
||||
class SortState with ChangeNotifier{
|
||||
|
||||
SortState(){
|
||||
@@ -37,6 +51,11 @@ class SortState with ChangeNotifier{
|
||||
config = config.copyWith(name: name);
|
||||
}
|
||||
|
||||
void selectColor(int colorIndex){
|
||||
if(colorIndex==config.colorIndex) return;
|
||||
config = config.copyWith(colorIndex: colorIndex);
|
||||
}
|
||||
|
||||
void reset(){
|
||||
data.clear();
|
||||
status = SortStatus.none;
|
||||
|
||||
@@ -5,8 +5,9 @@ import 'package:flutter/material.dart';
|
||||
class DataPainter extends CustomPainter{
|
||||
|
||||
final List<int> data;
|
||||
final MaterialColor color;
|
||||
|
||||
DataPainter({required this.data});
|
||||
DataPainter( {required this.data,required this.color,});
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
@@ -17,28 +18,29 @@ class DataPainter extends CustomPainter{
|
||||
paint.strokeWidth = itemWidth;
|
||||
paint.strokeCap = StrokeCap.round;
|
||||
|
||||
|
||||
for(int i=0;i<data.length;i++){
|
||||
int value = data[i];
|
||||
if (value < 1000 * .10) {
|
||||
paint.color = Colors.blue.shade100;
|
||||
paint.color = color.shade50;
|
||||
} else if (value < 1000 * .20) {
|
||||
paint.color = Colors.blue.shade200;
|
||||
paint.color = color.shade100;
|
||||
} else if (value < 1000 * .30) {
|
||||
paint.color = Colors.blue.shade300;
|
||||
paint.color = color.shade200;
|
||||
} else if (value < 1000 * .40) {
|
||||
paint.color = Colors.blue.shade400;
|
||||
paint.color = color.shade300;
|
||||
} else if (value < 1000 * .50) {
|
||||
paint.color = Colors.blue.shade500;
|
||||
paint.color = color.shade400;
|
||||
} else if (value < 1000 * .60) {
|
||||
paint.color = Colors.blue.shade600;
|
||||
paint.color = color.shade500;
|
||||
} else if (value < 1000 * .70) {
|
||||
paint.color = Colors.blue.shade700;
|
||||
paint.color = color.shade600;
|
||||
} else if (value < 1000 * .80) {
|
||||
paint.color = Colors.blue.shade800;
|
||||
paint.color = color.shade700;
|
||||
} else if (value < 1000 * .90) {
|
||||
paint.color = Colors.blue.shade900;
|
||||
paint.color = color.shade800;
|
||||
} else {
|
||||
paint.color = const Color(0xFF011E51);
|
||||
paint.color = color.shade900;
|
||||
}
|
||||
canvas.drawLine(
|
||||
Offset(i * itemWidth+itemWidth/2, 0),
|
||||
22
lib/v8/pages/sort/views/player/sort_player.dart
Normal file
22
lib/v8/pages/sort/views/player/sort_player.dart
Normal file
@@ -0,0 +1,22 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../provider/state.dart';
|
||||
import 'data_painter.dart';
|
||||
|
||||
class SortPlayer extends StatelessWidget {
|
||||
const SortPlayer({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SortState state = SortStateScope.of(context);
|
||||
List<int> numbers = state.data;
|
||||
MaterialColor color = kColorSupport[state.config.colorIndex];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: CustomPaint(
|
||||
painter: DataPainter(data: numbers,color: color),
|
||||
child: ConstrainedBox(constraints: const BoxConstraints.expand()),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
41
lib/v8/pages/sort/views/settings/color_picker.dart
Normal file
41
lib/v8/pages/sort/views/settings/color_picker.dart
Normal file
@@ -0,0 +1,41 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ColorPicker extends StatelessWidget {
|
||||
final List<MaterialColor> colors;
|
||||
final ValueChanged<int> onSelected;
|
||||
final int activeIndex;
|
||||
|
||||
const ColorPicker({
|
||||
super.key,
|
||||
required this.colors,
|
||||
required this.activeIndex,
|
||||
required this.onSelected,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Wrap(
|
||||
children: colors
|
||||
.asMap()
|
||||
.keys
|
||||
.map((int index) => MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: ()=>onSelected(index),
|
||||
child: Container(
|
||||
width: 32,
|
||||
height: 32,
|
||||
color: colors[index],
|
||||
child: activeIndex == index
|
||||
? const Icon(
|
||||
Icons.check,
|
||||
color: Colors.white,
|
||||
)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
))
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
169
lib/v8/pages/sort/views/settings/sort_setting.dart
Normal file
169
lib/v8/pages/sort/views/settings/sort_setting.dart
Normal file
@@ -0,0 +1,169 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../provider/state.dart';
|
||||
import 'color_picker.dart';
|
||||
class SortSettings extends StatefulWidget {
|
||||
|
||||
const SortSettings({super.key,});
|
||||
|
||||
@override
|
||||
State<SortSettings> createState() => _SortSettingsState();
|
||||
}
|
||||
|
||||
class _SortSettingsState extends State<SortSettings> {
|
||||
final TextEditingController _count = TextEditingController();
|
||||
final TextEditingController _duration = TextEditingController();
|
||||
final TextEditingController _seed = TextEditingController();
|
||||
int _colorIndex = 0;
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
SortState state = SortStateScope.of(context);
|
||||
_count.text = state.config.count.toString();
|
||||
_duration.text = state.config.duration.inMicroseconds.toString();
|
||||
_seed.text = state.config.seed.toString();
|
||||
_colorIndex = state.config.colorIndex;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SortState state = SortStateScope.of(context);
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
leading: Align(
|
||||
child: MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: (){
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Container(
|
||||
width: 28,
|
||||
height: 28,
|
||||
margin: EdgeInsets.only(right: 8,left: 8),
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xffE3E5E7),
|
||||
borderRadius: BorderRadius.circular(6)
|
||||
),
|
||||
child: Icon(Icons.arrow_back_ios_new,size: 18,)),
|
||||
),
|
||||
),
|
||||
),
|
||||
// leading: BackButton(),
|
||||
actions: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: IconButton(
|
||||
splashRadius: 20,
|
||||
onPressed: (){
|
||||
SortState state = SortStateScope.of(context);
|
||||
state.config =state.config.copyWith(
|
||||
count: int.parse(_count.text),
|
||||
duration: Duration(
|
||||
microseconds: int.parse(_duration.text),
|
||||
),
|
||||
seed: int.parse(_seed.text),
|
||||
colorIndex: _colorIndex
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
}, icon: Icon(Icons.check)),
|
||||
)],
|
||||
iconTheme: IconThemeData(color: Colors.black),
|
||||
titleTextStyle: TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
centerTitle: true,
|
||||
title: Text('排序算法配置'),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text('数据数量(个数):'),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _count,
|
||||
)),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text('时间间隔(微秒):'),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _duration,
|
||||
)),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text('随机种子:'),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _seed,
|
||||
)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20,),
|
||||
|
||||
Row(
|
||||
children: [
|
||||
Text('选择颜色:'),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Expanded(
|
||||
child: ColorPicker(
|
||||
colors: kColorSupport,
|
||||
onSelected: (index){
|
||||
setState(() {
|
||||
_colorIndex = index;
|
||||
});
|
||||
},
|
||||
activeIndex: _colorIndex,
|
||||
),),
|
||||
],
|
||||
),
|
||||
|
||||
Spacer(),
|
||||
// ElevatedButton(
|
||||
// onPressed: () {
|
||||
// SortState state = SortStateScope.of(context);
|
||||
// state.config =state.config.copyWith(
|
||||
// count: int.parse(_count.text),
|
||||
// duration: Duration(
|
||||
// microseconds: int.parse(_duration.text),
|
||||
// ),
|
||||
// seed: int.parse(_seed.text)
|
||||
// );
|
||||
// Navigator.of(context).pop();
|
||||
// },
|
||||
// child: Text('确定设置'))
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:iroute/components/components.dart';
|
||||
|
||||
import '../provider/state.dart';
|
||||
import '../functions.dart';
|
||||
import 'sort_button.dart';
|
||||
|
||||
class SortBar extends StatelessWidget {
|
||||
const SortBar({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SortState state = SortStateScope.of(context);
|
||||
return Row(
|
||||
children: [
|
||||
const SortButton(),
|
||||
const SizedBox(width: 10,),
|
||||
DropSelectableWidget(
|
||||
value: sortNameMap[state.config.name]!,
|
||||
fontSize: 12,
|
||||
data: sortNameMap.values.toList(),
|
||||
iconSize: 20,
|
||||
height: 28,
|
||||
width: 200,
|
||||
disableColor: const Color(0xff1F425F),
|
||||
onDropSelected: (int index) async {
|
||||
SortState state = SortStateScope.of(context);
|
||||
state.config =state.config.copyWith(
|
||||
name: sortNameMap.keys.toList()[index]
|
||||
);
|
||||
// curveAnim = CurvedAnimation(
|
||||
// parent: _ctrl, curve: maps.values.toList()[index]);
|
||||
// _startAnim();
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 10,),
|
||||
GestureDetector(
|
||||
onTap: (){
|
||||
Scaffold.of(context).openEndDrawer();
|
||||
// showDialog(
|
||||
// useRootNavigator: false,
|
||||
// context: context, builder: (ctx)=>AlertDialog());
|
||||
},
|
||||
child: const Icon(Icons.settings))
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'sort_setting.dart';
|
||||
import 'code_page/code_page.dart';
|
||||
import 'sort_button.dart';
|
||||
|
||||
import '../functions.dart';
|
||||
import '../provider/state.dart';
|
||||
import 'data_painter.dart';
|
||||
|
||||
class SortPage extends StatelessWidget {
|
||||
const SortPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SortState state = SortStateScope.of(context);
|
||||
List<int> numbers = state.data;
|
||||
return Scaffold(
|
||||
body: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 220,
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
// color: Color(0xffF4F4F4),
|
||||
padding: EdgeInsets.symmetric(horizontal: 12,vertical: 8),
|
||||
child: Row(
|
||||
children: [
|
||||
SortButton(),
|
||||
Spacer(),
|
||||
MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: (){
|
||||
(key.currentState as NavigatorState).push(MaterialPageRoute(builder: (_)=>CodePage()));
|
||||
},
|
||||
child: const Icon(CupertinoIcons.chevron_left_slash_chevron_right,size: 18,)),
|
||||
),
|
||||
SizedBox(width: 8,),
|
||||
MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: (){
|
||||
|
||||
(key.currentState as NavigatorState).push(MaterialPageRoute(builder: (_)=>SortSettings()));
|
||||
},
|
||||
child: Icon(CupertinoIcons.settings,size: 18,)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 1,),
|
||||
Expanded(
|
||||
child: SortSelectorPanel(
|
||||
active: state.config.name,
|
||||
options: sortNameMap.values.toList(),
|
||||
onSelected: state.selectName,
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
VerticalDivider(width: 1,),
|
||||
Expanded(
|
||||
child: NavigatorScope(),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _onSelected(String value) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
final GlobalKey key = GlobalKey();
|
||||
|
||||
class NavigatorScope extends StatefulWidget {
|
||||
const NavigatorScope({super.key});
|
||||
|
||||
@override
|
||||
State<NavigatorScope> createState() => _NavigatorScopeState();
|
||||
}
|
||||
|
||||
class _NavigatorScopeState extends State<NavigatorScope> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SortState state = SortStateScope.of(context);
|
||||
List<int> numbers = state.data;
|
||||
return Navigator(
|
||||
onPopPage: _onPopPage,
|
||||
key: key,
|
||||
pages: [
|
||||
MaterialPage(child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: CustomPaint(
|
||||
painter: DataPainter(data: numbers),
|
||||
child: ConstrainedBox(constraints: BoxConstraints.expand()),
|
||||
),
|
||||
))
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
bool _onPopPage(Route<dynamic> route, result) {
|
||||
return route.didPop(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class SortSelectorPanel extends StatelessWidget {
|
||||
final String active;
|
||||
final ValueChanged<String> onSelected;
|
||||
final List<String> options;
|
||||
|
||||
const SortSelectorPanel(
|
||||
{super.key, required this.active, required this.options, required this.onSelected});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListView.builder(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
itemExtent: 46,
|
||||
itemCount: sortNameMap.length,
|
||||
itemBuilder: _buildByIndex,
|
||||
);
|
||||
}
|
||||
|
||||
Widget? _buildByIndex(BuildContext context, int index) {
|
||||
String key = sortNameMap.keys.toList()[index];
|
||||
bool selected = sortNameMap.keys.toList()[index] == active;
|
||||
return SortItemTile(
|
||||
selected: selected,
|
||||
onTap: ()=>onSelected(key),
|
||||
title: options[index],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SortItemTile extends StatefulWidget {
|
||||
final String title;
|
||||
final VoidCallback onTap;
|
||||
final bool selected;
|
||||
const SortItemTile({super.key, required this.title, required this.selected, required this.onTap});
|
||||
|
||||
@override
|
||||
State<SortItemTile> createState() => _SortItemTileState();
|
||||
}
|
||||
|
||||
class _SortItemTileState extends State<SortItemTile> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: widget.onTap,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0,vertical: 2),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
color: widget.selected?Color(0xffE6F0FF):null
|
||||
),
|
||||
padding: EdgeInsets.only(left: 12),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
widget.title,
|
||||
style: TextStyle(fontSize: 14,
|
||||
fontWeight: widget.selected?FontWeight.bold:null
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../provider/state.dart';
|
||||
import '../../provider/state.dart';
|
||||
|
||||
class SortButton extends StatelessWidget {
|
||||
const SortButton({super.key});
|
||||
@@ -49,7 +49,6 @@ class SortButton extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(width: 4,),
|
||||
Text(text,style: TextStyle(fontSize: 12,fontWeight: FontWeight.bold,color: color),),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
230
lib/v8/pages/sort/views/sort_page/sort_page.dart
Normal file
230
lib/v8/pages/sort/views/sort_page/sort_page.dart
Normal file
@@ -0,0 +1,230 @@
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../player/sort_player.dart';
|
||||
import '../../../../app/navigation/router/app_router_delegate.dart';
|
||||
import '../settings/sort_setting.dart';
|
||||
import 'sort_button.dart';
|
||||
|
||||
import '../../functions.dart';
|
||||
import '../../provider/state.dart';
|
||||
|
||||
class SortPage extends StatefulWidget {
|
||||
const SortPage({super.key});
|
||||
|
||||
@override
|
||||
State<SortPage> createState() => _SortPageState();
|
||||
}
|
||||
|
||||
class _SortPageState extends State<SortPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 220,
|
||||
child: SortRailPanel(),
|
||||
),
|
||||
VerticalDivider(
|
||||
width: 1,
|
||||
),
|
||||
Expanded(
|
||||
child: SortNavigatorScope(),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SortRailPanel extends StatelessWidget {
|
||||
const SortRailPanel({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SortState state = SortStateScope.of(context);
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
child: Row(
|
||||
children: [
|
||||
const SortButton(),
|
||||
const Spacer(),
|
||||
const MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: Icon(
|
||||
CupertinoIcons.chevron_left_slash_chevron_right,
|
||||
size: 18,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
router.changePath('/sort/settings');
|
||||
},
|
||||
child: const Icon(
|
||||
CupertinoIcons.settings,
|
||||
size: 18,
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(
|
||||
height: 1,
|
||||
),
|
||||
Expanded(
|
||||
child: SortSelectorPanel(
|
||||
active: state.config.name,
|
||||
options: sortNameMap.values.toList(),
|
||||
onSelected: (name) {
|
||||
state.selectName(name);
|
||||
router.changePath('/sort');
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SortNavigatorScope extends StatefulWidget {
|
||||
const SortNavigatorScope({super.key});
|
||||
|
||||
@override
|
||||
State<SortNavigatorScope> createState() => _SortNavigatorScopeState();
|
||||
}
|
||||
|
||||
class _SortNavigatorScopeState extends State<SortNavigatorScope> {
|
||||
@override
|
||||
void initState() {
|
||||
router.addListener(_update);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
router.removeListener(_update);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String path = router.path;
|
||||
List<Page> pages = buildPagesByPath(context, path);
|
||||
return Navigator(
|
||||
onPopPage: _onPopPage,
|
||||
pages: pages,
|
||||
);
|
||||
}
|
||||
|
||||
bool _onPopPage(Route<dynamic> route, result) {
|
||||
return route.didPop(result);
|
||||
}
|
||||
|
||||
List<Page> buildPagesByPath(BuildContext context, String path) {
|
||||
if (path == '/sort/settings') {
|
||||
return [
|
||||
const MaterialPage(key: ValueKey('/sort/player'), child: SortPlayer()),
|
||||
const MaterialPage(
|
||||
key: ValueKey('/sort/settings'),
|
||||
child: SortSettings(),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
const MaterialPage(
|
||||
key: ValueKey('/sort/player'),
|
||||
child: SortPlayer(),
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
void _update() {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
class SortSelectorPanel extends StatelessWidget {
|
||||
final String active;
|
||||
final ValueChanged<String> onSelected;
|
||||
final List<String> options;
|
||||
|
||||
const SortSelectorPanel(
|
||||
{super.key,
|
||||
required this.active,
|
||||
required this.options,
|
||||
required this.onSelected});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListView.builder(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
itemExtent: 46,
|
||||
itemCount: sortNameMap.length,
|
||||
itemBuilder: _buildByIndex,
|
||||
);
|
||||
}
|
||||
|
||||
Widget? _buildByIndex(BuildContext context, int index) {
|
||||
String key = sortNameMap.keys.toList()[index];
|
||||
bool selected = sortNameMap.keys.toList()[index] == active;
|
||||
return SortItemTile(
|
||||
selected: selected,
|
||||
onTap: () => onSelected(key),
|
||||
title: options[index],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SortItemTile extends StatefulWidget {
|
||||
final String title;
|
||||
final VoidCallback onTap;
|
||||
final bool selected;
|
||||
|
||||
const SortItemTile(
|
||||
{super.key,
|
||||
required this.title,
|
||||
required this.selected,
|
||||
required this.onTap});
|
||||
|
||||
@override
|
||||
State<SortItemTile> createState() => _SortItemTileState();
|
||||
}
|
||||
|
||||
class _SortItemTileState extends State<SortItemTile> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: widget.onTap,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 2),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
color: widget.selected ? const Color(0xffE6F0FF) : null),
|
||||
padding: const EdgeInsets.only(left: 12),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
widget.title,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: widget.selected ? FontWeight.bold : null),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../provider/sort_config.dart';
|
||||
import '../provider/state.dart';
|
||||
|
||||
class SortSettings extends StatefulWidget {
|
||||
|
||||
const SortSettings({super.key,});
|
||||
|
||||
@override
|
||||
State<SortSettings> createState() => _SortSettingsState();
|
||||
}
|
||||
|
||||
class _SortSettingsState extends State<SortSettings> {
|
||||
late TextEditingController _count =
|
||||
TextEditingController();
|
||||
late TextEditingController _duration = TextEditingController();
|
||||
late TextEditingController _seed =
|
||||
TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
print('========_SortSettingsState#didChangeDependencies=============');
|
||||
super.didChangeDependencies();
|
||||
SortState state = SortStateScope.of(context);
|
||||
_count.text = state.config.count.toString();
|
||||
_duration.text = state.config.duration.inMicroseconds.toString();
|
||||
_seed.text = state.config.seed.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
leading: BackButton(),
|
||||
titleTextStyle: TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
centerTitle: true,
|
||||
title: Text('排序算法配置'),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text('数据数量(个数):'),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _count,
|
||||
)),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text('时间间隔(微秒):'),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _duration,
|
||||
)),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text('随机种子:'),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _seed,
|
||||
)),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
SortState state = SortStateScope.of(context);
|
||||
state.config =state.config.copyWith(
|
||||
count: int.parse(_count.text),
|
||||
duration: Duration(
|
||||
microseconds: int.parse(_duration.text),
|
||||
),
|
||||
seed: int.parse(_seed.text)
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('确定设置'))
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user